diff --git a/internal/api/members/crud.go b/internal/api/members/crud.go index a338ef1d..b684414f 100644 --- a/internal/api/members/crud.go +++ b/internal/api/members/crud.go @@ -12,15 +12,15 @@ type MemberCreatePayload struct { } type MemberDataPayload struct { - ID string `json:"id"` - Secret string `json:"secret,omitempty"` - Name string `json:"name"` - IsAdmin bool `json:"is_admin"` - CanLogin bool `json:"can_login"` - CanConnect bool `json:"can_connect"` - CanWatch bool `json:"can_watch"` - CanHost bool `json:"can_host"` - CanAccessClipboard bool `json:"can_access_clipboard"` + ID *string `json:"id"` + Secret *string `json:"secret,omitempty"` + Name *string `json:"name"` + IsAdmin *bool `json:"is_admin"` + CanLogin *bool `json:"can_login"` + CanConnect *bool `json:"can_connect"` + CanWatch *bool `json:"can_watch"` + CanHost *bool `json:"can_host"` + CanAccessClipboard *bool `json:"can_access_clipboard"` } func (h *MembersHandler) membersCreate(w http.ResponseWriter, r *http.Request) { @@ -29,29 +29,40 @@ func (h *MembersHandler) membersCreate(w http.ResponseWriter, r *http.Request) { return } - if data.ID == "" { + if data.Secret == nil || *data.Secret == "" { + utils.HttpBadRequest(w, "Secret cannot be empty.") + return + } + + if data.Name == nil || *data.Name == "" { + utils.HttpBadRequest(w, "Name cannot be empty.") + return + } + + var ID string + if data.ID == nil || *data.ID == "" { var err error - if data.ID, err = utils.NewUID(32); err != nil { + if ID, err = utils.NewUID(32); err != nil { utils.HttpInternalServerError(w, err) return } } else { - if _, ok := h.sessions.Get(data.ID); ok { + ID = *data.ID + if _, ok := h.sessions.Get(ID); ok { utils.HttpBadRequest(w, "Member ID already exists.") return } } - // TODO: Join structs? - session, err := h.sessions.Create(data.ID, types.MemberProfile{ - Secret: data.Secret, - Name: data.Name, - IsAdmin: data.IsAdmin, - CanLogin: data.CanLogin, - CanConnect: data.CanConnect, - CanWatch: data.CanWatch, - CanHost: data.CanHost, - CanAccessClipboard: data.CanAccessClipboard, + session, err := h.sessions.Create(ID, types.MemberProfile{ + Secret: *data.Secret, + Name: *data.Name, + IsAdmin: defaultBool(data.IsAdmin, false), + CanLogin: defaultBool(data.CanLogin, true), + CanConnect: defaultBool(data.CanConnect, true), + CanWatch: defaultBool(data.CanWatch, true), + CanHost: defaultBool(data.CanHost, true), + CanAccessClipboard: defaultBool(data.CanAccessClipboard, true), }) if err != nil { @@ -68,14 +79,15 @@ func (h *MembersHandler) membersRead(w http.ResponseWriter, r *http.Request) { member := GetMember(r) // TODO: Join structs? + // TODO: Ugly. utils.HttpSuccess(w, MemberDataPayload{ - Name: member.Name(), - IsAdmin: member.IsAdmin(), - CanLogin: member.CanLogin(), - CanConnect: member.CanConnect(), - CanWatch: member.CanWatch(), - CanHost: member.CanHost(), - CanAccessClipboard: member.CanAccessClipboard(), + Name: func(v string) *string { return &v }(member.Name()), + IsAdmin: func(v bool) *bool { return &v }(member.IsAdmin()), + CanLogin: func(v bool) *bool { return &v }(member.CanLogin()), + CanConnect: func(v bool) *bool { return &v }(member.CanConnect()), + CanWatch: func(v bool) *bool { return &v }(member.CanWatch()), + CanHost: func(v bool) *bool { return &v }(member.CanHost()), + CanAccessClipboard: func(v bool) *bool { return &v }(member.CanAccessClipboard()), }) } @@ -87,18 +99,29 @@ func (h *MembersHandler) membersUpdate(w http.ResponseWriter, r *http.Request) { member := GetMember(r) + secret := "" + if data.Secret != nil && *data.Secret != "" { + secret = *data.Secret + } + + name := member.Name() + if data.Name != nil && *data.Name != "" { + name = *data.Name + } + // TODO: Join structs? - // TODO: Update independent props. - if err := h.sessions.Update(member.ID(), types.MemberProfile{ - Secret: data.Secret, - Name: data.Name, - IsAdmin: data.IsAdmin, - CanLogin: data.CanLogin, - CanConnect: data.CanConnect, - CanWatch: data.CanWatch, - CanHost: data.CanHost, - CanAccessClipboard: data.CanAccessClipboard, - }); err != nil { + err := h.sessions.Update(member.ID(), types.MemberProfile{ + Secret: secret, + Name: name, + IsAdmin: defaultBool(data.IsAdmin, member.IsAdmin()), + CanLogin: defaultBool(data.CanLogin, member.CanLogin()), + CanConnect: defaultBool(data.CanConnect, member.CanConnect()), + CanWatch: defaultBool(data.CanWatch, member.CanWatch()), + CanHost: defaultBool(data.CanHost, member.CanHost()), + CanAccessClipboard: defaultBool(data.CanAccessClipboard, member.CanAccessClipboard()), + }) + + if err != nil { utils.HttpInternalServerError(w, err) return } @@ -116,3 +139,10 @@ func (h *MembersHandler) membersDelete(w http.ResponseWriter, r *http.Request) { utils.HttpSuccess(w) } + +func defaultBool(val *bool, def bool) bool { + if val != nil { + return *val + } + return def +} diff --git a/internal/session/manager.go b/internal/session/manager.go index d3fb9e32..a8702d26 100644 --- a/internal/session/manager.go +++ b/internal/session/manager.go @@ -132,6 +132,11 @@ func (manager *SessionManagerCtx) Update(id string, profile types.MemberProfile) return fmt.Errorf("Member not found.") } + // preserve secret if not updated + if profile.Secret == "" { + profile.Secret = session.profile.Secret + } + err := manager.database.Update(id, profile) if err != nil { manager.membersMu.Unlock()