diff --git a/social_core/backends/openstreetmap_oauth2.py b/social_core/backends/openstreetmap_oauth2.py new file mode 100644 index 00000000..6e1e877a --- /dev/null +++ b/social_core/backends/openstreetmap_oauth2.py @@ -0,0 +1,69 @@ +""" +OpenStreetMap OAuth 2.0 support. + +This adds support for OpenStreetMap OAuth service. An application must be +registered first on OpenStreetMap and the settings +SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_KEY and SOCIAL_AUTH_OPENSTREETMAP_OAUTH2_SECRET +must be defined with the corresponding values. + +More info: https://wiki.openstreetmap.org/wiki/OAuth +""" +from xml.dom import minidom + +from .oauth import BaseOAuth2PKCE + + +class OpenStreetMapOAuth2(BaseOAuth2PKCE): + """OpenStreetMap OAuth2 authentication backend""" + + name = "openstreetmap-oauth2" + AUTHORIZATION_URL = "https://www.openstreetmap.org/oauth2/authorize" + ACCESS_TOKEN_URL = "https://www.openstreetmap.org/oauth2/token" + ACCESS_TOKEN_METHOD = "POST" + SCOPE_SEPARATOR = " " + STATE_PARAMETER = True + EXTRA_DATA = [ + ("id", "id"), + ("avatar", "avatar"), + ("account_created", "account_created"), + ] + PKCE_DEFAULT_CODE_CHALLENGE_METHOD = "S256" + DEFAULT_USE_PKCE = True + + def get_user_details(self, response): + """Return user details from OpenStreetMap account""" + return { + "username": response["username"], + "email": "", + "fullname": "", + "first_name": "", + "last_name": "", + } + + def user_data(self, access_token, *args, **kwargs): + """Return user data provided""" + response = self.oauth_request( + access_token, "https://api.openstreetmap.org/api/0.6/user/details" + ) + try: + dom = minidom.parseString(response.content) + except ValueError: + return None + user = dom.getElementsByTagName("user")[0] + try: + avatar = dom.getElementsByTagName("img")[0].getAttribute("href") + except IndexError: + avatar = None + return { + "id": user.getAttribute("id"), + "username": user.getAttribute("display_name"), + "account_created": user.getAttribute("account_created"), + "avatar": avatar, + } + +class OpenStreetMapOAuth2Sandbox(OpenStreetMapOAuth2): + """OpenStreetMap OAuth2 authentication testing backend""" + + name = "openstreetmap-oauth2-dev" + AUTHORIZATION_URL = "https://master.apis.dev.openstreetmap.org/oauth2/authorize" + ACCESS_TOKEN_URL = "https://master.apis.dev.openstreetmap.org/oauth2/token"