fix(user_store): add checking and move some common vars

This commit is contained in:
hexxa 2022-03-24 14:46:22 +08:00 committed by Hexxa
parent c3a3b2dc5b
commit b7609e6c06
17 changed files with 567 additions and 560 deletions

View file

@ -803,7 +803,7 @@ export class BgCfg extends React.Component<BgProps, BgState, {}> {
} }
const bgAlign = this.props.ui.bg.align; const bgAlign = this.props.ui.bg.align;
if (bgAlign != "scroll" && bgAlign != "fixed" && bgAlign != "local") { if (bgAlign !== "scroll" && bgAlign !== "fixed" && bgAlign !== "local") {
alertMsg(this.props.msg.pkg.get("bg.align.alert")); alertMsg(this.props.msg.pkg.get("bg.align.alert"));
return; return;
} }

View file

@ -9,20 +9,72 @@ import (
const ( const (
SchemaV2 = "v2" // add size to file info SchemaV2 = "v2" // add size to file info
UsersNs = "users" UserSchemaNs = "UserSchemaNs"
InfoNs = "sharing" UserIDsNs = "UserIDsNs"
ShareIDNs = "sharingKey" UsersNs = "UsersNs"
RolesNs = "RolesNs"
InfoNs = "InfoNs"
ShareIDNs = "ShareIDNs"
uploadsPrefix = "uploads" uploadsPrefix = "uploads"
KeyInitTime = "keyInitTime" KeyInitTime = "keyInitTime"
AdminRole = "admin"
UserRole = "user"
VisitorRole = "visitor"
) )
var ( var (
ErrInvalidUser = errors.New("invalid user")
ErrInvalidQuota = errors.New("invalid quota")
ErrInvalidPreferences = errors.New("invalid preferences")
ErrBucketNotFound = errors.New("bucket not found") ErrBucketNotFound = errors.New("bucket not found")
ErrKeyNotFound = errors.New("key not found") ErrKeyNotFound = errors.New("key not found")
ErrCreateExisting = errors.New("create upload info which already exists") ErrCreateExisting = errors.New("create upload info which already exists")
ErrQuota = errors.New("quota limit reached") ErrQuota = errors.New("quota limit reached")
DefaultSiteName = "Quickshare"
DefaultSiteDesc = "Quickshare"
DefaultBgConfig = &BgConfig{
Repeat: "repeated",
Position: "top",
Align: "fixed",
BgColor: "#ccc",
}
BgRepeatValues = map[string]bool{
"repeat-x": true,
"repeat-y": true,
"repeat": true,
"space": true,
"round": true,
"no-repeat": true,
}
BgAlignValues = map[string]bool{
"scroll": true,
"fixed": true,
"local": true,
}
BgPositionValues = map[string]bool{
"top": true,
"bottom": true,
"left": true,
"right": true,
"center": true,
}
DefaultCSSURL = ""
DefaultLanPackURL = ""
DefaultLan = "en_US"
DefaultTheme = "light"
DefaultAvatar = ""
DefaultEmail = ""
DefaultSpaceLimit = int64(1024 * 1024 * 1024) // 1GB
DefaultUploadSpeedLimit = 50 * 1024 * 1024 // 50MB
DefaultDownloadSpeedLimit = 50 * 1024 * 1024 // 50MB
VisitorUploadSpeedLimit = 10 * 1024 * 1024 // 10MB
VisitorDownloadSpeedLimit = 10 * 1024 * 1024 // 10MB
) )
type FileInfo struct { type FileInfo struct {
@ -33,20 +85,30 @@ type FileInfo struct {
Size int64 `json:"size"` Size int64 `json:"size"`
} }
type UserCfg struct {
Name string `json:"name" yaml:"name"`
Role string `json:"role" yaml:"role"`
Pwd string `json:"pwd" yaml:"pwd"`
}
type Quota struct { type Quota struct {
SpaceLimit int64 `json:"spaceLimit,string"` SpaceLimit int64 `json:"spaceLimit,string" yaml:"spaceLimit,string"`
UploadSpeedLimit int `json:"uploadSpeedLimit"` UploadSpeedLimit int `json:"uploadSpeedLimit" yaml:"uploadSpeedLimit"`
DownloadSpeedLimit int `json:"downloadSpeedLimit"` DownloadSpeedLimit int `json:"downloadSpeedLimit" yaml:"downloadSpeedLimit"`
} }
type Preferences struct { type Preferences struct {
Bg *BgConfig `json:"bg"` Bg *BgConfig `json:"bg" yaml:"bg"`
CSSURL string `json:"cssURL"` CSSURL string `json:"cssURL" yaml:"cssURL"`
LanPackURL string `json:"lanPackURL"` LanPackURL string `json:"lanPackURL" yaml:"lanPackURL"`
Lan string `json:"lan"` Lan string `json:"lan" yaml:"lan"`
Theme string `json:"theme"` Theme string `json:"theme" yaml:"theme"`
Avatar string `json:"avatar"` Avatar string `json:"avatar" yaml:"avatar"`
Email string `json:"email"` Email string `json:"email" yaml:"email"`
}
type SiteConfig struct {
ClientCfg *ClientConfig `json:"clientCfg" yaml:"clientCfg"`
} }
type ClientConfig struct { type ClientConfig struct {
@ -63,6 +125,22 @@ type BgConfig struct {
BgColor string `json:"bgColor" yaml:"bgColor"` BgColor string `json:"bgColor" yaml:"bgColor"`
} }
type User struct {
ID uint64 `json:"id,string" yaml:"id,string"`
Name string `json:"name" yaml:"name"`
Pwd string `json:"pwd" yaml:"pwd"`
Role string `json:"role" yaml:"role"`
UsedSpace int64 `json:"usedSpace,string" yaml:"usedSpace,string"`
Quota *Quota `json:"quota" yaml:"quota"`
Preferences *Preferences `json:"preferences" yaml:"preferences"`
}
type UploadInfo struct {
RealFilePath string `json:"realFilePath" yaml:"realFilePath"`
Size int64 `json:"size" yaml:"size"`
Uploaded int64 `json:"uploaded" yaml:"uploaded"`
}
func ComparePreferences(p1, p2 *Preferences) bool { func ComparePreferences(p1, p2 *Preferences) bool {
return p1.CSSURL == p2.CSSURL && return p1.CSSURL == p2.CSSURL &&
p1.LanPackURL == p2.LanPackURL && p1.LanPackURL == p2.LanPackURL &&
@ -73,22 +151,158 @@ func ComparePreferences(p1, p2 *Preferences) bool {
reflect.DeepEqual(p1.Bg, p2.Bg) reflect.DeepEqual(p1.Bg, p2.Bg)
} }
type User struct {
ID uint64 `json:"id,string"`
Name string `json:"name"`
Pwd string `json:"pwd"`
Role string `json:"role"`
UsedSpace int64 `json:"usedSpace,string"`
Quota *Quota `json:"quota"`
Preferences *Preferences `json:"preferences"`
}
type UploadInfo struct {
RealFilePath string `json:"realFilePath"`
Size int64 `json:"size"`
Uploaded int64 `json:"uploaded"`
}
func UploadNS(user string) string { func UploadNS(user string) string {
return fmt.Sprintf("%s/%s", uploadsPrefix, user) return fmt.Sprintf("%s/%s", uploadsPrefix, user)
} }
func CheckSiteCfg(cfg *SiteConfig, fillDefault bool) error {
if cfg.ClientCfg == nil {
if !fillDefault {
return errors.New("cfg.ClientCfg not defined")
}
cfg.ClientCfg = &ClientConfig{
SiteName: DefaultSiteName,
SiteDesc: DefaultSiteDesc,
Bg: &BgConfig{
Url: DefaultBgConfig.Url,
Repeat: DefaultBgConfig.Repeat,
Position: DefaultBgConfig.Position,
Align: DefaultBgConfig.Align,
BgColor: DefaultBgConfig.BgColor,
},
}
return nil
}
if cfg.ClientCfg.SiteName == "" {
cfg.ClientCfg.SiteName = DefaultSiteName
}
if cfg.ClientCfg.SiteDesc == "" {
cfg.ClientCfg.SiteDesc = DefaultSiteDesc
}
if cfg.ClientCfg.Bg == nil {
if !fillDefault {
return errors.New("cfg.ClientCfg.Bg not defined")
}
cfg.ClientCfg.Bg = DefaultBgConfig
}
if err := CheckBgConfig(cfg.ClientCfg.Bg, fillDefault); err != nil {
return err
}
return nil
}
func CheckQuota(quota *Quota) error {
if quota.SpaceLimit < 0 {
return ErrInvalidQuota
}
if quota.UploadSpeedLimit < 0 {
return ErrInvalidQuota
}
if quota.DownloadSpeedLimit < 0 {
return ErrInvalidQuota
}
return nil
}
func CheckPreferences(prefers *Preferences, fillDefault bool) error {
if prefers.CSSURL == "" {
prefers.CSSURL = DefaultCSSURL
}
if prefers.LanPackURL == "" {
prefers.LanPackURL = DefaultLanPackURL
}
if prefers.Lan == "" {
if !fillDefault {
return ErrInvalidPreferences
}
prefers.Lan = DefaultLan
}
if prefers.Theme == "" {
if !fillDefault {
return ErrInvalidPreferences
}
prefers.Theme = DefaultTheme
}
if prefers.Avatar == "" {
prefers.Avatar = DefaultAvatar
}
if prefers.Email == "" {
if !fillDefault {
return ErrInvalidPreferences
}
prefers.Email = DefaultEmail
}
if prefers.Bg == nil {
if !fillDefault {
return ErrInvalidPreferences
}
prefers.Bg = DefaultBgConfig
}
if err := CheckBgConfig(prefers.Bg, fillDefault); err != nil {
return err
}
return nil
}
func CheckBgConfig(cfg *BgConfig, fillDefault bool) error {
if cfg.Url == "" && cfg.BgColor == "" {
if !fillDefault {
return errors.New("one of Bg.Url or Bg.BgColor must be defined")
}
cfg.BgColor = DefaultBgConfig.BgColor
}
if !BgRepeatValues[cfg.Repeat] {
return fmt.Errorf("invalid repeat value (%s)", cfg.Repeat)
}
if !BgPositionValues[cfg.Position] {
return fmt.Errorf("invalid position value (%s)", cfg.Position)
}
if !BgAlignValues[cfg.Align] {
return fmt.Errorf("invalid align value (%s)", cfg.Align)
}
if cfg.Repeat == "" {
cfg.Repeat = DefaultBgConfig.Repeat
}
if cfg.Position == "" {
cfg.Position = DefaultBgConfig.Position
}
if cfg.Align == "" {
cfg.Align = DefaultBgConfig.Align
}
if cfg.BgColor == "" {
cfg.BgColor = DefaultBgConfig.BgColor
}
return nil
}
func CheckUser(user User, fillDefault bool) error {
if user.ID == 0 && user.Role != AdminRole {
return ErrInvalidUser
}
// TODO: add length check
if user.Name == "" || user.Pwd == "" || user.Role == "" {
return ErrInvalidUser
}
if user.UsedSpace < 0 {
return ErrInvalidUser
}
if user.Quota == nil || user.Preferences == nil {
return ErrInvalidUser
}
var err error
if err = CheckQuota(user.Quota); err != nil {
return err
}
if err = CheckPreferences(user.Preferences, fillDefault); err != nil {
return err
}
return nil
}

View file

@ -14,28 +14,13 @@ const (
KeySiteCfg = "KeySiteCfg" KeySiteCfg = "KeySiteCfg"
) )
var (
DefaultSiteName = "Quickshare"
DefaultSiteDesc = "Quickshare"
DefaultBgConfig = &db.BgConfig{
Repeat: "repeated",
Position: "top",
Align: "fixed",
BgColor: "#ccc",
}
)
var ( var (
ErrNotFound = errors.New("site config not found") ErrNotFound = errors.New("site config not found")
) )
type ISiteStore interface { type ISiteStore interface {
SetClientCfg(cfg *db.ClientConfig) error SetClientCfg(cfg *db.ClientConfig) error
GetCfg() (*SiteConfig, error) GetCfg() (*db.SiteConfig, error)
}
type SiteConfig struct {
ClientCfg *db.ClientConfig `json:"clientCfg" yaml:"clientCfg"`
} }
type SiteStore struct { type SiteStore struct {
@ -50,7 +35,7 @@ func NewSiteStore(store kvstore.IKVStore) (*SiteStore, error) {
}, nil }, nil
} }
func (st *SiteStore) Init(cfg *SiteConfig) error { func (st *SiteStore) Init(cfg *db.SiteConfig) error {
_, ok := st.store.GetStringIn(NsSite, KeySiteCfg) _, ok := st.store.GetStringIn(NsSite, KeySiteCfg)
if !ok { if !ok {
var err error var err error
@ -63,26 +48,26 @@ func (st *SiteStore) Init(cfg *SiteConfig) error {
return nil return nil
} }
func (st *SiteStore) getCfg() (*SiteConfig, error) { func (st *SiteStore) getCfg() (*db.SiteConfig, error) {
cfgStr, ok := st.store.GetStringIn(NsSite, KeySiteCfg) cfgStr, ok := st.store.GetStringIn(NsSite, KeySiteCfg)
if !ok { if !ok {
return nil, ErrNotFound return nil, ErrNotFound
} }
cfg := &SiteConfig{} cfg := &db.SiteConfig{}
err := json.Unmarshal([]byte(cfgStr), cfg) err := json.Unmarshal([]byte(cfgStr), cfg)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err = CheckCfg(cfg, true); err != nil { if err = db.CheckSiteCfg(cfg, true); err != nil {
return nil, err return nil, err
} }
return cfg, nil return cfg, nil
} }
func (st *SiteStore) setCfg(cfg *SiteConfig) error { func (st *SiteStore) setCfg(cfg *db.SiteConfig) error {
if err := CheckCfg(cfg, false); err != nil { if err := db.CheckSiteCfg(cfg, false); err != nil {
return err return err
} }
@ -106,64 +91,9 @@ func (st *SiteStore) SetClientCfg(cfg *db.ClientConfig) error {
return st.setCfg(siteCfg) return st.setCfg(siteCfg)
} }
func (st *SiteStore) GetCfg() (*SiteConfig, error) { func (st *SiteStore) GetCfg() (*db.SiteConfig, error) {
st.mtx.RLock() st.mtx.RLock()
defer st.mtx.RUnlock() defer st.mtx.RUnlock()
return st.getCfg() return st.getCfg()
} }
func CheckCfg(cfg *SiteConfig, autoFill bool) error {
if cfg.ClientCfg == nil {
if !autoFill {
return errors.New("cfg.ClientCfg not defined")
}
cfg.ClientCfg = &db.ClientConfig{
SiteName: DefaultSiteName,
SiteDesc: DefaultSiteDesc,
Bg: &db.BgConfig{
Url: DefaultBgConfig.Url,
Repeat: DefaultBgConfig.Repeat,
Position: DefaultBgConfig.Position,
Align: DefaultBgConfig.Align,
BgColor: DefaultBgConfig.BgColor,
},
}
return nil
}
if cfg.ClientCfg.SiteName == "" {
cfg.ClientCfg.SiteName = DefaultSiteName
}
if cfg.ClientCfg.SiteDesc == "" {
cfg.ClientCfg.SiteDesc = DefaultSiteDesc
}
if cfg.ClientCfg.Bg == nil {
if !autoFill {
return errors.New("cfg.ClientCfg.Bg not defined")
}
cfg.ClientCfg.Bg = DefaultBgConfig
}
if cfg.ClientCfg.Bg.Url == "" && cfg.ClientCfg.Bg.BgColor == "" {
if !autoFill {
return errors.New("one of Bg.Url or Bg.BgColor must be defined")
}
cfg.ClientCfg.Bg.BgColor = DefaultBgConfig.BgColor
}
if cfg.ClientCfg.Bg.Repeat == "" {
cfg.ClientCfg.Bg.Repeat = DefaultBgConfig.Repeat
}
if cfg.ClientCfg.Bg.Position == "" {
cfg.ClientCfg.Bg.Position = DefaultBgConfig.Position
}
if cfg.ClientCfg.Bg.Align == "" {
cfg.ClientCfg.Bg.Align = DefaultBgConfig.Align
}
if cfg.ClientCfg.Bg.BgColor == "" {
cfg.ClientCfg.Bg.BgColor = DefaultBgConfig.BgColor
}
return nil
}

View file

@ -14,15 +14,15 @@ import (
func TestSiteStore(t *testing.T) { func TestSiteStore(t *testing.T) {
testSiteMethods := func(t *testing.T, store ISiteStore) { testSiteMethods := func(t *testing.T, store ISiteStore) {
siteCfg := &SiteConfig{ siteCfg := &db.SiteConfig{
ClientCfg: &db.ClientConfig{ ClientCfg: &db.ClientConfig{
SiteName: "quickshare", SiteName: "quickshare",
SiteDesc: "simpel file sharing", SiteDesc: "simpel file sharing",
Bg: &db.BgConfig{ Bg: &db.BgConfig{
Url: "/imgs/bg.jpg", Url: "/imgs/bg.jpg",
Repeat: "no-repeat", Repeat: "no-repeat",
Position: "fixed", Position: "center",
Align: "center", Align: "fixed",
BgColor: "#ccc", BgColor: "#ccc",
}, },
}, },
@ -55,16 +55,16 @@ func TestSiteStore(t *testing.T) {
if err != nil { if err != nil {
t.Fatal("fail to new kvstore", err) t.Fatal("fail to new kvstore", err)
} }
err = store.Init(&SiteConfig{ err = store.Init(&db.SiteConfig{
ClientCfg: &db.ClientConfig{ ClientCfg: &db.ClientConfig{
SiteName: "", SiteName: "",
SiteDesc: "", SiteDesc: "",
Bg: &db.BgConfig{ Bg: &db.BgConfig{
Url: "", Url: "/imgs/bg.jpg",
Repeat: "", Repeat: "repeat",
Position: "", Position: "top",
Align: "", Align: "scroll",
BgColor: "#ccc", BgColor: "#000",
}, },
}, },
}) })

View file

@ -11,51 +11,29 @@ import (
"github.com/ihexxa/quickshare/src/kvstore" "github.com/ihexxa/quickshare/src/kvstore"
) )
// TODO: use sync.Pool instead
const ( const (
AdminRole = "admin"
UserRole = "user"
VisitorRole = "visitor"
InitNs = "usersInit"
IDsNs = "ids"
RoleListNs = "roleList"
InitTimeKey = "initTime"
VisitorID = uint64(1) VisitorID = uint64(1)
VisitorName = "visitor" VisitorName = "visitor"
defaultSpaceLimit = 1024 * 1024 * 1024 // 1GB
defaultUploadSpeedLimit = 50 * 1024 * 1024 // 50MB
defaultDownloadSpeedLimit = 50 * 1024 * 1024 // 50MB
visitorUploadSpeedLimit = 10 * 1024 * 1024 // 10MB
visitorDownloadSpeedLimit = 10 * 1024 * 1024 // 10MB
) )
var ( var (
ErrReachedLimit = errors.New("reached space limit") ErrReachedLimit = errors.New("reached space limit")
ErrNotFound = errors.New("not found") ErrUserNotFound = errors.New("user not found")
ErrNegtiveUsedSpace = errors.New("used space can not be negative")
DefaultPreferences = db.Preferences{ DefaultPreferences = db.Preferences{
Bg: &db.BgConfig{ Bg: db.DefaultBgConfig,
Url: "", CSSURL: db.DefaultCSSURL,
Repeat: "no-repeat", LanPackURL: db.DefaultLanPackURL,
Position: "center", Lan: db.DefaultLan,
Align: "fixed", Theme: db.DefaultTheme,
BgColor: "#ccc", Avatar: db.DefaultAvatar,
}, Email: db.DefaultEmail,
CSSURL: "",
LanPackURL: "",
Lan: "en_US",
Theme: "light",
Avatar: "",
Email: "",
} }
) )
type UserCfg struct {
Name string `json:"name" yaml:"name"`
Role string `json:"role" yaml:"role"`
Pwd string `json:"pwd" yaml:"pwd"`
}
type IUserStore interface { type IUserStore interface {
Init(rootName, rootPwd string) error Init(rootName, rootPwd string) error
IsInited() bool IsInited() bool
@ -64,7 +42,7 @@ type IUserStore interface {
GetUser(id uint64) (*db.User, error) GetUser(id uint64) (*db.User, error)
GetUserByName(name string) (*db.User, error) GetUserByName(name string) (*db.User, error)
SetInfo(id uint64, user *db.User) error SetInfo(id uint64, user *db.User) error
CanIncrUsed(id uint64, capacity int64) (bool, error) // CanIncrUsed(id uint64, capacity int64) (bool, error)
SetUsed(id uint64, incr bool, capacity int64) error SetUsed(id uint64, incr bool, capacity int64) error
ResetUsed(id uint64, used int64) error ResetUsed(id uint64, used int64) error
SetPwd(id uint64, pwd string) error SetPwd(id uint64, pwd string) error
@ -82,57 +60,53 @@ type KVUserStore struct {
} }
func NewKVUserStore(store kvstore.IKVStore) (*KVUserStore, error) { func NewKVUserStore(store kvstore.IKVStore) (*KVUserStore, error) {
_, ok := store.GetStringIn(InitNs, InitTimeKey) return &KVUserStore{
if !ok {
var err error
for _, nsName := range []string{
IDsNs,
db.UsersNs,
InitNs,
RoleListNs,
} {
if err = store.AddNamespace(nsName); err != nil {
return nil, err
}
}
}
usStore := &KVUserStore{
store: store, store: store,
mtx: &sync.RWMutex{}, mtx: &sync.RWMutex{},
} }, nil
return usStore, nil
} }
func (us *KVUserStore) Init(rootName, rootPwd string) error { func (us *KVUserStore) Init(rootName, rootPwd string) error {
var err error var err error
adminPreferences := DefaultPreferences
for _, namespace := range []string{
db.UserSchemaNs,
db.UserIDsNs,
db.UsersNs,
db.RolesNs,
} {
_, ok := us.store.GetStringIn(namespace, db.KeyInitTime)
if !ok {
if err = us.store.AddNamespace(namespace); err != nil {
return err
}
}
}
admin := &db.User{ admin := &db.User{
ID: 0, ID: 0,
Name: rootName, Name: rootName,
Pwd: rootPwd, Pwd: rootPwd,
Role: AdminRole, Role: db.AdminRole,
Quota: &db.Quota{ Quota: &db.Quota{
SpaceLimit: defaultSpaceLimit, SpaceLimit: db.DefaultSpaceLimit,
UploadSpeedLimit: defaultUploadSpeedLimit, UploadSpeedLimit: db.DefaultUploadSpeedLimit,
DownloadSpeedLimit: defaultDownloadSpeedLimit, DownloadSpeedLimit: db.DefaultDownloadSpeedLimit,
}, },
Preferences: &adminPreferences, Preferences: &DefaultPreferences,
} }
visitorPreferences := DefaultPreferences
visitor := &db.User{ visitor := &db.User{
ID: VisitorID, ID: VisitorID,
Name: VisitorName, Name: VisitorName,
Pwd: rootPwd, Pwd: rootPwd,
Role: VisitorRole, Role: db.VisitorRole,
Quota: &db.Quota{ Quota: &db.Quota{
SpaceLimit: 0, SpaceLimit: 0,
UploadSpeedLimit: visitorUploadSpeedLimit, UploadSpeedLimit: db.VisitorUploadSpeedLimit,
DownloadSpeedLimit: visitorDownloadSpeedLimit, DownloadSpeedLimit: db.VisitorDownloadSpeedLimit,
}, },
Preferences: &visitorPreferences, Preferences: &DefaultPreferences,
} }
for _, user := range []*db.User{admin, visitor} { for _, user := range []*db.User{admin, visitor} {
@ -142,39 +116,26 @@ func (us *KVUserStore) Init(rootName, rootPwd string) error {
} }
} }
for _, role := range []string{AdminRole, UserRole, VisitorRole} { for _, role := range []string{db.AdminRole, db.UserRole, db.VisitorRole} {
err = us.AddRole(role) err = us.AddRole(role)
if err != nil { if err != nil {
return err return err
} }
} }
return us.store.SetStringIn(InitNs, InitTimeKey, fmt.Sprintf("%d", time.Now().Unix())) return us.store.SetStringIn(db.UserSchemaNs, db.KeyInitTime, fmt.Sprintf("%d", time.Now().Unix()))
} }
func (us *KVUserStore) IsInited() bool { func (us *KVUserStore) IsInited() bool {
_, ok := us.store.GetStringIn(InitNs, InitTimeKey) _, ok := us.store.GetStringIn(db.UserSchemaNs, db.KeyInitTime)
return ok return ok
} }
func (us *KVUserStore) AddUser(user *db.User) error { func (us *KVUserStore) setUser(user *db.User) error {
us.mtx.Lock() var err error
defer us.mtx.Unlock()
userID := fmt.Sprint(user.ID) userID := fmt.Sprint(user.ID)
_, ok := us.store.GetStringIn(db.UsersNs, userID) err = us.store.SetStringIn(db.UserIDsNs, user.Name, userID)
if ok {
return fmt.Errorf("userID (%d) exists", user.ID)
}
if user.Name == "" || user.Pwd == "" {
return errors.New("user name or password can not be empty")
}
_, ok = us.store.GetStringIn(IDsNs, user.Name)
if ok {
return fmt.Errorf("user name (%s) exists", user.Name)
}
err := us.store.SetStringIn(IDsNs, user.Name, userID)
if err != nil { if err != nil {
return err return err
} }
@ -185,24 +146,60 @@ func (us *KVUserStore) AddUser(user *db.User) error {
return us.store.SetStringIn(db.UsersNs, userID, string(userBytes)) return us.store.SetStringIn(db.UsersNs, userID, string(userBytes))
} }
func (us *KVUserStore) getUser(id uint64) (*db.User, error) {
userID := fmt.Sprint(id)
userBytes, ok := us.store.GetStringIn(db.UsersNs, userID)
if !ok {
return nil, ErrUserNotFound
}
user := &db.User{}
err := json.Unmarshal([]byte(userBytes), user)
if err != nil {
return nil, err
}
return user, nil
}
func (us *KVUserStore) getUserByName(name string) (*db.User, error) {
userID, ok := us.store.GetStringIn(db.UserIDsNs, name)
if !ok {
return nil, ErrUserNotFound
}
userBytes, ok := us.store.GetStringIn(db.UsersNs, userID)
if !ok {
return nil, ErrUserNotFound
}
user := &db.User{}
err := json.Unmarshal([]byte(userBytes), user)
if err != nil {
return nil, err
}
return user, nil
}
func (us *KVUserStore) AddUser(user *db.User) error {
us.mtx.Lock()
defer us.mtx.Unlock()
return us.setUser(user)
}
func (us *KVUserStore) DelUser(id uint64) error { func (us *KVUserStore) DelUser(id uint64) error {
us.mtx.Lock() us.mtx.Lock()
defer us.mtx.Unlock() defer us.mtx.Unlock()
userID := fmt.Sprint(id) user, err := us.getUser(id)
infoStr, ok := us.store.GetStringIn(db.UsersNs, userID)
if !ok {
return fmt.Errorf("userID (%s) does not exist", userID)
}
user := &db.User{}
err := json.Unmarshal([]byte(infoStr), user)
if err != nil { if err != nil {
return err return err
} }
// TODO: add complement operations if part of the actions fails // TODO: add complement operations if part of the actions fails
err1 := us.store.DelStringIn(IDsNs, user.Name) err1 := us.store.DelStringIn(db.UserIDsNs, user.Name)
err2 := us.store.DelStringIn(db.UsersNs, userID) err2 := us.store.DelStringIn(db.UsersNs, fmt.Sprint(user.ID))
if err1 != nil || err2 != nil { if err1 != nil || err2 != nil {
return fmt.Errorf("DelUser: err1(%s) err2(%s)", err1, err2) return fmt.Errorf("DelUser: err1(%s) err2(%s)", err1, err2)
} }
@ -213,143 +210,64 @@ func (us *KVUserStore) GetUser(id uint64) (*db.User, error) {
us.mtx.RLock() us.mtx.RLock()
defer us.mtx.RUnlock() defer us.mtx.RUnlock()
userID := fmt.Sprint(id) return us.getUser(id)
infoStr, ok := us.store.GetStringIn(db.UsersNs, userID)
if !ok {
return nil, fmt.Errorf("user (%s) not found", userID)
}
user := &db.User{}
err := json.Unmarshal([]byte(infoStr), user)
if err != nil {
return nil, err
}
gotID, ok := us.store.GetStringIn(IDsNs, user.Name)
if !ok {
return nil, fmt.Errorf("user id (%s) not found", user.Name)
} else if gotID != userID {
return nil, fmt.Errorf("user id (%s) not match: got(%s) expected(%s)", user.Name, gotID, userID)
}
// TODO: use sync.Pool instead
return user, nil
} }
func (us *KVUserStore) GetUserByName(name string) (*db.User, error) { func (us *KVUserStore) GetUserByName(name string) (*db.User, error) {
us.mtx.RLock() us.mtx.RLock()
defer us.mtx.RUnlock() defer us.mtx.RUnlock()
userID, ok := us.store.GetStringIn(IDsNs, name) return us.getUserByName(name)
if !ok {
return nil, ErrNotFound
}
infoStr, ok := us.store.GetStringIn(db.UsersNs, userID)
if !ok {
return nil, ErrNotFound
}
user := &db.User{}
err := json.Unmarshal([]byte(infoStr), user)
if err != nil {
return nil, err
}
if user.Name != name {
return nil, fmt.Errorf("user id (%s) not match: got(%s) expected(%s)", userID, user.Name, name)
}
// TODO: use sync.Pool instead
return user, nil
} }
func (us *KVUserStore) SetPwd(id uint64, pwd string) error { func (us *KVUserStore) SetPwd(id uint64, pwd string) error {
us.mtx.Lock() us.mtx.Lock()
defer us.mtx.Unlock() defer us.mtx.Unlock()
userID := fmt.Sprint(id) user, err := us.getUser(id)
infoStr, ok := us.store.GetStringIn(db.UsersNs, userID)
if !ok {
return fmt.Errorf("user (%d) does not exist", id)
}
gotUser := &db.User{}
err := json.Unmarshal([]byte(infoStr), gotUser)
if err != nil { if err != nil {
return err return err
} else if gotUser.ID != id {
return fmt.Errorf("user id key(%d) info(%d) does match", id, gotUser.ID)
} }
gotUser.Pwd = pwd user.Pwd = pwd
infoBytes, err := json.Marshal(gotUser) return us.setUser(user)
}
func (us *KVUserStore) SetInfo(id uint64, user *db.User) error {
us.mtx.Lock()
defer us.mtx.Unlock()
gotUser, err := us.getUser(id)
if err != nil { if err != nil {
return err return err
} }
return us.store.SetStringIn(db.UsersNs, userID, string(infoBytes))
gotUser.Role = user.Role
gotUser.Quota = user.Quota
gotUser.UsedSpace = user.UsedSpace
return us.setUser(gotUser)
} }
func (us *KVUserStore) SetPreferences(id uint64, prefers *db.Preferences) error { func (us *KVUserStore) SetPreferences(id uint64, prefers *db.Preferences) error {
us.mtx.Lock() us.mtx.Lock()
defer us.mtx.Unlock() defer us.mtx.Unlock()
userID := fmt.Sprint(id) user, err := us.getUser(id)
infoStr, ok := us.store.GetStringIn(db.UsersNs, userID)
if !ok {
return fmt.Errorf("user (%d) does not exist", id)
}
gotUser := &db.User{}
err := json.Unmarshal([]byte(infoStr), gotUser)
if err != nil {
return err
} else if gotUser.ID != id {
return fmt.Errorf("user id key(%d) info(%d) does match", id, gotUser.ID)
}
gotUser.Preferences = prefers
infoBytes, err := json.Marshal(gotUser)
if err != nil { if err != nil {
return err return err
} }
return us.store.SetStringIn(db.UsersNs, userID, string(infoBytes))
}
func (us *KVUserStore) CanIncrUsed(id uint64, capacity int64) (bool, error) { user.Preferences = prefers
us.mtx.Lock() return us.setUser(user)
defer us.mtx.Unlock()
userID := fmt.Sprint(id)
infoStr, ok := us.store.GetStringIn(db.UsersNs, userID)
if !ok {
return false, fmt.Errorf("user (%d) does not exist", id)
}
gotUser := &db.User{}
err := json.Unmarshal([]byte(infoStr), gotUser)
if err != nil {
return false, err
} else if gotUser.ID != id {
return false, fmt.Errorf("user id key(%d) info(%d) does match", id, gotUser.ID)
}
return gotUser.UsedSpace+capacity <= int64(gotUser.Quota.SpaceLimit), nil
} }
func (us *KVUserStore) SetUsed(id uint64, incr bool, capacity int64) error { func (us *KVUserStore) SetUsed(id uint64, incr bool, capacity int64) error {
us.mtx.Lock() us.mtx.Lock()
defer us.mtx.Unlock() defer us.mtx.Unlock()
userID := fmt.Sprint(id) gotUser, err := us.getUser(id)
infoStr, ok := us.store.GetStringIn(db.UsersNs, userID)
if !ok {
return fmt.Errorf("user (%d) does not exist", id)
}
gotUser := &db.User{}
err := json.Unmarshal([]byte(infoStr), gotUser)
if err != nil { if err != nil {
return err return err
} else if gotUser.ID != id {
return fmt.Errorf("user id key(%d) info(%d) does match", id, gotUser.ID)
} }
if incr && gotUser.UsedSpace+capacity > int64(gotUser.Quota.SpaceLimit) { if incr && gotUser.UsedSpace+capacity > int64(gotUser.Quota.SpaceLimit) {
@ -359,78 +277,26 @@ func (us *KVUserStore) SetUsed(id uint64, incr bool, capacity int64) error {
if incr { if incr {
gotUser.UsedSpace = gotUser.UsedSpace + capacity gotUser.UsedSpace = gotUser.UsedSpace + capacity
} else { } else {
if gotUser.UsedSpace-capacity < 0 {
return ErrNegtiveUsedSpace
}
gotUser.UsedSpace = gotUser.UsedSpace - capacity gotUser.UsedSpace = gotUser.UsedSpace - capacity
if gotUser.UsedSpace < 0 { // TODO: this is a work around
gotUser.UsedSpace = 0
} }
}
infoBytes, err := json.Marshal(gotUser) return us.setUser(gotUser)
if err != nil {
return err
}
return us.store.SetStringIn(db.UsersNs, userID, string(infoBytes))
} }
func (us *KVUserStore) ResetUsed(id uint64, used int64) error { func (us *KVUserStore) ResetUsed(id uint64, used int64) error {
us.mtx.Lock() us.mtx.Lock()
defer us.mtx.Unlock() defer us.mtx.Unlock()
userID := fmt.Sprint(id) gotUser, err := us.getUser(id)
infoStr, ok := us.store.GetStringIn(db.UsersNs, userID)
if !ok {
return fmt.Errorf("user (%d) does not exist", id)
}
gotUser := &db.User{}
err := json.Unmarshal([]byte(infoStr), gotUser)
if err != nil { if err != nil {
return err return err
} else if gotUser.ID != id {
return fmt.Errorf("user id key(%d) info(%d) does match", id, gotUser.ID)
} }
gotUser.UsedSpace = used gotUser.UsedSpace = used
infoBytes, err := json.Marshal(gotUser) return us.setUser(gotUser)
if err != nil {
return err
}
return us.store.SetStringIn(db.UsersNs, userID, string(infoBytes))
}
func (us *KVUserStore) SetInfo(id uint64, user *db.User) error {
us.mtx.Lock()
defer us.mtx.Unlock()
userID := fmt.Sprint(id)
infoStr, ok := us.store.GetStringIn(db.UsersNs, userID)
if !ok {
return fmt.Errorf("user (%d) does not exist", id)
}
gotUser := &db.User{}
err := json.Unmarshal([]byte(infoStr), gotUser)
if err != nil {
return err
} else if gotUser.ID != id {
return fmt.Errorf("user id key(%d) info(%d) does match", id, gotUser.ID)
}
// name and password can not be updated here
if user.Role != "" {
gotUser.Role = user.Role
}
if user.Quota != nil {
gotUser.Quota = user.Quota
}
if user.UsedSpace > 0 {
gotUser.UsedSpace = user.UsedSpace
}
infoBytes, err := json.Marshal(gotUser)
if err != nil {
return err
}
return us.store.SetStringIn(db.UsersNs, userID, string(infoBytes))
} }
func (us *KVUserStore) ListUsers() ([]*db.User, error) { func (us *KVUserStore) ListUsers() ([]*db.User, error) {
@ -441,7 +307,7 @@ func (us *KVUserStore) ListUsers() ([]*db.User, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
nameToID, err := us.store.ListStringsIn(IDsNs) nameToID, err := us.store.ListStringsIn(db.UserIDsNs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -474,7 +340,7 @@ func (us *KVUserStore) ListUsers() ([]*db.User, error) {
for name, id := range nameToID { for name, id := range nameToID {
_, ok := idToInfo[id] _, ok := idToInfo[id]
if !ok { if !ok {
err = us.store.DelStringIn(IDsNs, name) err = us.store.DelStringIn(db.UserIDsNs, name)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -490,35 +356,35 @@ func (us *KVUserStore) ListUserIDs() (map[string]string, error) {
us.mtx.RLock() us.mtx.RLock()
defer us.mtx.RUnlock() defer us.mtx.RUnlock()
return us.store.ListStringsIn(IDsNs) return us.store.ListStringsIn(db.UserIDsNs)
} }
func (us *KVUserStore) AddRole(role string) error { func (us *KVUserStore) AddRole(role string) error {
us.mtx.Lock() us.mtx.Lock()
defer us.mtx.Unlock() defer us.mtx.Unlock()
_, ok := us.store.GetBoolIn(RoleListNs, role) _, ok := us.store.GetBoolIn(db.RolesNs, role)
if ok { if ok {
return fmt.Errorf("role (%s) exists", role) return fmt.Errorf("role (%s) exists", role)
} }
return us.store.SetBoolIn(RoleListNs, role, true) return us.store.SetBoolIn(db.RolesNs, role, true)
} }
func (us *KVUserStore) DelRole(role string) error { func (us *KVUserStore) DelRole(role string) error {
us.mtx.Lock() us.mtx.Lock()
defer us.mtx.Unlock() defer us.mtx.Unlock()
if role == AdminRole || role == UserRole || role == VisitorRole { if role == db.AdminRole || role == db.UserRole || role == db.VisitorRole {
return errors.New("predefined roles can not be deleted") return errors.New("predefined roles can not be deleted")
} }
return us.store.DelBoolIn(RoleListNs, role) return us.store.DelBoolIn(db.RolesNs, role)
} }
func (us *KVUserStore) ListRoles() (map[string]bool, error) { func (us *KVUserStore) ListRoles() (map[string]bool, error) {
us.mtx.Lock() us.mtx.Lock()
defer us.mtx.Unlock() defer us.mtx.Unlock()
return us.store.ListBoolsIn(RoleListNs) return us.store.ListBoolsIn(db.RolesNs)
} }

View file

@ -8,7 +8,6 @@ import (
"testing" "testing"
"github.com/ihexxa/quickshare/src/db" "github.com/ihexxa/quickshare/src/db"
"github.com/ihexxa/quickshare/src/db/sitestore"
"github.com/ihexxa/quickshare/src/kvstore/boltdbpvd" "github.com/ihexxa/quickshare/src/kvstore/boltdbpvd"
) )
@ -26,16 +25,16 @@ func TestUserStores(t *testing.T) {
if root.Pwd != rootPwd { if root.Pwd != rootPwd {
t.Fatalf("passwords not match %s", err) t.Fatalf("passwords not match %s", err)
} }
if root.Role != AdminRole { if root.Role != db.AdminRole {
t.Fatalf("incorrect root role") t.Fatalf("incorrect root role")
} }
if root.Quota.SpaceLimit != defaultSpaceLimit { if root.Quota.SpaceLimit != db.DefaultSpaceLimit {
t.Fatalf("incorrect root SpaceLimit") t.Fatalf("incorrect root SpaceLimit")
} }
if root.Quota.UploadSpeedLimit != defaultUploadSpeedLimit { if root.Quota.UploadSpeedLimit != db.DefaultUploadSpeedLimit {
t.Fatalf("incorrect root UploadSpeedLimit") t.Fatalf("incorrect root UploadSpeedLimit")
} }
if root.Quota.DownloadSpeedLimit != defaultDownloadSpeedLimit { if root.Quota.DownloadSpeedLimit != db.DefaultDownloadSpeedLimit {
t.Fatalf("incorrect root DownloadSpeedLimit") t.Fatalf("incorrect root DownloadSpeedLimit")
} }
if !db.ComparePreferences(root.Preferences, &DefaultPreferences) { if !db.ComparePreferences(root.Preferences, &DefaultPreferences) {
@ -52,16 +51,16 @@ func TestUserStores(t *testing.T) {
if visitor.Pwd != rootPwd { if visitor.Pwd != rootPwd {
t.Fatalf("passwords not match %s", err) t.Fatalf("passwords not match %s", err)
} }
if visitor.Role != VisitorRole { if visitor.Role != db.VisitorRole {
t.Fatalf("incorrect visitor role") t.Fatalf("incorrect visitor role")
} }
if visitor.Quota.SpaceLimit != 0 { if visitor.Quota.SpaceLimit != 0 {
t.Fatalf("incorrect visitor SpaceLimit") t.Fatalf("incorrect visitor SpaceLimit")
} }
if visitor.Quota.UploadSpeedLimit != visitorUploadSpeedLimit { if visitor.Quota.UploadSpeedLimit != db.VisitorUploadSpeedLimit {
t.Fatalf("incorrect visitor UploadSpeedLimit") t.Fatalf("incorrect visitor UploadSpeedLimit")
} }
if visitor.Quota.DownloadSpeedLimit != visitorDownloadSpeedLimit { if visitor.Quota.DownloadSpeedLimit != db.VisitorDownloadSpeedLimit {
t.Fatalf("incorrect visitor DownloadSpeedLimit") t.Fatalf("incorrect visitor DownloadSpeedLimit")
} }
if !db.ComparePreferences(visitor.Preferences, &DefaultPreferences) { if !db.ComparePreferences(visitor.Preferences, &DefaultPreferences) {
@ -70,7 +69,7 @@ func TestUserStores(t *testing.T) {
id, name1 := uint64(2), "test_user1" id, name1 := uint64(2), "test_user1"
pwd1, pwd2 := "666", "888" pwd1, pwd2 := "666", "888"
role1, role2 := UserRole, AdminRole role1, role2 := db.UserRole, db.AdminRole
spaceLimit1, upLimit1, downLimit1 := int64(17), 5, 7 spaceLimit1, upLimit1, downLimit1 := int64(17), 5, 7
spaceLimit2, upLimit2, downLimit2 := int64(19), 13, 17 spaceLimit2, upLimit2, downLimit2 := int64(19), 13, 17
@ -121,7 +120,7 @@ func TestUserStores(t *testing.T) {
} }
for _, user := range users { for _, user := range users {
if user.ID == 0 { if user.ID == 0 {
if user.Name != rootName || user.Role != AdminRole { if user.Name != rootName || user.Role != db.AdminRole {
t.Fatalf("incorrect root info %v", user) t.Fatalf("incorrect root info %v", user)
} }
} }
@ -130,6 +129,9 @@ func TestUserStores(t *testing.T) {
t.Fatalf("incorrect user info %v", user) t.Fatalf("incorrect user info %v", user)
} }
} }
if user.Pwd != "" {
t.Fatalf("password must be empty")
}
} }
err = store.SetPwd(id, pwd2) err = store.SetPwd(id, pwd2)
@ -243,10 +245,10 @@ func TestUserStores(t *testing.T) {
t.Fatalf("users size should be 2 (%d)", len(users)) t.Fatalf("users size should be 2 (%d)", len(users))
} }
for _, user := range users { for _, user := range users {
if user.ID == 0 && user.Name != rootName && user.Role != AdminRole { if user.ID == 0 && user.Name != rootName && user.Role != db.AdminRole {
t.Fatalf("incorrect root info %v", user) t.Fatalf("incorrect root info %v", user)
} }
if user.ID == VisitorID && user.Name != VisitorName && user.Role != VisitorRole { if user.ID == VisitorID && user.Name != VisitorName && user.Role != db.VisitorRole {
t.Fatalf("incorrect visitor info %v", user) t.Fatalf("incorrect visitor info %v", user)
} }
} }
@ -276,7 +278,7 @@ func TestUserStores(t *testing.T) {
} }
for _, role := range append(roles, []string{ for _, role := range append(roles, []string{
AdminRole, UserRole, VisitorRole, db.AdminRole, db.UserRole, db.VisitorRole,
}...) { }...) {
if !roleMap[role] { if !roleMap[role] {
t.Fatalf("role(%s) not found", role) t.Fatalf("role(%s) not found", role)

View file

@ -95,7 +95,7 @@ func (lk *AutoLocker) Exec(handler func()) {
// related elements: role, user, action(listing, downloading)/sharing // related elements: role, user, action(listing, downloading)/sharing
func (h *FileHandlers) canAccess(userName, role, op, sharedPath string) bool { func (h *FileHandlers) canAccess(userName, role, op, sharedPath string) bool {
if role == userstore.AdminRole { if role == db.AdminRole {
return true return true
} }
@ -625,7 +625,7 @@ func (h *FileHandlers) Download(c *gin.Context) {
var err error var err error
userIDInt := userstore.VisitorID userIDInt := userstore.VisitorID
if role != userstore.VisitorRole { if role != db.VisitorRole {
userID := c.MustGet(q.UserIDParam).(string) userID := c.MustGet(q.UserIDParam).(string)
userIDInt, err = strconv.ParseUint(userID, 10, 64) userIDInt, err = strconv.ParseUint(userID, 10, 64)
if err != nil { if err != nil {

View file

@ -37,98 +37,98 @@ func NewMultiUsersSvc(cfg gocfg.ICfg, deps *depidx.Deps) (*MultiUsersSvc, error)
apiACRules := map[string]bool{ apiACRules := map[string]bool{
// TODO: make these configurable // TODO: make these configurable
// admin rules // admin rules
apiRuleCname(userstore.AdminRole, "GET", "/"): true, apiRuleCname(db.AdminRole, "GET", "/"): true,
apiRuleCname(userstore.AdminRole, "GET", publicPath): true, apiRuleCname(db.AdminRole, "GET", publicPath): true,
apiRuleCname(userstore.AdminRole, "POST", "/v1/users/login"): true, apiRuleCname(db.AdminRole, "POST", "/v1/users/login"): true,
apiRuleCname(userstore.AdminRole, "POST", "/v1/users/logout"): true, apiRuleCname(db.AdminRole, "POST", "/v1/users/logout"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/users/isauthed"): true, apiRuleCname(db.AdminRole, "GET", "/v1/users/isauthed"): true,
apiRuleCname(userstore.AdminRole, "PATCH", "/v1/users/pwd"): true, apiRuleCname(db.AdminRole, "PATCH", "/v1/users/pwd"): true,
apiRuleCname(userstore.AdminRole, "PATCH", "/v1/users/"): true, apiRuleCname(db.AdminRole, "PATCH", "/v1/users/"): true,
apiRuleCname(userstore.AdminRole, "PATCH", "/v1/users/pwd/force-set"): true, apiRuleCname(db.AdminRole, "PATCH", "/v1/users/pwd/force-set"): true,
apiRuleCname(userstore.AdminRole, "POST", "/v1/users/"): true, apiRuleCname(db.AdminRole, "POST", "/v1/users/"): true,
apiRuleCname(userstore.AdminRole, "DELETE", "/v1/users/"): true, apiRuleCname(db.AdminRole, "DELETE", "/v1/users/"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/users/list"): true, apiRuleCname(db.AdminRole, "GET", "/v1/users/list"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/users/self"): true, apiRuleCname(db.AdminRole, "GET", "/v1/users/self"): true,
apiRuleCname(userstore.AdminRole, "PATCH", "/v1/users/preferences"): true, apiRuleCname(db.AdminRole, "PATCH", "/v1/users/preferences"): true,
apiRuleCname(userstore.AdminRole, "PUT", "/v1/users/used-space"): true, apiRuleCname(db.AdminRole, "PUT", "/v1/users/used-space"): true,
apiRuleCname(userstore.AdminRole, "POST", "/v1/roles/"): true, apiRuleCname(db.AdminRole, "POST", "/v1/roles/"): true,
apiRuleCname(userstore.AdminRole, "DELETE", "/v1/roles/"): true, apiRuleCname(db.AdminRole, "DELETE", "/v1/roles/"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/roles/list"): true, apiRuleCname(db.AdminRole, "GET", "/v1/roles/list"): true,
apiRuleCname(userstore.AdminRole, "POST", "/v1/fs/files"): true, apiRuleCname(db.AdminRole, "POST", "/v1/fs/files"): true,
apiRuleCname(userstore.AdminRole, "DELETE", "/v1/fs/files"): true, apiRuleCname(db.AdminRole, "DELETE", "/v1/fs/files"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/fs/files"): true, apiRuleCname(db.AdminRole, "GET", "/v1/fs/files"): true,
apiRuleCname(userstore.AdminRole, "PATCH", "/v1/fs/files/chunks"): true, apiRuleCname(db.AdminRole, "PATCH", "/v1/fs/files/chunks"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/fs/files/chunks"): true, apiRuleCname(db.AdminRole, "GET", "/v1/fs/files/chunks"): true,
apiRuleCname(userstore.AdminRole, "PATCH", "/v1/fs/files/copy"): true, apiRuleCname(db.AdminRole, "PATCH", "/v1/fs/files/copy"): true,
apiRuleCname(userstore.AdminRole, "PATCH", "/v1/fs/files/move"): true, apiRuleCname(db.AdminRole, "PATCH", "/v1/fs/files/move"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/fs/dirs"): true, apiRuleCname(db.AdminRole, "GET", "/v1/fs/dirs"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/fs/dirs/home"): true, apiRuleCname(db.AdminRole, "GET", "/v1/fs/dirs/home"): true,
apiRuleCname(userstore.AdminRole, "POST", "/v1/fs/dirs"): true, apiRuleCname(db.AdminRole, "POST", "/v1/fs/dirs"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/fs/uploadings"): true, apiRuleCname(db.AdminRole, "GET", "/v1/fs/uploadings"): true,
apiRuleCname(userstore.AdminRole, "DELETE", "/v1/fs/uploadings"): true, apiRuleCname(db.AdminRole, "DELETE", "/v1/fs/uploadings"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/fs/metadata"): true, apiRuleCname(db.AdminRole, "GET", "/v1/fs/metadata"): true,
apiRuleCname(userstore.AdminRole, "OPTIONS", "/v1/settings/health"): true, apiRuleCname(db.AdminRole, "OPTIONS", "/v1/settings/health"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/settings/client"): true, apiRuleCname(db.AdminRole, "GET", "/v1/settings/client"): true,
apiRuleCname(userstore.AdminRole, "PATCH", "/v1/settings/client"): true, apiRuleCname(db.AdminRole, "PATCH", "/v1/settings/client"): true,
apiRuleCname(userstore.AdminRole, "POST", "/v1/settings/errors"): true, apiRuleCname(db.AdminRole, "POST", "/v1/settings/errors"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/settings/workers/queue-len"): true, apiRuleCname(db.AdminRole, "GET", "/v1/settings/workers/queue-len"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/captchas/"): true, apiRuleCname(db.AdminRole, "GET", "/v1/captchas/"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/captchas/imgs"): true, apiRuleCname(db.AdminRole, "GET", "/v1/captchas/imgs"): true,
apiRuleCname(userstore.AdminRole, "POST", "/v1/fs/sharings"): true, apiRuleCname(db.AdminRole, "POST", "/v1/fs/sharings"): true,
apiRuleCname(userstore.AdminRole, "DELETE", "/v1/fs/sharings"): true, apiRuleCname(db.AdminRole, "DELETE", "/v1/fs/sharings"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/fs/sharings"): true, apiRuleCname(db.AdminRole, "GET", "/v1/fs/sharings"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/fs/sharings/exist"): true, apiRuleCname(db.AdminRole, "GET", "/v1/fs/sharings/exist"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/fs/sharings/dirs"): true, apiRuleCname(db.AdminRole, "GET", "/v1/fs/sharings/dirs"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/fs/sharings/ids"): true, apiRuleCname(db.AdminRole, "GET", "/v1/fs/sharings/ids"): true,
apiRuleCname(userstore.AdminRole, "POST", "/v1/fs/hashes/sha1"): true, apiRuleCname(db.AdminRole, "POST", "/v1/fs/hashes/sha1"): true,
// user rules // user rules
apiRuleCname(userstore.UserRole, "GET", "/"): true, apiRuleCname(db.UserRole, "GET", "/"): true,
apiRuleCname(userstore.UserRole, "GET", publicPath): true, apiRuleCname(db.UserRole, "GET", publicPath): true,
apiRuleCname(userstore.UserRole, "POST", "/v1/users/logout"): true, apiRuleCname(db.UserRole, "POST", "/v1/users/logout"): true,
apiRuleCname(userstore.UserRole, "GET", "/v1/users/isauthed"): true, apiRuleCname(db.UserRole, "GET", "/v1/users/isauthed"): true,
apiRuleCname(userstore.UserRole, "PATCH", "/v1/users/pwd"): true, apiRuleCname(db.UserRole, "PATCH", "/v1/users/pwd"): true,
apiRuleCname(userstore.UserRole, "GET", "/v1/users/self"): true, apiRuleCname(db.UserRole, "GET", "/v1/users/self"): true,
apiRuleCname(userstore.UserRole, "PATCH", "/v1/users/preferences"): true, apiRuleCname(db.UserRole, "PATCH", "/v1/users/preferences"): true,
apiRuleCname(userstore.UserRole, "POST", "/v1/fs/files"): true, apiRuleCname(db.UserRole, "POST", "/v1/fs/files"): true,
apiRuleCname(userstore.UserRole, "DELETE", "/v1/fs/files"): true, apiRuleCname(db.UserRole, "DELETE", "/v1/fs/files"): true,
apiRuleCname(userstore.UserRole, "GET", "/v1/fs/files"): true, apiRuleCname(db.UserRole, "GET", "/v1/fs/files"): true,
apiRuleCname(userstore.UserRole, "PATCH", "/v1/fs/files/chunks"): true, apiRuleCname(db.UserRole, "PATCH", "/v1/fs/files/chunks"): true,
apiRuleCname(userstore.UserRole, "GET", "/v1/fs/files/chunks"): true, apiRuleCname(db.UserRole, "GET", "/v1/fs/files/chunks"): true,
apiRuleCname(userstore.UserRole, "PATCH", "/v1/fs/files/copy"): true, apiRuleCname(db.UserRole, "PATCH", "/v1/fs/files/copy"): true,
apiRuleCname(userstore.UserRole, "PATCH", "/v1/fs/files/move"): true, apiRuleCname(db.UserRole, "PATCH", "/v1/fs/files/move"): true,
apiRuleCname(userstore.UserRole, "GET", "/v1/fs/dirs"): true, apiRuleCname(db.UserRole, "GET", "/v1/fs/dirs"): true,
apiRuleCname(userstore.UserRole, "GET", "/v1/fs/dirs/home"): true, apiRuleCname(db.UserRole, "GET", "/v1/fs/dirs/home"): true,
apiRuleCname(userstore.UserRole, "POST", "/v1/fs/dirs"): true, apiRuleCname(db.UserRole, "POST", "/v1/fs/dirs"): true,
apiRuleCname(userstore.UserRole, "GET", "/v1/fs/uploadings"): true, apiRuleCname(db.UserRole, "GET", "/v1/fs/uploadings"): true,
apiRuleCname(userstore.UserRole, "DELETE", "/v1/fs/uploadings"): true, apiRuleCname(db.UserRole, "DELETE", "/v1/fs/uploadings"): true,
apiRuleCname(userstore.UserRole, "GET", "/v1/fs/metadata"): true, apiRuleCname(db.UserRole, "GET", "/v1/fs/metadata"): true,
apiRuleCname(userstore.UserRole, "OPTIONS", "/v1/settings/health"): true, apiRuleCname(db.UserRole, "OPTIONS", "/v1/settings/health"): true,
apiRuleCname(userstore.UserRole, "GET", "/v1/settings/client"): true, apiRuleCname(db.UserRole, "GET", "/v1/settings/client"): true,
apiRuleCname(userstore.UserRole, "POST", "/v1/settings/errors"): true, apiRuleCname(db.UserRole, "POST", "/v1/settings/errors"): true,
apiRuleCname(userstore.UserRole, "GET", "/v1/captchas/"): true, apiRuleCname(db.UserRole, "GET", "/v1/captchas/"): true,
apiRuleCname(userstore.UserRole, "GET", "/v1/captchas/imgs"): true, apiRuleCname(db.UserRole, "GET", "/v1/captchas/imgs"): true,
apiRuleCname(userstore.UserRole, "POST", "/v1/fs/sharings"): true, apiRuleCname(db.UserRole, "POST", "/v1/fs/sharings"): true,
apiRuleCname(userstore.UserRole, "DELETE", "/v1/fs/sharings"): true, apiRuleCname(db.UserRole, "DELETE", "/v1/fs/sharings"): true,
apiRuleCname(userstore.UserRole, "GET", "/v1/fs/sharings"): true, apiRuleCname(db.UserRole, "GET", "/v1/fs/sharings"): true,
apiRuleCname(userstore.UserRole, "GET", "/v1/fs/sharings/exist"): true, apiRuleCname(db.UserRole, "GET", "/v1/fs/sharings/exist"): true,
apiRuleCname(userstore.UserRole, "GET", "/v1/fs/sharings/dirs"): true, apiRuleCname(db.UserRole, "GET", "/v1/fs/sharings/dirs"): true,
apiRuleCname(userstore.UserRole, "GET", "/v1/fs/sharings/ids"): true, apiRuleCname(db.UserRole, "GET", "/v1/fs/sharings/ids"): true,
apiRuleCname(userstore.UserRole, "POST", "/v1/fs/hashes/sha1"): true, apiRuleCname(db.UserRole, "POST", "/v1/fs/hashes/sha1"): true,
// visitor rules // visitor rules
apiRuleCname(userstore.VisitorRole, "GET", "/"): true, apiRuleCname(db.VisitorRole, "GET", "/"): true,
apiRuleCname(userstore.VisitorRole, "GET", publicPath): true, apiRuleCname(db.VisitorRole, "GET", publicPath): true,
apiRuleCname(userstore.VisitorRole, "POST", "/v1/users/login"): true, apiRuleCname(db.VisitorRole, "POST", "/v1/users/login"): true,
apiRuleCname(userstore.VisitorRole, "GET", "/v1/users/self"): true, apiRuleCname(db.VisitorRole, "GET", "/v1/users/self"): true,
apiRuleCname(userstore.VisitorRole, "GET", "/v1/fs/files"): true, apiRuleCname(db.VisitorRole, "GET", "/v1/fs/files"): true,
apiRuleCname(userstore.VisitorRole, "GET", "/v1/fs/dirs"): true, apiRuleCname(db.VisitorRole, "GET", "/v1/fs/dirs"): true,
apiRuleCname(userstore.VisitorRole, "OPTIONS", "/v1/settings/health"): true, apiRuleCname(db.VisitorRole, "OPTIONS", "/v1/settings/health"): true,
apiRuleCname(userstore.VisitorRole, "GET", "/v1/settings/client"): true, apiRuleCname(db.VisitorRole, "GET", "/v1/settings/client"): true,
apiRuleCname(userstore.VisitorRole, "GET", "/v1/captchas/"): true, apiRuleCname(db.VisitorRole, "GET", "/v1/captchas/"): true,
apiRuleCname(userstore.VisitorRole, "GET", "/v1/captchas/imgs"): true, apiRuleCname(db.VisitorRole, "GET", "/v1/captchas/imgs"): true,
apiRuleCname(userstore.VisitorRole, "GET", "/v1/fs/sharings/exist"): true, apiRuleCname(db.VisitorRole, "GET", "/v1/fs/sharings/exist"): true,
apiRuleCname(userstore.VisitorRole, "GET", "/v1/fs/sharings/dirs"): true, apiRuleCname(db.VisitorRole, "GET", "/v1/fs/sharings/dirs"): true,
} }
handlers := &MultiUsersSvc{ handlers := &MultiUsersSvc{
@ -167,7 +167,7 @@ func (h *MultiUsersSvc) Init(adminName, adminPwd string) (string, error) {
return "", fmt.Errorf("download speed limit can not be lower than chunk size: %d", q.DownloadChunkSize) return "", fmt.Errorf("download speed limit can not be lower than chunk size: %d", q.DownloadChunkSize)
} }
if ok { if ok {
userCfgs, ok := usersInterface.([]*userstore.UserCfg) userCfgs, ok := usersInterface.([]*db.UserCfg)
if !ok { if !ok {
return "", fmt.Errorf("predefined user is invalid: %s", err) return "", fmt.Errorf("predefined user is invalid: %s", err)
} }
@ -242,7 +242,7 @@ func (h *MultiUsersSvc) Login(c *gin.Context) {
user, err := h.deps.Users().GetUserByName(req.User) user, err := h.deps.Users().GetUserByName(req.User)
if err != nil { if err != nil {
if errors.Is(err, userstore.ErrNotFound) { if errors.Is(err, userstore.ErrUserNotFound) {
c.JSON(q.ErrResp(c, 403, err)) c.JSON(q.ErrResp(c, 403, err))
return return
} }
@ -366,7 +366,7 @@ func (h *MultiUsersSvc) ForceSetPwd(c *gin.Context) {
c.JSON(q.ErrResp(c, 500, err)) c.JSON(q.ErrResp(c, 500, err))
return return
} }
if targetUser.Role == userstore.AdminRole { if targetUser.Role == db.AdminRole {
c.JSON(q.ErrResp(c, 403, errors.New("can not set admin's password"))) c.JSON(q.ErrResp(c, 403, errors.New("can not set admin's password")))
return return
} }
@ -626,7 +626,7 @@ func (h *MultiUsersSvc) isValidPwd(pwd string) error {
} }
func (h *MultiUsersSvc) isValidRole(role string) error { func (h *MultiUsersSvc) isValidRole(role string) error {
if role == userstore.AdminRole || role == userstore.UserRole || role == userstore.VisitorRole { if role == db.AdminRole || role == db.UserRole || role == db.VisitorRole {
return errors.New("predefined roles can not be added/deleted") return errors.New("predefined roles can not be added/deleted")
} }
return h.isValidUserName(role) return h.isValidUserName(role)

View file

@ -10,7 +10,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/ihexxa/quickshare/src/db/userstore" "github.com/ihexxa/quickshare/src/db"
q "github.com/ihexxa/quickshare/src/handlers" q "github.com/ihexxa/quickshare/src/handlers"
) )
@ -26,7 +26,7 @@ func (h *MultiUsersSvc) AuthN() gin.HandlerFunc {
claims := map[string]string{ claims := map[string]string{
q.UserIDParam: "", q.UserIDParam: "",
q.UserParam: "", q.UserParam: "",
q.RoleParam: userstore.VisitorRole, q.RoleParam: db.VisitorRole,
q.ExpireParam: "", q.ExpireParam: "",
} }
@ -59,7 +59,7 @@ func (h *MultiUsersSvc) AuthN() gin.HandlerFunc {
} else { } else {
claims[q.UserIDParam] = "0" claims[q.UserIDParam] = "0"
claims[q.UserParam] = "admin" claims[q.UserParam] = "admin"
claims[q.RoleParam] = userstore.AdminRole claims[q.RoleParam] = db.AdminRole
claims[q.ExpireParam] = "" claims[q.ExpireParam] = ""
} }

View file

@ -4,8 +4,6 @@ import (
"encoding/json" "encoding/json"
"github.com/ihexxa/quickshare/src/db" "github.com/ihexxa/quickshare/src/db"
"github.com/ihexxa/quickshare/src/db/sitestore"
"github.com/ihexxa/quickshare/src/db/userstore"
) )
type DbConfig struct { type DbConfig struct {
@ -35,7 +33,7 @@ type UsersCfg struct {
SpaceLimit int `json:"spaceLimit" yaml:"spaceLimit"` SpaceLimit int `json:"spaceLimit" yaml:"spaceLimit"`
LimiterCapacity int `json:"limiterCapacity" yaml:"limiterCapacity"` LimiterCapacity int `json:"limiterCapacity" yaml:"limiterCapacity"`
LimiterCyc int `json:"limiterCyc" yaml:"limiterCyc"` LimiterCyc int `json:"limiterCyc" yaml:"limiterCyc"`
PredefinedUsers []*userstore.UserCfg `json:"predefinedUsers" yaml:"predefinedUsers"` PredefinedUsers []*db.UserCfg `json:"predefinedUsers" yaml:"predefinedUsers"`
} }
type Secrets struct { type Secrets struct {
@ -64,7 +62,7 @@ type Config struct {
Server *ServerCfg `json:"server" yaml:"server"` Server *ServerCfg `json:"server" yaml:"server"`
Users *UsersCfg `json:"users" yaml:"users"` Users *UsersCfg `json:"users" yaml:"users"`
Workers *WorkerPoolCfg `json:"workers" yaml:"workers"` Workers *WorkerPoolCfg `json:"workers" yaml:"workers"`
Site *sitestore.SiteConfig `json:"site" yaml:"site"` Site *db.SiteConfig `json:"site" yaml:"site"`
Db *DbConfig `json:"db" yaml:"db"` Db *DbConfig `json:"db" yaml:"db"`
} }
@ -101,7 +99,7 @@ func DefaultConfigStruct() *Config {
SpaceLimit: 1024 * 1024 * 100, // 100MB SpaceLimit: 1024 * 1024 * 100, // 100MB
LimiterCapacity: 1000, LimiterCapacity: 1000,
LimiterCyc: 1000, // 1s LimiterCyc: 1000, // 1s
PredefinedUsers: []*userstore.UserCfg{}, PredefinedUsers: []*db.UserCfg{},
}, },
Secrets: &Secrets{ Secrets: &Secrets{
TokenSecret: "", TokenSecret: "",
@ -120,15 +118,15 @@ func DefaultConfigStruct() *Config {
SleepCyc: 1, SleepCyc: 1,
WorkerCount: 2, WorkerCount: 2,
}, },
Site: &sitestore.SiteConfig{ Site: &db.SiteConfig{
ClientCfg: &db.ClientConfig{ ClientCfg: &db.ClientConfig{
SiteName: "Quickshare", SiteName: "Quickshare",
SiteDesc: "quick and simple file sharing", SiteDesc: "quick and simple file sharing",
Bg: &db.BgConfig{ Bg: &db.BgConfig{
Url: "/static/img/textured_paper.png", Url: "/static/img/textured_paper.png",
Repeat: "repeat", Repeat: "repeat",
Position: "fixed", Position: "center",
Align: "center", Align: "fixed",
BgColor: "#ccc", BgColor: "#ccc",
}, },
}, },

View file

@ -8,8 +8,6 @@ import (
"github.com/ihexxa/gocfg" "github.com/ihexxa/gocfg"
"github.com/ihexxa/quickshare/src/db" "github.com/ihexxa/quickshare/src/db"
"github.com/ihexxa/quickshare/src/db/sitestore"
"github.com/ihexxa/quickshare/src/db/userstore"
) )
func TestLoadCfg(t *testing.T) { func TestLoadCfg(t *testing.T) {
@ -86,8 +84,8 @@ func TestLoadCfg(t *testing.T) {
SpaceLimit: 1, SpaceLimit: 1,
LimiterCapacity: 1, LimiterCapacity: 1,
LimiterCyc: 1, LimiterCyc: 1,
PredefinedUsers: []*userstore.UserCfg{ PredefinedUsers: []*db.UserCfg{
&userstore.UserCfg{ &db.UserCfg{
Name: "1", Name: "1",
Pwd: "1", Pwd: "1",
Role: "1", Role: "1",
@ -111,7 +109,7 @@ func TestLoadCfg(t *testing.T) {
SleepCyc: 1, SleepCyc: 1,
WorkerCount: 1, WorkerCount: 1,
}, },
Site: &sitestore.SiteConfig{ Site: &db.SiteConfig{
ClientCfg: &db.ClientConfig{ ClientCfg: &db.ClientConfig{
SiteName: "1", SiteName: "1",
SiteDesc: "1", SiteDesc: "1",
@ -152,8 +150,8 @@ func TestLoadCfg(t *testing.T) {
SpaceLimit: 4, SpaceLimit: 4,
LimiterCapacity: 4, LimiterCapacity: 4,
LimiterCyc: 4, LimiterCyc: 4,
PredefinedUsers: []*userstore.UserCfg{ PredefinedUsers: []*db.UserCfg{
&userstore.UserCfg{ &db.UserCfg{
Name: "4", Name: "4",
Pwd: "4", Pwd: "4",
Role: "4", Role: "4",
@ -177,7 +175,7 @@ func TestLoadCfg(t *testing.T) {
SleepCyc: 4, SleepCyc: 4,
WorkerCount: 4, WorkerCount: 4,
}, },
Site: &sitestore.SiteConfig{ Site: &db.SiteConfig{
ClientCfg: &db.ClientConfig{ ClientCfg: &db.ClientConfig{
SiteName: "4", SiteName: "4",
SiteDesc: "4", SiteDesc: "4",
@ -218,8 +216,8 @@ func TestLoadCfg(t *testing.T) {
SpaceLimit: 5, SpaceLimit: 5,
LimiterCapacity: 5, LimiterCapacity: 5,
LimiterCyc: 5, LimiterCyc: 5,
PredefinedUsers: []*userstore.UserCfg{ PredefinedUsers: []*db.UserCfg{
&userstore.UserCfg{ &db.UserCfg{
Name: "5", Name: "5",
Pwd: "5", Pwd: "5",
Role: "5", Role: "5",
@ -243,7 +241,7 @@ func TestLoadCfg(t *testing.T) {
SleepCyc: 4, SleepCyc: 4,
WorkerCount: 4, WorkerCount: 4,
}, },
Site: &sitestore.SiteConfig{ Site: &db.SiteConfig{
ClientCfg: &db.ClientConfig{ ClientCfg: &db.ClientConfig{
SiteName: "4", SiteName: "4",
SiteDesc: "4", SiteDesc: "4",
@ -284,8 +282,8 @@ func TestLoadCfg(t *testing.T) {
SpaceLimit: 5, SpaceLimit: 5,
LimiterCapacity: 5, LimiterCapacity: 5,
LimiterCyc: 5, LimiterCyc: 5,
PredefinedUsers: []*userstore.UserCfg{ PredefinedUsers: []*db.UserCfg{
&userstore.UserCfg{ &db.UserCfg{
Name: "5", Name: "5",
Pwd: "5", Pwd: "5",
Role: "5", Role: "5",
@ -309,7 +307,7 @@ func TestLoadCfg(t *testing.T) {
SleepCyc: 4, SleepCyc: 4,
WorkerCount: 4, WorkerCount: 4,
}, },
Site: &sitestore.SiteConfig{ Site: &db.SiteConfig{
ClientCfg: &db.ClientConfig{ ClientCfg: &db.ClientConfig{
SiteName: "4", SiteName: "4",
SiteDesc: "4", SiteDesc: "4",

View file

@ -162,15 +162,15 @@ func initDeps(cfg gocfg.ICfg) *depidx.Deps {
panic(fmt.Sprintf("fail to init bolt store: %s", err)) panic(fmt.Sprintf("fail to init bolt store: %s", err))
} }
err = siteStore.Init(&sitestore.SiteConfig{ err = siteStore.Init(&db.SiteConfig{
ClientCfg: &db.ClientConfig{ ClientCfg: &db.ClientConfig{
SiteName: cfg.StringOr("Site.ClientCfg.SiteName", "Quickshare"), SiteName: cfg.StringOr("Site.ClientCfg.SiteName", "Quickshare"),
SiteDesc: cfg.StringOr("Site.ClientCfg.SiteDesc", "quick and simple file sharing"), SiteDesc: cfg.StringOr("Site.ClientCfg.SiteDesc", "quick and simple file sharing"),
Bg: &db.BgConfig{ Bg: &db.BgConfig{
Url: cfg.StringOr("Site.ClientCfg.Bg.Url", "/static/img/textured_paper.png"), Url: cfg.StringOr("Site.ClientCfg.Bg.Url", "/static/img/textured_paper.png"),
Repeat: cfg.StringOr("Site.ClientCfg.Bg.Repeat", "repeat"), Repeat: cfg.StringOr("Site.ClientCfg.Bg.Repeat", "repeat"),
Position: cfg.StringOr("Site.ClientCfg.Bg.Position", "fixed"), Position: cfg.StringOr("Site.ClientCfg.Bg.Position", "center"),
Align: cfg.StringOr("Site.ClientCfg.Bg.Align", "center"), Align: cfg.StringOr("Site.ClientCfg.Bg.Align", "fixed"),
BgColor: cfg.StringOr("Site.ClientCfg.Bg.BgColor", "#ccc"), BgColor: cfg.StringOr("Site.ClientCfg.Bg.BgColor", "#ccc"),
}, },
}, },

View file

@ -11,7 +11,6 @@ import (
"github.com/ihexxa/quickshare/src/client" "github.com/ihexxa/quickshare/src/client"
"github.com/ihexxa/quickshare/src/db" "github.com/ihexxa/quickshare/src/db"
"github.com/ihexxa/quickshare/src/db/userstore"
q "github.com/ihexxa/quickshare/src/handlers" q "github.com/ihexxa/quickshare/src/handlers"
"github.com/ihexxa/quickshare/src/handlers/settings" "github.com/ihexxa/quickshare/src/handlers/settings"
) )
@ -105,7 +104,7 @@ func TestPermissions(t *testing.T) {
testUsersAPIs := func(desc, user string, pwd string, requireAuth bool, expectedCodes map[string]int) { testUsersAPIs := func(desc, user string, pwd string, requireAuth bool, expectedCodes map[string]int) {
newPwd := "12345" newPwd := "12345"
newRole := userstore.AdminRole newRole := db.AdminRole
newQuota := &db.Quota{ newQuota := &db.Quota{
SpaceLimit: int64(2046), SpaceLimit: int64(2046),
UploadSpeedLimit: int(8 * 1024 * 1024), UploadSpeedLimit: int(8 * 1024 * 1024),
@ -146,7 +145,7 @@ func TestPermissions(t *testing.T) {
// user management // user management
resp, addUserResp, errs := cl.AddUser(tmpUser, tmpPwd, tmpRole, token) resp, addUserResp, errs := cl.AddUser(tmpUser, tmpPwd, tmpRole, token)
assertResp(t, resp, errs, expectedCodes["AddUser"], fmt.Sprintf("%s-%s", desc, "AddUser")) assertResp(t, resp, errs, expectedCodes["AddUser"], fmt.Sprintf("%s-%s", desc, "AddUser"))
resp, addAdminResp, errs := cl.AddUser(tmpAdmin, tmpAdminPwd, userstore.AdminRole, token) resp, addAdminResp, errs := cl.AddUser(tmpAdmin, tmpAdminPwd, db.AdminRole, token)
assertResp(t, resp, errs, expectedCodes["AddUser"], fmt.Sprintf("%s-%s", desc, "AddUser")) assertResp(t, resp, errs, expectedCodes["AddUser"], fmt.Sprintf("%s-%s", desc, "AddUser"))
resp, _, errs = cl.ListUsers(token) resp, _, errs = cl.ListUsers(token)
@ -186,9 +185,9 @@ func TestPermissions(t *testing.T) {
resp, _, errs = cl.SetUser(userID, newRole, newQuota, token) resp, _, errs = cl.SetUser(userID, newRole, newQuota, token)
assertResp(t, resp, errs, expectedCodes["SetUserSelf"], fmt.Sprintf("%s-%s", desc, "SetUserSelf")) assertResp(t, resp, errs, expectedCodes["SetUserSelf"], fmt.Sprintf("%s-%s", desc, "SetUserSelf"))
// update other users // update other users
resp, _, errs = cl.SetUser(tmpUserID, userstore.AdminRole, newQuota, token) resp, _, errs = cl.SetUser(tmpUserID, db.AdminRole, newQuota, token)
assertResp(t, resp, errs, expectedCodes["SetUserOthers"], fmt.Sprintf("%s-%s", desc, "SetUserOthers")) assertResp(t, resp, errs, expectedCodes["SetUserOthers"], fmt.Sprintf("%s-%s", desc, "SetUserOthers"))
resp, _, errs = cl.SetUser(0, userstore.UserRole, newQuota, token) resp, _, errs = cl.SetUser(0, db.UserRole, newQuota, token)
assertResp(t, resp, errs, expectedCodes["SetUserOthersAdmin"], fmt.Sprintf("%s-%s", desc, "SetUserOthersAdmin")) assertResp(t, resp, errs, expectedCodes["SetUserOthersAdmin"], fmt.Sprintf("%s-%s", desc, "SetUserOthersAdmin"))
resp, _, errs = cl.DelUser(addUserResp.ID, token) resp, _, errs = cl.DelUser(addUserResp.ID, token)

View file

@ -9,7 +9,7 @@ import (
"time" "time"
"github.com/ihexxa/quickshare/src/client" "github.com/ihexxa/quickshare/src/client"
"github.com/ihexxa/quickshare/src/db/userstore" "github.com/ihexxa/quickshare/src/db"
q "github.com/ihexxa/quickshare/src/handlers" q "github.com/ihexxa/quickshare/src/handlers"
) )
@ -82,7 +82,7 @@ func TestSpaceLimit(t *testing.T) {
for i := 0; i < userCount; i++ { for i := 0; i < userCount; i++ {
userName := getUserName(i) userName := getUserName(i)
resp, adResp, errs := usersCl.AddUser(userName, userPwd, userstore.UserRole, token) resp, adResp, errs := usersCl.AddUser(userName, userPwd, db.UserRole, token)
if len(errs) > 0 { if len(errs) > 0 {
t.Fatal(errs) t.Fatal(errs)
} else if resp.StatusCode != 200 { } else if resp.StatusCode != 200 {

View file

@ -89,7 +89,7 @@ func TestUsersHandlers(t *testing.T) {
for _, user := range lsResp.Users { for _, user := range lsResp.Users {
if user.Name == adminName { if user.Name == adminName {
if user.ID != 0 || if user.ID != 0 ||
user.Role != userstore.AdminRole || user.Role != db.AdminRole ||
user.UsedSpace != 0 || user.UsedSpace != 0 ||
user.Quota.SpaceLimit != 1024*1024*1024 || // TODO: export these user.Quota.SpaceLimit != 1024*1024*1024 || // TODO: export these
user.Quota.UploadSpeedLimit != 50*1024*1024 || user.Quota.UploadSpeedLimit != 50*1024*1024 ||
@ -99,7 +99,7 @@ func TestUsersHandlers(t *testing.T) {
} }
} }
if user.Name == "visitor" { if user.Name == "visitor" {
if user.Role != userstore.VisitorRole || if user.Role != db.VisitorRole ||
user.Quota.SpaceLimit != 0 || // TODO: export these user.Quota.SpaceLimit != 0 || // TODO: export these
user.Quota.UploadSpeedLimit != 10*1024*1024 || user.Quota.UploadSpeedLimit != 10*1024*1024 ||
user.Quota.DownloadSpeedLimit != 10*1024*1024 || user.Quota.DownloadSpeedLimit != 10*1024*1024 ||
@ -108,7 +108,7 @@ func TestUsersHandlers(t *testing.T) {
} }
} }
if user.Name == "demo" { if user.Name == "demo" {
if user.Role != userstore.UserRole || if user.Role != db.UserRole ||
user.Quota.SpaceLimit != 1024 || user.Quota.SpaceLimit != 1024 ||
user.Quota.UploadSpeedLimit != 409600 || user.Quota.UploadSpeedLimit != 409600 ||
user.Quota.DownloadSpeedLimit != 409600 || user.Quota.DownloadSpeedLimit != 409600 ||
@ -125,7 +125,7 @@ func TestUsersHandlers(t *testing.T) {
ID: 0, ID: 0,
Name: adminName, Name: adminName,
Pwd: adminPwd, Pwd: adminPwd,
Role: userstore.AdminRole, Role: db.AdminRole,
UsedSpace: 0, UsedSpace: 0,
Quota: &db.Quota{ Quota: &db.Quota{
UploadSpeedLimit: 50 * 1024 * 1024, UploadSpeedLimit: 50 * 1024 * 1024,
@ -137,7 +137,7 @@ func TestUsersHandlers(t *testing.T) {
ID: 0, ID: 0,
Name: "demo", Name: "demo",
Pwd: "Quicksh@re", Pwd: "Quicksh@re",
Role: userstore.UserRole, Role: db.UserRole,
UsedSpace: 0, UsedSpace: 0,
Quota: &db.Quota{ Quota: &db.Quota{
UploadSpeedLimit: 409600, UploadSpeedLimit: 409600,
@ -171,7 +171,7 @@ func TestUsersHandlers(t *testing.T) {
// TODO: expose default values from userstore // TODO: expose default values from userstore
t.Fatalf("user infos don't match %v", selfResp) t.Fatalf("user infos don't match %v", selfResp)
} }
if selfResp.Role == userstore.AdminRole { if selfResp.Role == db.AdminRole {
if selfResp.ID != "0" { if selfResp.ID != "0" {
t.Fatalf("user id don't match %v", selfResp) t.Fatalf("user id don't match %v", selfResp)
} }
@ -210,7 +210,7 @@ func TestUsersHandlers(t *testing.T) {
token := client.GetCookie(resp.Cookies(), su.TokenCookie) token := client.GetCookie(resp.Cookies(), su.TokenCookie)
userName, userPwd := "user_login", "1234" userName, userPwd := "user_login", "1234"
resp, auResp, errs := usersCl.AddUser(userName, userPwd, userstore.UserRole, token) resp, auResp, errs := usersCl.AddUser(userName, userPwd, db.UserRole, token)
if len(errs) > 0 { if len(errs) > 0 {
t.Fatal(errs) t.Fatal(errs)
} else if resp.StatusCode != 200 { } else if resp.StatusCode != 200 {
@ -270,7 +270,7 @@ func TestUsersHandlers(t *testing.T) {
token := client.GetCookie(resp.Cookies(), su.TokenCookie) token := client.GetCookie(resp.Cookies(), su.TokenCookie)
userName, userPwd, userRole := "new_user", "1234", userstore.UserRole userName, userPwd, userRole := "new_user", "1234", db.UserRole
resp, auResp, errs := usersCl.AddUser(userName, userPwd, userRole, token) resp, auResp, errs := usersCl.AddUser(userName, userPwd, userRole, token)
if len(errs) > 0 { if len(errs) > 0 {
t.Fatal(errs) t.Fatal(errs)
@ -297,7 +297,7 @@ func TestUsersHandlers(t *testing.T) {
for _, user := range lsResp.Users { for _, user := range lsResp.Users {
if user.ID == 0 { if user.ID == 0 {
if user.Name != adminName || if user.Name != adminName ||
user.Role != userstore.AdminRole { user.Role != db.AdminRole {
t.Fatal(fmt.Errorf("incorrect root info (%v)", user)) t.Fatal(fmt.Errorf("incorrect root info (%v)", user))
} }
} }
@ -309,7 +309,7 @@ func TestUsersHandlers(t *testing.T) {
} }
} }
newRole, newQuota := userstore.AdminRole, &db.Quota{ newRole, newQuota := db.AdminRole, &db.Quota{
SpaceLimit: 3, SpaceLimit: 3,
UploadSpeedLimit: 3, UploadSpeedLimit: 3,
DownloadSpeedLimit: 3, DownloadSpeedLimit: 3,
@ -396,9 +396,9 @@ func TestUsersHandlers(t *testing.T) {
t.Fatal(resp.StatusCode) t.Fatal(resp.StatusCode)
} }
for _, role := range append(roles, []string{ for _, role := range append(roles, []string{
userstore.AdminRole, db.AdminRole,
userstore.UserRole, db.UserRole,
userstore.VisitorRole, db.VisitorRole,
}...) { }...) {
if !lsResp.Roles[role] { if !lsResp.Roles[role] {
t.Fatalf("role(%s) not found", role) t.Fatalf("role(%s) not found", role)

View file

@ -14,7 +14,7 @@ import (
"github.com/ihexxa/gocfg" "github.com/ihexxa/gocfg"
"github.com/ihexxa/quickshare/src/client" "github.com/ihexxa/quickshare/src/client"
"github.com/ihexxa/quickshare/src/db/userstore" "github.com/ihexxa/quickshare/src/db"
fspkg "github.com/ihexxa/quickshare/src/fs" fspkg "github.com/ihexxa/quickshare/src/fs"
) )
@ -62,7 +62,7 @@ func addUsers(t *testing.T, addr, userPwd string, userCount int, adminToken *htt
for i := range make([]int, userCount) { for i := range make([]int, userCount) {
userName := getUserName(i) userName := getUserName(i)
resp, adResp, errs := usersCl.AddUser(userName, userPwd, userstore.UserRole, adminToken) resp, adResp, errs := usersCl.AddUser(userName, userPwd, db.UserRole, adminToken)
if len(errs) > 0 { if len(errs) > 0 {
t.Fatal(errs) t.Fatal(errs)
} else if resp.StatusCode != 200 { } else if resp.StatusCode != 200 {

Binary file not shown.