Skip to content

Commit

Permalink
roles: Adds ability to update a role using PUT (#14)
Browse files Browse the repository at this point in the history
* transfer UpdateRoleMembers from ory/hydra#768 to keto

* fix tests by using right http method & correcting sql request

* Change behavior to overwrite the whole role instead of just the members.
+ small sql migration fix
  • Loading branch information
zepatrik authored and arekkas committed May 23, 2018
1 parent 70b12ad commit 97ccbe6
Show file tree
Hide file tree
Showing 57 changed files with 639 additions and 197 deletions.
36 changes: 36 additions & 0 deletions docs/api.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,38 @@
}
}
},
"put": {
"description": "This endpoint allows you to overwrite a role. You have to know the role's ID.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"schemes": [
"http",
"https"
],
"tags": [
"role"
],
"summary": "A Role represents a group of users that share the same role and thus permissions. A role could be an administrator, a moderator, a regular\nuser or some other sort of role.",
"operationId": "setRole",
"responses": {
"204": {
"$ref": "#/responses/emptyResponse"
},
"401": {
"$ref": "#/responses/genericError"
},
"403": {
"$ref": "#/responses/genericError"
},
"500": {
"$ref": "#/responses/genericError"
}
}
},
"delete": {
"description": "A Role represents a group of users that share the same role and thus permissions. A role could be an administrator, a moderator, a regular\nuser or some other sort of role.\n\nThis endpoint allows you to delete an existing role. You have to know the role's ID.",
"consumes": [
Expand Down Expand Up @@ -820,6 +852,10 @@
"type": "string",
"x-go-name": "Subject"
},
"token_type": {
"type": "string",
"x-go-name": "TokenType"
},
"username": {
"type": "string",
"x-go-name": "Username"
Expand Down
41 changes: 41 additions & 0 deletions role/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func (h *Handler) SetRoutes(r *httprouter.Router) {
r.DELETE(handlerBasePath+"/:id", h.DeleteRole)
r.POST(handlerBasePath+"/:id/members", h.AddRoleMembers)
r.DELETE(handlerBasePath+"/:id/members", h.DeleteRoleMembers)
r.PUT(handlerBasePath+"/:id", h.UpdateRole)
}

// swagger:route GET /roles role listRoles
Expand Down Expand Up @@ -295,3 +296,43 @@ func (h *Handler) DeleteRoleMembers(w http.ResponseWriter, r *http.Request, ps h

w.WriteHeader(http.StatusNoContent)
}

// swagger:route PUT /roles/{id} role setRole
//
// A Role represents a group of users that share the same role and thus permissions. A role could be an administrator, a moderator, a regular
// user or some other sort of role.
//
// This endpoint allows you to overwrite a role. You have to know the role's ID.
//
// Consumes:
// - application/json
//
// Produces:
// - application/json
//
// Schemes: http, https
//
// Responses:
// 204: emptyResponse
// 401: genericError
// 403: genericError
// 500: genericError
func (h *Handler) UpdateRole(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
var id = ps.ByName("id")

var m membersRequest
if err := json.NewDecoder(r.Body).Decode(&m); err != nil {
h.H.WriteError(w, r, errors.WithStack(err))
return
}

if err := h.Manager.UpdateRole(Role{
ID: id,
Members: m.Members,
}); err != nil {
h.H.WriteError(w, r, err)
return
}

w.WriteHeader(http.StatusNoContent)
}
5 changes: 3 additions & 2 deletions role/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ type Manager interface {
GetRole(id string) (*Role, error)
DeleteRole(id string) error

AddRoleMembers(group string, members []string) error
RemoveRoleMembers(group string, members []string) error
AddRoleMembers(role string, members []string) error
RemoveRoleMembers(role string, members []string) error

FindRolesByMember(member string, limit, offset int) ([]Role, error)
ListRoles(limit, offset int) ([]Role, error)
UpdateRole(role Role) error
}
52 changes: 32 additions & 20 deletions role/manager_memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,23 @@ type MemoryManager struct {
sync.RWMutex
}

func (m *MemoryManager) CreateRole(g *Role) error {
if g.ID == "" {
g.ID = uuid.New()
func (m *MemoryManager) CreateRole(r *Role) error {
if r.ID == "" {
r.ID = uuid.New()
}
if m.Roles == nil {
m.Roles = map[string]Role{}
}

m.Roles[g.ID] = *g
m.Roles[r.ID] = *r
return nil
}

func (m *MemoryManager) GetRole(id string) (*Role, error) {
if g, ok := m.Roles[id]; !ok {
if r, ok := m.Roles[id]; !ok {
return nil, errors.WithStack(pkg.ErrNotFound)
} else {
return &g, nil
return &r, nil
}
}

Expand All @@ -65,23 +65,23 @@ func (m *MemoryManager) DeleteRole(id string) error {
return nil
}

func (m *MemoryManager) AddRoleMembers(group string, subjects []string) error {
g, err := m.GetRole(group)
func (m *MemoryManager) AddRoleMembers(role string, subjects []string) error {
r, err := m.GetRole(role)
if err != nil {
return err
}
g.Members = append(g.Members, subjects...)
return m.CreateRole(g)
r.Members = append(r.Members, subjects...)
return m.CreateRole(r)
}

func (m *MemoryManager) RemoveRoleMembers(group string, subjects []string) error {
g, err := m.GetRole(group)
func (m *MemoryManager) RemoveRoleMembers(role string, subjects []string) error {
r, err := m.GetRole(role)
if err != nil {
return err
}

var subs []string
for _, s := range g.Members {
for _, s := range r.Members {
var remove bool
for _, f := range subjects {
if f == s {
Expand All @@ -94,8 +94,8 @@ func (m *MemoryManager) RemoveRoleMembers(group string, subjects []string) error
}
}

g.Members = subs
return m.CreateRole(g)
r.Members = subs
return m.CreateRole(r)
}

func (m *MemoryManager) FindRolesByMember(member string, limit, offset int) ([]Role, error) {
Expand All @@ -104,10 +104,10 @@ func (m *MemoryManager) FindRolesByMember(member string, limit, offset int) ([]R
}

res := make([]Role, 0)
for _, g := range m.Roles {
for _, s := range g.Members {
for _, r := range m.Roles {
for _, s := range r.Members {
if s == member {
res = append(res, g)
res = append(res, r)
break
}
}
Expand All @@ -124,11 +124,23 @@ func (m *MemoryManager) ListRoles(limit, offset int) ([]Role, error) {

i := 0
res := make([]Role, len(m.Roles))
for _, g := range m.Roles {
res[i] = g
for _, r := range m.Roles {
res[i] = r
i++
}

start, end := pagination.Index(limit, offset, len(res))
return res[start:end], nil
}

func (m *MemoryManager) UpdateRole(role Role) error {
if err := m.DeleteRole(role.ID); err != nil {
return err
}

if err := m.CreateRole(&role); err != nil {
return err
}

return nil
}
Loading

0 comments on commit 97ccbe6

Please sign in to comment.