1
1
package coderd
2
2
3
3
import (
4
+ "context"
5
+ "fmt"
4
6
"net/http"
5
7
6
8
"github.com/google/uuid"
@@ -12,6 +14,100 @@ import (
12
14
"github.com/coder/coder/v2/codersdk"
13
15
)
14
16
17
+ type enterpriseCustomRoleHandler struct {
18
+ Enabled bool
19
+ }
20
+
21
+ func (h enterpriseCustomRoleHandler ) PatchOrganizationRole (ctx context.Context , db database.Store , rw http.ResponseWriter , orgID uuid.UUID , role codersdk.Role ) (codersdk.Role , bool ) {
22
+ if ! h .Enabled {
23
+ httpapi .Write (ctx , rw , http .StatusForbidden , codersdk.Response {
24
+ Message : "Custom roles is not enabled" ,
25
+ })
26
+ return codersdk.Role {}, false
27
+ }
28
+
29
+ // Only organization permissions are allowed to be granted
30
+ if len (role .SitePermissions ) > 0 {
31
+ httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
32
+ Message : "Invalid request, not allowed to assign site wide permissions for an organization role." ,
33
+ Detail : "organization scoped roles may not contain site wide permissions" ,
34
+ })
35
+ return codersdk.Role {}, false
36
+ }
37
+
38
+ if len (role .UserPermissions ) > 0 {
39
+ httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
40
+ Message : "Invalid request, not allowed to assign user permissions for an organization role." ,
41
+ Detail : "organization scoped roles may not contain user permissions" ,
42
+ })
43
+ return codersdk.Role {}, false
44
+ }
45
+
46
+ if len (role .OrganizationPermissions ) > 1 {
47
+ httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
48
+ Message : "Invalid request, Only 1 organization can be assigned permissions" ,
49
+ Detail : "roles can only contain 1 organization" ,
50
+ })
51
+ return codersdk.Role {}, false
52
+ }
53
+
54
+ if len (role .OrganizationPermissions ) == 1 {
55
+ _ , exists := role .OrganizationPermissions [orgID .String ()]
56
+ if ! exists {
57
+ httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
58
+ Message : fmt .Sprintf ("Invalid request, expected permissions for only the organization %q" , orgID .String ()),
59
+ Detail : fmt .Sprintf ("only org id %s allowed" , orgID .String ()),
60
+ })
61
+ return codersdk.Role {}, false
62
+ }
63
+ }
64
+
65
+ // Make sure all permissions inputted are valid according to our policy.
66
+ rbacRole := db2sdk .RoleToRBAC (role )
67
+ args , err := rolestore .ConvertRoleToDB (rbacRole )
68
+ if err != nil {
69
+ httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
70
+ Message : "Invalid request" ,
71
+ Detail : err .Error (),
72
+ })
73
+ return codersdk.Role {}, false
74
+ }
75
+
76
+ inserted , err := db .UpsertCustomRole (ctx , database.UpsertCustomRoleParams {
77
+ Name : args .Name ,
78
+ DisplayName : args .DisplayName ,
79
+ OrganizationID : uuid.NullUUID {
80
+ UUID : orgID ,
81
+ Valid : true ,
82
+ },
83
+ SitePermissions : args .SitePermissions ,
84
+ OrgPermissions : args .OrgPermissions ,
85
+ UserPermissions : args .UserPermissions ,
86
+ })
87
+ if httpapi .Is404Error (err ) {
88
+ httpapi .ResourceNotFound (rw )
89
+ return codersdk.Role {}, false
90
+ }
91
+ if err != nil {
92
+ httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
93
+ Message : "Failed to update role permissions" ,
94
+ Detail : err .Error (),
95
+ })
96
+ return codersdk.Role {}, false
97
+ }
98
+
99
+ convertedInsert , err := rolestore .ConvertDBRole (inserted )
100
+ if err != nil {
101
+ httpapi .Write (ctx , rw , http .StatusInternalServerError , codersdk.Response {
102
+ Message : "Permissions were updated, unable to read them back out of the database." ,
103
+ Detail : err .Error (),
104
+ })
105
+ return codersdk.Role {}, false
106
+ }
107
+
108
+ return db2sdk .Role (convertedInsert ), true
109
+ }
110
+
15
111
// patchRole will allow creating a custom role
16
112
//
17
113
// @Summary Upsert a custom site-wide role
@@ -61,7 +157,6 @@ func (api *API) patchRole(rw http.ResponseWriter, r *http.Request) {
61
157
inserted , err := api .Database .UpsertCustomRole (ctx , database.UpsertCustomRoleParams {
62
158
Name : args .Name ,
63
159
DisplayName : args .DisplayName ,
64
- OrganizationID : uuid.NullUUID {},
65
160
SitePermissions : args .SitePermissions ,
66
161
OrgPermissions : args .OrgPermissions ,
67
162
UserPermissions : args .UserPermissions ,
0 commit comments