from allauth.account.models import EmailAddress from allauth.socialaccount import app_settings from allauth.socialaccount.providers.base import AuthAction, ProviderAccount from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider class Scope(object): NAME = "aq:name" EMAIL = "email" PHONE = "phone" ADDRESS = "address" LOCATION = "aq:location" PUSH = "aq:push" IDENTITY_CLAIMS = frozenset( [ "sub", "name", "given_name", "family_name", "middle_name", "nickname", "preferred_username", "profile", "picture", "website", "email", "email_verified", "gender", "birthdate", "zoneinfo", "locale", "phone_number", "phone_number_verified", "address", "updated_at", "aq:location", ] ) class AuthentiqAccount(ProviderAccount): def get_profile_url(self): return self.account.extra_data.get("profile") def get_avatar_url(self): return self.account.extra_data.get("picture") def to_str(self): dflt = super(AuthentiqAccount, self).to_str() return self.account.extra_data.get("name", dflt) class AuthentiqProvider(OAuth2Provider): id = "authentiq" name = "Authentiq" account_class = AuthentiqAccount def get_scope(self, request): scope = set(super(AuthentiqProvider, self).get_scope(request)) scope.add("openid") if Scope.EMAIL in scope: modifiers = "" if app_settings.EMAIL_REQUIRED: modifiers += "r" if app_settings.EMAIL_VERIFICATION: modifiers += "s" if modifiers: scope.add(Scope.EMAIL + "~" + modifiers) scope.remove(Scope.EMAIL) return list(scope) def get_default_scope(self): scope = [Scope.NAME, Scope.PUSH] if app_settings.QUERY_EMAIL: scope.append(Scope.EMAIL) return scope def get_auth_params(self, request, action): ret = super(AuthentiqProvider, self).get_auth_params(request, action) if action == AuthAction.REAUTHENTICATE: ret["prompt"] = "select_account" return ret def extract_uid(self, data): return str(data["sub"]) def extract_common_fields(self, data): return dict( username=data.get("preferred_username", data.get("given_name")), email=data.get("email"), name=data.get("name"), first_name=data.get("given_name"), last_name=data.get("family_name"), ) def extract_extra_data(self, data): return {k: v for k, v in data.items() if k in IDENTITY_CLAIMS} def extract_email_addresses(self, data): ret = [] email = data.get("email") if email and data.get("email_verified"): ret.append(EmailAddress(email=email, verified=True, primary=True)) return ret provider_classes = [AuthentiqProvider]