@ -37,7 +37,7 @@ func (s *APIV1Service) ListUsers(ctx context.Context, request *v1pb.ListUsersReq
if currentUser == nil {
if currentUser == nil {
return nil , status . Errorf ( codes . Unauthenticated , "user not authenticated" )
return nil , status . Errorf ( codes . Unauthenticated , "user not authenticated" )
}
}
if currentUser . Role != store . Role Host && currentUser . Role != store . Role Admin {
if currentUser . Role != store . Role Admin {
return nil , status . Errorf ( codes . PermissionDenied , "permission denied" )
return nil , status . Errorf ( codes . PermissionDenied , "permission denied" )
}
}
@ -132,17 +132,17 @@ func (s *APIV1Service) CreateUser(ctx context.Context, request *v1pb.CreateUserR
// Determine the role to assign
// Determine the role to assign
var roleToAssign store . Role
var roleToAssign store . Role
if isFirstUser {
if isFirstUser {
// First-time setup: create the first user as HOST (no authentication required)
// First-time setup: create the first user as ADMIN (no authentication required)
roleToAssign = store . Role Host
roleToAssign = store . Role Admin
} else if currentUser != nil && currentUser . Role == store . Role Host {
} else if currentUser != nil && currentUser . Role == store . Role Admin {
// Authenticated HOST user can create users with any role specified in request
// Authenticated ADMIN user can create users with any role specified in request
if request . User . Role != v1pb . User_ROLE_UNSPECIFIED {
if request . User . Role != v1pb . User_ROLE_UNSPECIFIED {
roleToAssign = convertUserRoleToStore ( request . User . Role )
roleToAssign = convertUserRoleToStore ( request . User . Role )
} else {
} else {
roleToAssign = store . RoleUser
roleToAssign = store . RoleUser
}
}
} else {
} else {
// Unauthenticated or non- HOST users can only create normal users
// Unauthenticated or non- ADMIN users can only create normal users
roleToAssign = store . RoleUser
roleToAssign = store . RoleUser
}
}
@ -197,7 +197,7 @@ func (s *APIV1Service) UpdateUser(ctx context.Context, request *v1pb.UpdateUserR
}
}
// Check permission.
// Check permission.
// Only allow admin or self to update user.
// Only allow admin or self to update user.
if currentUser . ID != userID && currentUser . Role != store . RoleAdmin && currentUser . Role != store . RoleHost {
if currentUser . ID != userID && currentUser . Role != store . RoleAdmin {
return nil , status . Errorf ( codes . PermissionDenied , "permission denied" )
return nil , status . Errorf ( codes . PermissionDenied , "permission denied" )
}
}
@ -264,7 +264,7 @@ func (s *APIV1Service) UpdateUser(ctx context.Context, request *v1pb.UpdateUserR
update . Description = & request . User . Description
update . Description = & request . User . Description
case "role" :
case "role" :
// Only allow admin to update role.
// Only allow admin to update role.
if currentUser . Role != store . RoleAdmin && currentUser . Role != store . RoleHost {
if currentUser . Role != store . RoleAdmin {
return nil , status . Errorf ( codes . PermissionDenied , "permission denied" )
return nil , status . Errorf ( codes . PermissionDenied , "permission denied" )
}
}
role := convertUserRoleToStore ( request . User . Role )
role := convertUserRoleToStore ( request . User . Role )
@ -301,7 +301,7 @@ func (s *APIV1Service) DeleteUser(ctx context.Context, request *v1pb.DeleteUserR
if err != nil {
if err != nil {
return nil , status . Errorf ( codes . Internal , "failed to get user: %v" , err )
return nil , status . Errorf ( codes . Internal , "failed to get user: %v" , err )
}
}
if currentUser . ID != userID && currentUser . Role != store . RoleAdmin && currentUser . Role != store . RoleHost {
if currentUser . ID != userID && currentUser . Role != store . RoleAdmin {
return nil , status . Errorf ( codes . PermissionDenied , "permission denied" )
return nil , status . Errorf ( codes . PermissionDenied , "permission denied" )
}
}
@ -542,7 +542,7 @@ func (s *APIV1Service) ListPersonalAccessTokens(ctx context.Context, request *v1
claims := auth . GetUserClaims ( ctx )
claims := auth . GetUserClaims ( ctx )
if claims == nil || claims . UserID != userID {
if claims == nil || claims . UserID != userID {
currentUser , _ := s . fetchCurrentUser ( ctx )
currentUser , _ := s . fetchCurrentUser ( ctx )
if currentUser == nil || ( currentUser . ID != userID && currentUser . Role != store . Role Host && currentUser . Role != store . Role Admin) {
if currentUser == nil || ( currentUser . ID != userID && currentUser . Role != store . Role Admin) {
return nil , status . Errorf ( codes . PermissionDenied , "permission denied" )
return nil , status . Errorf ( codes . PermissionDenied , "permission denied" )
}
}
}
}
@ -689,7 +689,7 @@ func (s *APIV1Service) ListUserWebhooks(ctx context.Context, request *v1pb.ListU
if currentUser == nil {
if currentUser == nil {
return nil , status . Errorf ( codes . Unauthenticated , "user not authenticated" )
return nil , status . Errorf ( codes . Unauthenticated , "user not authenticated" )
}
}
if currentUser . ID != userID && currentUser . Role != store . Role Host && currentUser . Role != store . Role Admin {
if currentUser . ID != userID && currentUser . Role != store . Role Admin {
return nil , status . Errorf ( codes . PermissionDenied , "permission denied" )
return nil , status . Errorf ( codes . PermissionDenied , "permission denied" )
}
}
@ -721,7 +721,7 @@ func (s *APIV1Service) CreateUserWebhook(ctx context.Context, request *v1pb.Crea
if currentUser == nil {
if currentUser == nil {
return nil , status . Errorf ( codes . Unauthenticated , "user not authenticated" )
return nil , status . Errorf ( codes . Unauthenticated , "user not authenticated" )
}
}
if currentUser . ID != userID && currentUser . Role != store . Role Host && currentUser . Role != store . Role Admin {
if currentUser . ID != userID && currentUser . Role != store . Role Admin {
return nil , status . Errorf ( codes . PermissionDenied , "permission denied" )
return nil , status . Errorf ( codes . PermissionDenied , "permission denied" )
}
}
@ -761,7 +761,7 @@ func (s *APIV1Service) UpdateUserWebhook(ctx context.Context, request *v1pb.Upda
if currentUser == nil {
if currentUser == nil {
return nil , status . Errorf ( codes . Unauthenticated , "user not authenticated" )
return nil , status . Errorf ( codes . Unauthenticated , "user not authenticated" )
}
}
if currentUser . ID != userID && currentUser . Role != store . Role Host && currentUser . Role != store . Role Admin {
if currentUser . ID != userID && currentUser . Role != store . Role Admin {
return nil , status . Errorf ( codes . PermissionDenied , "permission denied" )
return nil , status . Errorf ( codes . PermissionDenied , "permission denied" )
}
}
@ -833,7 +833,7 @@ func (s *APIV1Service) DeleteUserWebhook(ctx context.Context, request *v1pb.Dele
if currentUser == nil {
if currentUser == nil {
return nil , status . Errorf ( codes . Unauthenticated , "user not authenticated" )
return nil , status . Errorf ( codes . Unauthenticated , "user not authenticated" )
}
}
if currentUser . ID != userID && currentUser . Role != store . Role Host && currentUser . Role != store . Role Admin {
if currentUser . ID != userID && currentUser . Role != store . Role Admin {
return nil , status . Errorf ( codes . PermissionDenied , "permission denied" )
return nil , status . Errorf ( codes . PermissionDenied , "permission denied" )
}
}
@ -928,8 +928,6 @@ func convertUserFromStore(user *store.User) *v1pb.User {
func convertUserRoleFromStore ( role store . Role ) v1pb . User_Role {
func convertUserRoleFromStore ( role store . Role ) v1pb . User_Role {
switch role {
switch role {
case store . RoleHost :
return v1pb . User_HOST
case store . RoleAdmin :
case store . RoleAdmin :
return v1pb . User_ADMIN
return v1pb . User_ADMIN
case store . RoleUser :
case store . RoleUser :
@ -941,8 +939,6 @@ func convertUserRoleFromStore(role store.Role) v1pb.User_Role {
func convertUserRoleToStore ( role v1pb . User_Role ) store . Role {
func convertUserRoleToStore ( role v1pb . User_Role ) store . Role {
switch role {
switch role {
case v1pb . User_HOST :
return store . RoleHost
case v1pb . User_ADMIN :
case v1pb . User_ADMIN :
return store . RoleAdmin
return store . RoleAdmin
default :
default :