CreateRole creates a new role.
(ctx context.Context, req *connect.Request[v1pb.CreateRoleRequest])
| 73 | |
| 74 | // CreateRole creates a new role. |
| 75 | func (s *RoleService) CreateRole(ctx context.Context, req *connect.Request[v1pb.CreateRoleRequest]) (*connect.Response[v1pb.Role], error) { |
| 76 | workspaceID := common.GetWorkspaceIDFromContext(ctx) |
| 77 | if err := s.licenseService.IsFeatureEnabled(ctx, workspaceID, v1pb.PlanFeature_FEATURE_CUSTOM_ROLES); err != nil { |
| 78 | return nil, connect.NewError(connect.CodePermissionDenied, err) |
| 79 | } |
| 80 | |
| 81 | if predefinedRole := s.getBuildinRole(req.Msg.RoleId); predefinedRole != nil { |
| 82 | return nil, connect.NewError(connect.CodeInvalidArgument, errors.Errorf("role %s is a built-in role", req.Msg.RoleId)) |
| 83 | } |
| 84 | |
| 85 | if err := validateResourceID(req.Msg.RoleId); err != nil { |
| 86 | return nil, err |
| 87 | } |
| 88 | |
| 89 | permissions := make(map[permission.Permission]bool) |
| 90 | for _, v := range req.Msg.GetRole().GetPermissions() { |
| 91 | permissions[permission.Permission(v)] = true |
| 92 | } |
| 93 | create := &store.RoleMessage{ |
| 94 | Workspace: workspaceID, |
| 95 | ResourceID: req.Msg.RoleId, |
| 96 | Name: req.Msg.Role.Title, |
| 97 | Description: req.Msg.Role.Description, |
| 98 | Permissions: permissions, |
| 99 | } |
| 100 | if ok := permission.Exists(req.Msg.Role.Permissions...); !ok { |
| 101 | invalidPerms := []string{} |
| 102 | for _, p := range req.Msg.Role.Permissions { |
| 103 | if !permission.Exist(p) { |
| 104 | invalidPerms = append(invalidPerms, p) |
| 105 | } |
| 106 | } |
| 107 | return nil, connect.NewError(connect.CodeInvalidArgument, errors.Errorf("invalid permissions: %v", invalidPerms)) |
| 108 | } |
| 109 | roleMessage, err := s.store.CreateRole(ctx, create) |
| 110 | if err != nil { |
| 111 | if strings.Contains(err.Error(), "duplicate key") { |
| 112 | return nil, connect.NewError(connect.CodeAlreadyExists, errors.Errorf("role ID %q already exists", req.Msg.RoleId)) |
| 113 | } |
| 114 | return nil, connect.NewError(connect.CodeInternal, errors.Wrap(err, "failed to create role")) |
| 115 | } |
| 116 | if err := s.iamManager.ReloadCache(ctx); err != nil { |
| 117 | return nil, err |
| 118 | } |
| 119 | return connect.NewResponse(convertToRole(roleMessage)), nil |
| 120 | } |
| 121 | |
| 122 | // UpdateRole updates an existing role. |
| 123 | func (s *RoleService) UpdateRole(ctx context.Context, req *connect.Request[v1pb.UpdateRoleRequest]) (*connect.Response[v1pb.Role], error) { |
no test coverage detected