Browse Source

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).
Hitoshi Mitake 9 years ago
parent
commit
60fc1e4d4e
3 changed files with 50 additions and 25 deletions
  1. 22 7
      auth/store.go
  2. 24 18
      etcdserver/api/v3rpc/rpctypes/error.go
  3. 4 0
      etcdserver/api/v3rpc/util.go

+ 22 - 7
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

+ 24 - 18
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)

+ 4 - 0
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())
 	}