From 60fc1e4d4ec02052b4aa17763f6c660da2f5a267 Mon Sep 17 00:00:00 2001 From: Hitoshi Mitake Date: Sun, 5 Jun 2016 16:41:10 +0900 Subject: [PATCH] auth, etcdserver: error codes for revoking non existing role and permission This commit adds error codes for representing revoking non existing role (from user) and permission (from role). --- auth/store.go | 29 +++++++++++++----- etcdserver/api/v3rpc/rpctypes/error.go | 42 +++++++++++++++----------- etcdserver/api/v3rpc/util.go | 4 +++ 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/auth/store.go b/auth/store.go index 59fa485ef..e674bec89 100644 --- a/auth/store.go +++ b/auth/store.go @@ -37,12 +37,14 @@ var ( plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "auth") - ErrUserAlreadyExist = errors.New("auth: user already exists") - ErrUserNotFound = errors.New("auth: user not found") - ErrRoleAlreadyExist = errors.New("auth: role already exists") - ErrRoleNotFound = errors.New("auth: role not found") - ErrAuthFailed = errors.New("auth: authentication failed, invalid user ID or password") - ErrPermissionDenied = errors.New("auth: permission denied") + ErrUserAlreadyExist = errors.New("auth: user already exists") + ErrUserNotFound = errors.New("auth: user not found") + ErrRoleAlreadyExist = errors.New("auth: role already exists") + ErrRoleNotFound = errors.New("auth: role not found") + ErrAuthFailed = errors.New("auth: authentication failed, invalid user ID or password") + ErrPermissionDenied = errors.New("auth: permission denied") + ErrRoleNotGranted = errors.New("auth: role is not granted to the user") + ErrPermissionNotGranted = errors.New("auth: permission is not granted to the role") ) type AuthStore interface { @@ -353,13 +355,19 @@ func (as *authStore) UserRevoke(r *pb.AuthUserRevokeRequest) (*pb.AuthUserRevoke updatedUser.Name = user.Name updatedUser.Password = user.Password - // TODO(mitake): return error if the target role doesn't exist in the granted roles of the user + revoked := false for _, role := range user.Roles { if strings.Compare(role, r.Role) != 0 { updatedUser.Roles = append(updatedUser.Roles, role) + } else { + revoked = true } } + if !revoked { + return nil, ErrRoleNotGranted + } + marshaledUser, merr := updatedUser.Marshal() if merr != nil { return nil, merr @@ -414,12 +422,19 @@ func (as *authStore) RoleRevoke(r *pb.AuthRoleRevokeRequest) (*pb.AuthRoleRevoke updatedRole := &authpb.Role{} updatedRole.Name = role.Name + revoked := false for _, perm := range role.KeyPermission { if !bytes.Equal(perm.Key, []byte(r.Key)) { updatedRole.KeyPermission = append(updatedRole.KeyPermission, perm) + } else { + revoked = true } } + if !revoked { + return nil, ErrPermissionNotGranted + } + marshaledRole, merr := updatedRole.Marshal() if merr != nil { return nil, merr diff --git a/etcdserver/api/v3rpc/rpctypes/error.go b/etcdserver/api/v3rpc/rpctypes/error.go index 3868eff26..1c53c0753 100644 --- a/etcdserver/api/v3rpc/rpctypes/error.go +++ b/etcdserver/api/v3rpc/rpctypes/error.go @@ -38,12 +38,14 @@ var ( ErrGRPCRequestTooLarge = grpc.Errorf(codes.InvalidArgument, "etcdserver: request is too large") - ErrGRPCUserAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name already exists") - ErrGRPCUserNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name not found") - ErrGRPCRoleAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role name already exists") - ErrGRPCRoleNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role name not found") - ErrGRPCAuthFailed = grpc.Errorf(codes.InvalidArgument, "etcdserver: authentication failed, invalid user ID or password") - ErrGRPCPermissionDenied = grpc.Errorf(codes.FailedPrecondition, "etcdserver: permission denied") + ErrGRPCUserAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name already exists") + ErrGRPCUserNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name not found") + ErrGRPCRoleAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role name already exists") + ErrGRPCRoleNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role name not found") + ErrGRPCAuthFailed = grpc.Errorf(codes.InvalidArgument, "etcdserver: authentication failed, invalid user ID or password") + ErrGRPCPermissionDenied = grpc.Errorf(codes.FailedPrecondition, "etcdserver: permission denied") + ErrGRPCRoleNotGranted = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role is not granted to the user") + ErrGRPCPermissionNotGranted = grpc.Errorf(codes.FailedPrecondition, "etcdserver: permission is not granted to the role") ErrGRPCNoLeader = grpc.Errorf(codes.Unavailable, "etcdserver: no leader") ErrGRPCNotCapable = grpc.Errorf(codes.Unavailable, "etcdserver: not capable") @@ -66,12 +68,14 @@ var ( grpc.ErrorDesc(ErrGRPCRequestTooLarge): ErrGRPCRequestTooLarge, - grpc.ErrorDesc(ErrGRPCUserAlreadyExist): ErrGRPCUserAlreadyExist, - grpc.ErrorDesc(ErrGRPCUserNotFound): ErrGRPCUserNotFound, - grpc.ErrorDesc(ErrGRPCRoleAlreadyExist): ErrGRPCRoleAlreadyExist, - grpc.ErrorDesc(ErrGRPCRoleNotFound): ErrGRPCRoleNotFound, - grpc.ErrorDesc(ErrGRPCAuthFailed): ErrGRPCAuthFailed, - grpc.ErrorDesc(ErrGRPCPermissionDenied): ErrGRPCPermissionDenied, + grpc.ErrorDesc(ErrGRPCUserAlreadyExist): ErrGRPCUserAlreadyExist, + grpc.ErrorDesc(ErrGRPCUserNotFound): ErrGRPCUserNotFound, + grpc.ErrorDesc(ErrGRPCRoleAlreadyExist): ErrGRPCRoleAlreadyExist, + grpc.ErrorDesc(ErrGRPCRoleNotFound): ErrGRPCRoleNotFound, + grpc.ErrorDesc(ErrGRPCAuthFailed): ErrGRPCAuthFailed, + grpc.ErrorDesc(ErrGRPCPermissionDenied): ErrGRPCPermissionDenied, + grpc.ErrorDesc(ErrGRPCRoleNotGranted): ErrGRPCRoleNotGranted, + grpc.ErrorDesc(ErrGRPCPermissionNotGranted): ErrGRPCPermissionNotGranted, grpc.ErrorDesc(ErrGRPCNoLeader): ErrGRPCNoLeader, grpc.ErrorDesc(ErrGRPCNotCapable): ErrGRPCNotCapable, @@ -95,12 +99,14 @@ var ( ErrRequestTooLarge = Error(ErrGRPCRequestTooLarge) - ErrUserAlreadyExist = Error(ErrGRPCUserAlreadyExist) - ErrUserNotFound = Error(ErrGRPCUserNotFound) - ErrRoleAlreadyExist = Error(ErrGRPCRoleAlreadyExist) - ErrRoleNotFound = Error(ErrGRPCRoleNotFound) - ErrAuthFailed = Error(ErrGRPCAuthFailed) - ErrPermissionDenied = Error(ErrGRPCPermissionDenied) + ErrUserAlreadyExist = Error(ErrGRPCUserAlreadyExist) + ErrUserNotFound = Error(ErrGRPCUserNotFound) + ErrRoleAlreadyExist = Error(ErrGRPCRoleAlreadyExist) + ErrRoleNotFound = Error(ErrGRPCRoleNotFound) + ErrAuthFailed = Error(ErrGRPCAuthFailed) + ErrPermissionDenied = Error(ErrGRPCPermissionDenied) + ErrRoleNotGranted = Error(ErrGRPCRoleNotGranted) + ErrPermissionNotGranted = Error(ErrGRPCPermissionNotGranted) ErrNoLeader = Error(ErrGRPCNoLeader) ErrNotCapable = Error(ErrGRPCNotCapable) diff --git a/etcdserver/api/v3rpc/util.go b/etcdserver/api/v3rpc/util.go index 8d5bda6a0..33afe1d85 100644 --- a/etcdserver/api/v3rpc/util.go +++ b/etcdserver/api/v3rpc/util.go @@ -49,6 +49,10 @@ func togRPCError(err error) error { return rpctypes.ErrGRPCAuthFailed case auth.ErrPermissionDenied: return rpctypes.ErrGRPCPermissionDenied + case auth.ErrRoleNotGranted: + return rpctypes.ErrGRPCRoleNotGranted + case auth.ErrPermissionNotGranted: + return rpctypes.ErrGRPCPermissionNotGranted default: return grpc.Errorf(codes.Internal, err.Error()) }