goauthentik / goauthentik/authentik

Mastodon as a identity source

Open
#4,193 4 comments 2 reactions 0 assignees View on GitHub
enhancement
Dominant language
Python
Stars
25.6k
Forks
2k
Avg merge
1d 1h
Merged PRs (30d)
644

Description

**Is your feature request related to a problem? Please describe.**
It would be fantastic to hook authentik up to a particular mastodon instance to allow for oauth signin. This might also work for other fediverse social platforms like Pleroma.

**Describe the solution you'd like**
Add mastodon as a potential source for federation and social login. I think the code would be something roughly like the attached (but I am not familiar enough to test it, so I don't have a specific PR)

**Describe alternatives you've considered**
I have tried setting it up as an oidc connection to test, but that is not quite ideal as mastodon only supports oauth2 and not full oidc. Things like username don't automatically populate. I thought about making my own build for authentik but I don't think I know enough to do that yet 😞 .

**Additional context**
Here is roughly what I think might work for Mastodon? Then an admin could simply paste the URLs of their instance, after creating a new developer application to get the client key and id:
https://[instance]/oauth/authorize
https://[instance]/oauth/token
https://[instance]/api/v1/accounts/verify_credentials for profile
```
class MastodonClient(OAuth2Client):
"""Mastodon OAuth2 Client"""

def get_access_token(self, **request_kwargs):
"Fetch access token from callback request."
auth = HTTPBasicAuth(self.source.consumer_key, self.source.consumer_secret)
return super().get_access_token(auth=auth)

class MastodonOAuthRedirect(OAuthRedirect):
"""Mastodon OAuth2 Redirect"""

def get_additional_parameters(self, source: OAuthSource): # pragma: no cover
return {
"scope": ["read"]
}

class MastodonOAuth2Callback(OAuthCallback):
"""Mastodon OAuth2 Callback"""

client_class = MastodonClient

def get_user_id(self, info: dict[str, str]) -> str:
return info.get("username", "")

def get_user_enroll_context(
self,
info: dict[str, Any],
) -> dict[str, Any]:
return {
"username": info.get("username"),
"name": info.get("display_name")
}

@registry.register()
class MastodonType(SourceType):
"""Mastodon Type definition"""

callback_view = MastodonOAuth2Callback
redirect_view = MastodonOAuthRedirect
name = "Mastodon"
slug = "Mastodon"

urls_customizable = True
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.