mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: implement SCIM handler for SCIM 2.0 compliance (#25572)
Rewrites the SCIM 2.0 user provisioning handler to be RFC 7644 compliant. Verified against an external IdP Okta. Behavior is OPT IN
This commit is contained in:
+11
-34
@@ -622,40 +622,12 @@ func New(ctx context.Context, options *Options) (_ *API, err error) {
|
||||
})
|
||||
})
|
||||
|
||||
if len(options.SCIMAPIKey) != 0 {
|
||||
api.AGPL.RootHandler.Route("/scim/v2", func(r chi.Router) {
|
||||
r.Use(
|
||||
api.RequireFeatureMW(codersdk.FeatureSCIM),
|
||||
)
|
||||
r.Get("/ServiceProviderConfig", api.scimServiceProviderConfig)
|
||||
r.Post("/Users", api.scimPostUser)
|
||||
r.Route("/Users", func(r chi.Router) {
|
||||
r.Get("/", api.scimGetUsers)
|
||||
r.Post("/", api.scimPostUser)
|
||||
r.Get("/{id}", api.scimGetUser)
|
||||
r.Patch("/{id}", api.scimPatchUser)
|
||||
r.Put("/{id}", api.scimPutUser)
|
||||
})
|
||||
r.NotFound(func(w http.ResponseWriter, r *http.Request) {
|
||||
u := r.URL.String()
|
||||
httpapi.Write(r.Context(), w, http.StatusNotFound, codersdk.Response{
|
||||
Message: fmt.Sprintf("SCIM endpoint %s not found", u),
|
||||
Detail: "This endpoint is not implemented. If it is correct and required, please contact support.",
|
||||
})
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// Show a helpful 404 error. Because this is not under the /api/v2 routes,
|
||||
// the frontend is the fallback. A html page is not a helpful error for
|
||||
// a SCIM provider. This JSON has a call to action that __may__ resolve
|
||||
// the issue.
|
||||
// Using Mount to cover all subroute possibilities.
|
||||
api.AGPL.RootHandler.Mount("/scim/v2", http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
httpapi.Write(r.Context(), w, http.StatusNotFound, codersdk.Response{
|
||||
Message: "SCIM is disabled, please contact your administrator if you believe this is an error",
|
||||
Detail: "SCIM endpoints are disabled if no SCIM is configured. Configure 'CODER_SCIM_AUTH_HEADER' to enable.",
|
||||
})
|
||||
})))
|
||||
var mountScimError error
|
||||
api.AGPL.RootHandler.Route("/scim", func(r chi.Router) {
|
||||
mountScimError = api.mountScimRoute(options, r)
|
||||
})
|
||||
if mountScimError != nil {
|
||||
return nil, xerrors.Errorf("mount scim routes: %w", mountScimError)
|
||||
}
|
||||
|
||||
// We always want to run the replica manager even if we don't have DERP
|
||||
@@ -754,6 +726,11 @@ type Options struct {
|
||||
// Whether to block non-browser connections.
|
||||
BrowserOnly bool
|
||||
SCIMAPIKey []byte
|
||||
// UseLegacySCIM opts into the legacy SCIM handler implementation
|
||||
// (imulab/go-scim based). This is provided for backward compatibility
|
||||
// during the transition to the new elimity-com/scim implementation.
|
||||
// It will be removed in a future release.
|
||||
UseLegacySCIM bool
|
||||
|
||||
ExternalTokenEncryption []dbcrypt.Cipher
|
||||
|
||||
|
||||
Reference in New Issue
Block a user