{"id":19592152,"url":"https://github.com/catalyst/moodle-local_user_provisioning","last_synced_at":"2025-08-24T14:08:08.268Z","repository":{"id":64128829,"uuid":"573638062","full_name":"catalyst/moodle-local_user_provisioning","owner":"catalyst","description":"SCIM plugin for user provisioning","archived":false,"fork":false,"pushed_at":"2024-03-08T14:06:38.000Z","size":203,"stargazers_count":5,"open_issues_count":6,"forks_count":2,"subscribers_count":18,"default_branch":"MOODLE_39_STABLE","last_synced_at":"2025-04-23T04:53:04.839Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/catalyst.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-12-03T00:42:42.000Z","updated_at":"2025-02-17T10:54:41.000Z","dependencies_parsed_at":"2022-12-07T11:16:16.555Z","dependency_job_id":null,"html_url":"https://github.com/catalyst/moodle-local_user_provisioning","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catalyst%2Fmoodle-local_user_provisioning","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catalyst%2Fmoodle-local_user_provisioning/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catalyst%2Fmoodle-local_user_provisioning/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/catalyst%2Fmoodle-local_user_provisioning/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/catalyst","download_url":"https://codeload.github.com/catalyst/moodle-local_user_provisioning/tar.gz/refs/heads/MOODLE_39_STABLE","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250372946,"owners_count":21419722,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T08:33:28.905Z","updated_at":"2025-04-23T04:53:09.873Z","avatar_url":"https://github.com/catalyst.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SCIM 2.0 compliant user provisioning plugin for Moodle\n\nThis plugin makes use of 3rd party AltoRouter class for routing the SCIM endpoints (https://github.com/dannyvankooten/AltoRouter)\n\n## How to use\n\n### Add Client identifier:\n\n1. Go to *Site Administration \u003e Server \u003e OAuth provider settings*\n\n2. Click *Add new client*\n\n3. Fill in the form. Your Client Identifier and Client Secret (which will be given later) will be used for you to authenticate. The Redirect URL is not used for this plugin as we using `client_credentials` as the authorization grant type.\n\n* Client identifier: must be same as set in the Organisation short name for the Portal organisation.\ne.g. If we are creating a Client secret key for Organisation `MSI Reproductive Choices`, the Client identifier will be `portal-61`\n* Redirect URL: is not in use and can be set to N/A\n* Grant Types: should be set to `client_credentials`\n* Scope: should be set to `SCIMv2`\n* User ID: should be set to `0`\n\n### The URL for Azure AD user provisioning is:\n`https://{siteurl}/local/user_provisioning/scim/rest.php/v2`\n\nThe client will have to create two Custom extention attribues for `Team` and `Auth`\n\n### Field mapping of Moodle to Azure AD are as follows:\n\n* idnumber : id (Azure AD - unique identifier)\n* Username : userName\n* Firstname : name.givenName\n* Lastname : name.familyName\n* Email address : emails.value (Type = Work AND primary = True)\n* Alternate name : displayName\n* Preferred language : preferredLanguage\n* City : addresses.locality (Type = Work AND primary = True)\n* Country : addresses.country (Type = Work AND primary = True)\n* Position : title\n* Suspended : active\n* Manager : urn:ietf:params:scim:schemas:extension:enterprise:2.0:User manager.value\n* Department : urn:ietf:params:scim:schemas:extension:enterprise:2.0:User department\n* Authentication : urn:ietf:params:scim:schemas:extension:CustomExtension:2.0:User auth\n* Team : urn:ietf:params:scim:schemas:extension:CustomExtension:2.0:User team\n\nSchemas endpoint provides a fair representation of Azure AD fields.\n\n### Generate a Long-lived bearer token:\n\n\n### Valid end points for this API are:\n\n#### `/token` - To validate / generate a token using the Client identifier and Client secret.\n\ncurl https://{siteurl}/local/user_provisioning/scim/rest.php/v2/token -d 'grant_type=client_credentials\u0026client_id=\u003cCLIENT_ID\u003e\u0026client_secret=\u003cCLIENT_SECRET\u003e'\n\nWhere CLIENT_ID is the Client identifier and the CLIENT_SECRET is the key generated when adding a new client as part of `Add Client identifier`\n\n#### `/ServiceProviderConfig` - To view the SCIM service provider config.\n\ncurl --location --request GET 'https://{SITE_URL}/local/user_provisioning/scim/rest.php/v2/ServiceProviderConfig' \\\n--header 'Authorization: Bearer {BEARER_TOKEN}'\n\n#### /Schemas` - To view the SCIM schemas that are used. Append following to view the individual User, Enterprise and Custom extention schema:\n\n* urn:ietf:params:scim:schemas:core:2.0:User\n* urn:ietf:params:scim:schemas:extension:enterprise:2.0:User\n* urn:ietf:params:scim:schemas:extension:CustomExtensionName:2.0:User\n\ncurl --location --request GET 'https://{SITE_URL}/local/user_provisioning/scim/rest.php/v2/Schemas' \\\n--header 'Authorization: Bearer {BEARER_TOKEN}'\n\n#### `/Users?filters={SEARCH_CRITERIA}` - GET request to fetch a given user's data\n\ncurl --location --request POST 'https://{SITE_URL}/local/user_provisioning/scim/rest.php/v2/Users?filter={SEARCH_CRITERIA}' \\\n--header 'Authorization: Bearer {BEARER_TOKEN}'\n\nSupported SEARCH_CRITERIA fields are:\nuserName, name.familyName, name.givenName and emails.\n\nSupported SCIM filter types are:\neq (equal) Ee.g. filter=userName+eq+\"joeb@job.com\"\nneq (Not Equal) Ee.g. filter=userName+neq+\"joeb@job.com\"\nco (Contains) e.g. filter=userName+co+\"joeb@job.com\"\nsw (Starts With) e.g. filter=userName+sw+\"joeb@job.com\"\new (Ends With) e.g. filter=userName+ew+\"joeb@job.com\"\n\n#### `/Users/{USER_ID}` - GET request to fetch a given user's data\n\ncurl --location --request POST 'https://{SITE_URL}/local/user_provisioning/scim/rest.php/v2/Users' \\\n--header 'Authorization: Bearer {BEARER_TOKEN}'\n\n#### `/Users` - POST request to create / provision a new user.\n\ncurl --location --request POST 'https://{SITE_URL}/local/user_provisioning/scim/rest.php/v2/Users' \\\n--header 'Authorization: Bearer {BEARER_TOKEN}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{\n    \"schemas\": [\"urn:ietf:params:scim:schemas:core:2.0:User\", \"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User\"],\n    \"externalId\": \"XXXXXXXX\",\n    \"userName\": \"catalyst.admin@catalyst-eu.net\",\n    \"active\": true,\n    \"addresses\": [{\n        \"primary\": true,\n        \"type\": \"work\",\n        \"country\": \"United Kingdom\",\n        \"locality\": \"Brighton\"\n    }],\n    \"displayName\": \"Catalyst Admin\",\n    \"emails\": [{\n        \"primary\": true,\n        \"type\": \"work\",\n        \"value\": \"catalyst.admin@catalyst-eu.net\"\n    }],\n    \"name\": {\n        \"familyName\": \"Catalyst\",\n        \"givenName\": \"Admin\"\n    },\n    \"title\": \"Site Administrator\",\n    \"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User\": {\n        \"department\": \"Internet Technologist\",\n        \"manager\": {\n            \"value\": \"\"\n        }\n    },\n    \"urn:ietf:params:scim:schemas:extension:CustomExtension:2.0:User\": {\n        \"auth\": \"saml2\",\n        \"team\": \"IT\"\n    }\n}'\n\n#### `/Users` - PATCH request to update given user's data.\n\ncurl --location --request PATCH 'https://{SITE_URL}/local/user_provisioning/scim/rest.php/v2/Users' \\\n--header 'Authorization: Bearer {BEARER_TOKEN}' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{\n    \"schemas\": [\n        \"urn:ietf:params:scim:api:messages:2.0:PatchOp\"\n    ],\n    \"Operations\": [\n        {\n            \"op\": \"Add\",\n            \"path\": \"displayName\",\n            \"value\": \"Catalyst Admin\"\n        },\n        {\n            \"op\": \"Add\",\n            \"path\": \"emails[type eq \\\"work\\\"].value\",\n            \"value\": \"bitsprintuk+catalyst@gmail.com\"\n        },\n        {\n            \"op\": \"Replace\",\n            \"path\": \"name.givenName\",\n            \"value\": \"Admin\"\n        },\n        {\n            \"op\": \"Replace\",\n            \"path\": \"name.familyName\",\n            \"value\": \"Catalyst\"\n        }\n    ]\n}'\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcatalyst%2Fmoodle-local_user_provisioning","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcatalyst%2Fmoodle-local_user_provisioning","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcatalyst%2Fmoodle-local_user_provisioning/lists"}