1
1
package coderd
2
2
3
3
import (
4
- "context"
5
4
"fmt"
6
5
"net/http"
7
6
@@ -11,117 +10,123 @@ import (
11
10
"github.com/coder/coder/v2/coderd/database"
12
11
"github.com/coder/coder/v2/coderd/database/db2sdk"
13
12
"github.com/coder/coder/v2/coderd/httpapi"
13
+ "github.com/coder/coder/v2/coderd/httpmw"
14
14
"github.com/coder/coder/v2/coderd/rbac"
15
15
"github.com/coder/coder/v2/coderd/rbac/policy"
16
16
"github.com/coder/coder/v2/codersdk"
17
17
)
18
18
19
- type enterpriseCustomRoleHandler struct {
20
- API * API
21
- Enabled bool
22
- }
23
-
24
- func (h enterpriseCustomRoleHandler ) PatchOrganizationRole (ctx context.Context , rw http.ResponseWriter , r * http.Request , orgID uuid.UUID , role codersdk.PatchRoleRequest ) (codersdk.Role , bool ) {
25
- if ! h .Enabled {
26
- httpapi .Write (ctx , rw , http .StatusForbidden , codersdk.Response {
27
- Message : "Custom roles are not enabled" ,
28
- })
29
- return codersdk.Role {}, false
30
- }
31
-
19
+ // patchRole will allow creating a custom organization role
20
+ //
21
+ // @Summary Upsert a custom organization role
22
+ // @ID upsert-a-custom-organization-role
23
+ // @Security CoderSessionToken
24
+ // @Produce json
25
+ // @Param organization path string true "Organization ID" format(uuid)
26
+ // @Tags Members
27
+ // @Success 200 {array} codersdk.Role
28
+ // @Router /organizations/{organization}/members/roles [patch]
29
+ func (api * API ) patchOrgRoles (rw http.ResponseWriter , r * http.Request ) {
32
30
var (
33
- db = h .API .Database
34
- auditor = h .API .AGPL .Auditor .Load ()
31
+ ctx = r .Context ()
32
+ db = api .Database
33
+ auditor = api .AGPL .Auditor .Load ()
34
+ organization = httpmw .OrganizationParam (r )
35
35
aReq , commitAudit = audit .InitRequest [database.CustomRole ](rw , & audit.RequestParams {
36
36
Audit : * auditor ,
37
- Log : h . API .Logger ,
37
+ Log : api .Logger ,
38
38
Request : r ,
39
39
Action : database .AuditActionWrite ,
40
- OrganizationID : orgID ,
40
+ OrganizationID : organization . ID ,
41
41
})
42
42
)
43
43
defer commitAudit ()
44
44
45
+ var req codersdk.Role
46
+ if ! httpapi .Read (ctx , rw , r , & req ) {
47
+ return
48
+ }
49
+
45
50
// This check is not ideal, but we cannot enforce a unique role name in the db against
46
51
// the built-in role names.
47
- if rbac .ReservedRoleName (role .Name ) {
52
+ if rbac .ReservedRoleName (req .Name ) {
48
53
httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
49
54
Message : "Reserved role name" ,
50
- Detail : fmt .Sprintf ("%q is a reserved role name, and not allowed to be used" , role .Name ),
55
+ Detail : fmt .Sprintf ("%q is a reserved role name, and not allowed to be used" , req .Name ),
51
56
})
52
- return codersdk. Role {}, false
57
+ return
53
58
}
54
59
55
- if err := httpapi .NameValid (role .Name ); err != nil {
60
+ if err := httpapi .NameValid (req .Name ); err != nil {
56
61
httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
57
62
Message : "Invalid role name" ,
58
63
Detail : err .Error (),
59
64
})
60
- return codersdk. Role {}, false
65
+ return
61
66
}
62
67
63
68
// Only organization permissions are allowed to be granted
64
- if len (role .SitePermissions ) > 0 {
69
+ if len (req .SitePermissions ) > 0 {
65
70
httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
66
71
Message : "Invalid request, not allowed to assign site wide permissions for an organization role." ,
67
72
Detail : "organization scoped roles may not contain site wide permissions" ,
68
73
})
69
- return codersdk. Role {}, false
74
+ return
70
75
}
71
76
72
- if len (role .UserPermissions ) > 0 {
77
+ if len (req .UserPermissions ) > 0 {
73
78
httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
74
79
Message : "Invalid request, not allowed to assign user permissions for an organization role." ,
75
80
Detail : "organization scoped roles may not contain user permissions" ,
76
81
})
77
- return codersdk. Role {}, false
82
+ return
78
83
}
79
84
80
85
originalRoles , err := db .CustomRoles (ctx , database.CustomRolesParams {
81
86
LookupRoles : []database.NameOrganizationPair {
82
87
{
83
- Name : role .Name ,
84
- OrganizationID : orgID ,
88
+ Name : req .Name ,
89
+ OrganizationID : organization . ID ,
85
90
},
86
91
},
87
92
ExcludeOrgRoles : false ,
88
- OrganizationID : orgID ,
93
+ OrganizationID : organization . ID ,
89
94
})
90
95
// If it is a 404 (not found) error, ignore it.
91
96
if err != nil && ! httpapi .Is404Error (err ) {
92
97
httpapi .InternalServerError (rw , err )
93
- return codersdk. Role {}, false
98
+ return
94
99
}
95
100
if len (originalRoles ) == 1 {
96
101
// For auditing changes to a role.
97
102
aReq .Old = originalRoles [0 ]
98
103
}
99
104
100
105
inserted , err := db .UpsertCustomRole (ctx , database.UpsertCustomRoleParams {
101
- Name : role .Name ,
102
- DisplayName : role .DisplayName ,
106
+ Name : req .Name ,
107
+ DisplayName : req .DisplayName ,
103
108
OrganizationID : uuid.NullUUID {
104
- UUID : orgID ,
109
+ UUID : organization . ID ,
105
110
Valid : true ,
106
111
},
107
- SitePermissions : db2sdk .List (role .SitePermissions , sdkPermissionToDB ),
108
- OrgPermissions : db2sdk .List (role .OrganizationPermissions , sdkPermissionToDB ),
109
- UserPermissions : db2sdk .List (role .UserPermissions , sdkPermissionToDB ),
112
+ SitePermissions : db2sdk .List (req .SitePermissions , sdkPermissionToDB ),
113
+ OrgPermissions : db2sdk .List (req .OrganizationPermissions , sdkPermissionToDB ),
114
+ UserPermissions : db2sdk .List (req .UserPermissions , sdkPermissionToDB ),
110
115
})
111
116
if httpapi .Is404Error (err ) {
112
117
httpapi .ResourceNotFound (rw )
113
- return codersdk. Role {}, false
118
+ return
114
119
}
115
120
if err != nil {
116
121
httpapi .Write (ctx , rw , http .StatusBadRequest , codersdk.Response {
117
122
Message : "Failed to update role permissions" ,
118
123
Detail : err .Error (),
119
124
})
120
- return codersdk. Role {}, false
125
+ return
121
126
}
122
127
aReq .New = inserted
123
128
124
- return db2sdk .Role (inserted ), true
129
+ httpapi . Write ( ctx , rw , http . StatusOK , db2sdk .Role (inserted ))
125
130
}
126
131
127
132
func sdkPermissionToDB (p codersdk.Permission ) database.CustomRolePermission {
0 commit comments