@@ -56,6 +56,12 @@ func setScimAuth(key []byte) func(*http.Request) {
56
56
}
57
57
}
58
58
59
+ func setScimAuthBearer (key []byte )func (* http.Request ) {
60
+ return func (r * http.Request ) {
61
+ r .Header .Set ("Authorization" ,"Bearer " + string (key ))
62
+ }
63
+ }
64
+
59
65
//nolint:gocritic // SCIM authenticates via a special header and bypasses internal RBAC.
60
66
func TestScim (t * testing.T ) {
61
67
t .Parallel ()
@@ -163,6 +169,62 @@ func TestScim(t *testing.T) {
163
169
require .Empty (t ,notifyEnq .Sent )
164
170
})
165
171
172
+ t .Run ("OK_Bearer" ,func (t * testing.T ) {
173
+ t .Parallel ()
174
+
175
+ ctx ,cancel := context .WithTimeout (context .Background (),testutil .WaitLong )
176
+ defer cancel ()
177
+
178
+ // given
179
+ scimAPIKey := []byte ("hi" )
180
+ mockAudit := audit .NewMock ()
181
+ notifyEnq := & testutil.FakeNotificationsEnqueuer {}
182
+ client ,_ := coderdenttest .New (t ,& coderdenttest.Options {
183
+ Options :& coderdtest.Options {
184
+ Auditor :mockAudit ,
185
+ NotificationsEnqueuer :notifyEnq ,
186
+ },
187
+ SCIMAPIKey :scimAPIKey ,
188
+ AuditLogging :true ,
189
+ LicenseOptions :& coderdenttest.LicenseOptions {
190
+ AccountID :"coolin" ,
191
+ Features : license.Features {
192
+ codersdk .FeatureSCIM :1 ,
193
+ codersdk .FeatureAuditLog :1 ,
194
+ },
195
+ },
196
+ })
197
+ mockAudit .ResetLogs ()
198
+
199
+ // when
200
+ sUser := makeScimUser (t )
201
+ res ,err := client .Request (ctx ,"POST" ,"/scim/v2/Users" ,sUser ,setScimAuthBearer (scimAPIKey ))
202
+ require .NoError (t ,err )
203
+ defer res .Body .Close ()
204
+ require .Equal (t ,http .StatusOK ,res .StatusCode )
205
+
206
+ // then
207
+ // Expect audit logs
208
+ aLogs := mockAudit .AuditLogs ()
209
+ require .Len (t ,aLogs ,1 )
210
+ af := map [string ]string {}
211
+ err = json .Unmarshal ([]byte (aLogs [0 ].AdditionalFields ),& af )
212
+ require .NoError (t ,err )
213
+ assert .Equal (t ,coderd .SCIMAuditAdditionalFields ,af )
214
+ assert .Equal (t ,database .AuditActionCreate ,aLogs [0 ].Action )
215
+
216
+ // Expect users exposed over API
217
+ userRes ,err := client .Users (ctx , codersdk.UsersRequest {Search :sUser .Emails [0 ].Value })
218
+ require .NoError (t ,err )
219
+ require .Len (t ,userRes .Users ,1 )
220
+ assert .Equal (t ,sUser .Emails [0 ].Value ,userRes .Users [0 ].Email )
221
+ assert .Equal (t ,sUser .UserName ,userRes .Users [0 ].Username )
222
+ assert .Len (t ,userRes .Users [0 ].OrganizationIDs ,1 )
223
+
224
+ // Expect zero notifications (SkipNotifications = true)
225
+ require .Empty (t ,notifyEnq .Sent )
226
+ })
227
+
166
228
t .Run ("OKNoDefault" ,func (t * testing.T ) {
167
229
t .Parallel ()
168
230