website/integrations: Update discord integration with guild and role check (#5701)
* Update Discord OAuth instructions - index.md Adds two sections to this document describing how the required expression policies needed to check users are a member of a certain guild or a member of a certain guild with a certain role. Signed-off-by: Aterfax <Aterfax@users.noreply.github.com> * Linting and styleguide amendments. * Remove spurious empty lines. * Add an extra line to space comments out. * Moved warning in wrong place. * Apply suggestions from code review Refactor as per BeryJu's suggestions. Co-authored-by: Jens L. <jens@beryju.org> Signed-off-by: Aterfax <Aterfax@users.noreply.github.com> --------- Signed-off-by: Aterfax <Aterfax@users.noreply.github.com> Co-authored-by: Jens L. <jens@beryju.org>
This commit is contained in:
parent
b4a3b266b3
commit
d8de60b053
|
@ -52,3 +52,93 @@ Save, and you now have Discord as a source.
|
||||||
:::note
|
:::note
|
||||||
For more details on how-to have the new source display on the Login Page see [here](../general#add-sources-to-default-login-page).
|
For more details on how-to have the new source display on the Login Page see [here](../general#add-sources-to-default-login-page).
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
### Checking for membership of a Discord Guild
|
||||||
|
|
||||||
|
:::info
|
||||||
|
Ensure that the Discord OAuth source in 'Federation & Social login' has the additional `guilds` scope added under the 'Protocol settings'.
|
||||||
|
:::
|
||||||
|
|
||||||
|
Create a new 'Expression Policy' with the content below, adjusting the variables where required:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# To get the guild ID number for the parameters, open Discord, go to Settings > Advanced and enable developer mode.
|
||||||
|
# Right-click on the server/guild title and select "Copy ID" to get the guild ID.
|
||||||
|
|
||||||
|
ACCEPTED_GUILD_ID = "123456789123456789"
|
||||||
|
GUILD_NAME_STRING = "The desired server/guild name in the error message."
|
||||||
|
|
||||||
|
# Only change below here if you know what you are doing.
|
||||||
|
|
||||||
|
# Ensure flow is only run during OAuth logins via Discord
|
||||||
|
if context['source'].provider_type != "discord":
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Get the user-source connection object from the context, and get the access token
|
||||||
|
connection = context.get("goauthentik.io/sources/connection")
|
||||||
|
if not connection:
|
||||||
|
return False
|
||||||
|
access_token = connection.access_token
|
||||||
|
|
||||||
|
guilds = requests.get(
|
||||||
|
"https://discord.com/api/users/@me/guilds",
|
||||||
|
headers= {
|
||||||
|
"Authorization": f"Bearer {access_token}",
|
||||||
|
}
|
||||||
|
).json()
|
||||||
|
|
||||||
|
user_matched = any(ACCEPTED_GUILD_ID == g["id"] for g in guilds)
|
||||||
|
if not user_matched:
|
||||||
|
ak_message(f"User is not a member of {GUILD_NAME_STRING}.")
|
||||||
|
return user_matched
|
||||||
|
```
|
||||||
|
|
||||||
|
Now bind this policy to the chosen enrollment and authentication flows for the Discord OAuth source.
|
||||||
|
|
||||||
|
### Checking for membership of a Discord Guild role
|
||||||
|
|
||||||
|
:::info
|
||||||
|
Ensure that the Discord OAuth source in 'Federation & Social login' has the additional `guilds guilds.members.read` scopes added under the 'Protocol settings'.
|
||||||
|
:::
|
||||||
|
|
||||||
|
Create a new 'Expression Policy' with the content below, adjusting the variables where required:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# To get the role and guild ID numbers for the parameters, open Discord, go to Settings > Advanced and
|
||||||
|
# enable developer mode.
|
||||||
|
# Right-click on the server/guild title and select "Copy ID" to get the guild ID.
|
||||||
|
# Right-click on the server/guild title and select server settings > roles, right click on the role and click
|
||||||
|
# "Copy ID" to get the role ID.
|
||||||
|
|
||||||
|
ACCEPTED_ROLE_ID = "123456789123456789"
|
||||||
|
ACCEPTED_GUILD_ID = "123456789123456789"
|
||||||
|
GUILD_NAME_STRING = "The desired server/guild name in the error message."
|
||||||
|
ROLE_NAME_STRING = "The desired role name in the error message."
|
||||||
|
|
||||||
|
# Only change below here if you know what you are doing.
|
||||||
|
GUILD_API_URL = f"https://discord.com/api/users/@me/guilds/{ACCEPTED_GUILD_ID}/member"
|
||||||
|
|
||||||
|
# Ensure flow is only run during OAuth logins via Discord
|
||||||
|
if context['source'].provider_type != "discord":
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Get the user-source connection object from the context, and get the access token
|
||||||
|
connection = context.get("goauthentik.io/sources/connection")
|
||||||
|
if not connection:
|
||||||
|
return False
|
||||||
|
access_token = connection.access_token
|
||||||
|
|
||||||
|
guild_member_object = requests.get(
|
||||||
|
GUILD_API_URL,
|
||||||
|
headers= {
|
||||||
|
"Authorization": f"Bearer {access_token}",
|
||||||
|
}
|
||||||
|
).json()
|
||||||
|
|
||||||
|
user_matched = any(ACCEPTED_ROLE_ID == g for g in guild_member_object["roles"])
|
||||||
|
if not user_matched:
|
||||||
|
ak_message(f"User is not a member of the {ROLE_NAME_STRING} role in {GUILD_NAME_STRING}.")
|
||||||
|
return user_matched
|
||||||
|
```
|
||||||
|
|
||||||
|
Now bind this policy to the chosen enrollment and authentication flows for the Discord OAuth source.
|
||||||
|
|
Reference in New Issue