auth: separate the role create and update path
Giving both permission and grant/revoke is not allowed. Creating an existing role is not allowed. Updating a non-existing is not allowed.
This commit is contained in:
@ -97,6 +97,10 @@ type Permissions struct {
|
|||||||
KV rwPermission `json:"kv"`
|
KV rwPermission `json:"kv"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Permissions) IsEmpty() bool {
|
||||||
|
return p == nil || (len(p.KV.Read) == 0 && len(p.KV.Write) == 0)
|
||||||
|
}
|
||||||
|
|
||||||
type rwPermission struct {
|
type rwPermission struct {
|
||||||
Read []string `json:"read"`
|
Read []string `json:"read"`
|
||||||
Write []string `json:"write"`
|
Write []string `json:"write"`
|
||||||
@ -297,16 +301,6 @@ func (s *Store) GetRole(name string) (Role, error) {
|
|||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Store) CreateOrUpdateRole(r Role) (role Role, created bool, err error) {
|
|
||||||
_, err = s.GetRole(r.Role)
|
|
||||||
if err == nil {
|
|
||||||
role, err = s.UpdateRole(r)
|
|
||||||
created = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return r, true, s.CreateRole(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Store) CreateRole(role Role) error {
|
func (s *Store) CreateRole(role Role) error {
|
||||||
if role.Role == RootRoleName {
|
if role.Role == RootRoleName {
|
||||||
return authErr(http.StatusForbidden, "Cannot modify role %s: is root role.", role.Role)
|
return authErr(http.StatusForbidden, "Cannot modify role %s: is root role.", role.Role)
|
||||||
|
@ -211,17 +211,32 @@ func (sh *authHandler) forRole(w http.ResponseWriter, r *http.Request, role stri
|
|||||||
writeError(w, httptypes.NewHTTPError(http.StatusBadRequest, "Role JSON name does not match the name in the URL"))
|
writeError(w, httptypes.NewHTTPError(http.StatusBadRequest, "Role JSON name does not match the name in the URL"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
newrole, created, err := sh.sec.CreateOrUpdateRole(in)
|
|
||||||
|
var out auth.Role
|
||||||
|
|
||||||
|
// create
|
||||||
|
if in.Grant.IsEmpty() && in.Revoke.IsEmpty() {
|
||||||
|
err = sh.sec.CreateRole(in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError(w, err)
|
writeError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if created {
|
|
||||||
w.WriteHeader(http.StatusCreated)
|
w.WriteHeader(http.StatusCreated)
|
||||||
|
out = in
|
||||||
} else {
|
} else {
|
||||||
|
if !in.Permissions.IsEmpty() {
|
||||||
|
writeError(w, httptypes.NewHTTPError(http.StatusBadRequest, "Role JSON contains both permissions and grant/revoke"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
out, err = sh.sec.UpdateRole(in)
|
||||||
|
if err != nil {
|
||||||
|
writeError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
}
|
}
|
||||||
err = json.NewEncoder(w).Encode(newrole)
|
|
||||||
|
err = json.NewEncoder(w).Encode(out)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
plog.Warningf("forRole error encoding on %s", r.URL)
|
plog.Warningf("forRole error encoding on %s", r.URL)
|
||||||
return
|
return
|
||||||
|
Reference in New Issue
Block a user