diff --git a/shub/apps/base/context_processors.py b/shub/apps/base/context_processors.py index aeaf50f0..536eb051 100644 --- a/shub/apps/base/context_processors.py +++ b/shub/apps/base/context_processors.py @@ -27,6 +27,7 @@ ENABLE_TWITTER_AUTH, ENABLE_GITHUB_AUTH, ENABLE_GITLAB_AUTH, + ENABLE_FIWARE_AUTH, HELP_CONTACT_EMAIL, HELP_INSTITUTION_SITE, PRIVATE_ONLY, @@ -55,6 +56,7 @@ def auth_processor(request): "ENABLE_TWITTER_AUTH":ENABLE_TWITTER_AUTH, "ENABLE_GITHUB_AUTH":ENABLE_GITHUB_AUTH, "ENABLE_GITLAB_AUTH":ENABLE_GITLAB_AUTH, + "ENABLE_FIWARE_AUTH":ENABLE_FIWARE_AUTH, "PLUGINS_ENABLED":PLUGINS_ENABLED,} diff --git a/shub/apps/users/static/css/social-auth.css b/shub/apps/users/static/css/social-auth.css index 6bb8ee89..b93bf394 100644 --- a/shub/apps/users/static/css/social-auth.css +++ b/shub/apps/users/static/css/social-auth.css @@ -219,3 +219,51 @@ html * { transition: all .3s ease; } +/* Fiware */ + +/* +.blue{color:#0093C6;} rgb(0, 147, 198) +.blue-ligth{color:#009FD6;} rgb(0, 159, 214) +.blue-dark{color:#3E80AD;} rgb(62, 128, 173) +*/ + +#fiware-connect { + background: rgb(255, 255, 255) url('/static/img/social-buttons/fiware.png') no-repeat scroll 5px 1px / 45px 45px padding-box border-box; + border: 1px solid rgb(62, 128, 173); + color: rgb(62, 128, 173); +} + +#fiware-connect:hover { + color: rgb(255, 255, 255); + border-color: rgb(62, 128, 173); + background: rgb(62, 128, 173) url('/static/img/social-buttons/fiware_hover.png') no-repeat scroll 5px 1px / 45px 45px padding-box border-box; + -webkit-transition: all .8s ease-out; + -moz-transition: all .3s ease; + -ms-transition: all .3s ease; + -o-transition: all .3s ease; + transition: all .3s ease-out; +} + +#fiware-connect span { + box-sizing: border-box; + color: rgb(62, 128, 173); + cursor: pointer; + text-align: center; + text-transform: uppercase; + border: 0px none rgb(62, 128, 173); + outline: rgb(62, 128, 173) none 0px; + -webkit-transition: all .3s ease; + -moz-transition: all .3s ease; + -ms-transition: all .3s ease; + -o-transition: all .3s ease; + transition: all .3s ease; +} + +#fiware-connect:hover span { + color: rgb(0, 159, 214); + -webkit-transition: all .3s ease; + -moz-transition: all .3s ease; + -ms-transition: all .3s ease; + -o-transition: all .3s ease; + transition: all .3s ease; + diff --git a/shub/apps/users/static/img/social-buttons/fiware.png b/shub/apps/users/static/img/social-buttons/fiware.png new file mode 100644 index 00000000..8c89ede1 Binary files /dev/null and b/shub/apps/users/static/img/social-buttons/fiware.png differ diff --git a/shub/apps/users/static/img/social-buttons/fiware_hover.png b/shub/apps/users/static/img/social-buttons/fiware_hover.png new file mode 100644 index 00000000..f4781cb5 Binary files /dev/null and b/shub/apps/users/static/img/social-buttons/fiware_hover.png differ diff --git a/shub/apps/users/templates/social/login.html b/shub/apps/users/templates/social/login.html index ff248528..061ea748 100644 --- a/shub/apps/users/templates/social/login.html +++ b/shub/apps/users/templates/social/login.html @@ -44,6 +44,10 @@

Hello, {{ user.get_full_name }}!

Login with Google {% endif %} + {% if ENABLE_FIWARE_AUTH %} + Login with Fiware + {% endif %} + {% if 'ldap_auth' in PLUGINS_ENABLED %} Login with LDAP {% endif %} diff --git a/shub/plugins/fiware/__init__.py b/shub/plugins/fiware/__init__.py new file mode 100644 index 00000000..ffa63ed1 --- /dev/null +++ b/shub/plugins/fiware/__init__.py @@ -0,0 +1 @@ +AUTHENTICATION_BACKENDS = ('shub.plugins.fiware.keyrock.KeyrockOAuth2',) diff --git a/shub/plugins/fiware/keyrock.py b/shub/plugins/fiware/keyrock.py new file mode 100644 index 00000000..a7b8a8a9 --- /dev/null +++ b/shub/plugins/fiware/keyrock.py @@ -0,0 +1,83 @@ +""" +Github OAuth2 backend, docs at: + https://python-social-auth.readthedocs.io/en/latest/backends/github.html +""" +from urllib.parse import urlencode +from requests import HTTPError + +from six.moves.urllib.parse import urljoin + +from social_core.backends.oauth import BaseOAuth2 +from social_core.exceptions import AuthFailed + +from django.conf import settings +from shub.logger import bot + +import base64 + + +class KeyrockOAuth2(BaseOAuth2): + """Keyrock OAuth authentication backend""" + name = 'fiware' + AUTHORIZATION_URL = urljoin( + settings.FIWARE_IDM_ENDPOINT, '/oauth2/authorize') + ACCESS_TOKEN_URL = urljoin(settings.FIWARE_IDM_ENDPOINT, '/oauth2/token') + #LOGOUT_URL = urljoin(settings.FIWARE_IDM_ENDPOINT, '/auth/logout') + ACCESS_TOKEN_METHOD = 'POST' + + REDIRECT_STATE = False + + EXTRA_DATA = [ + ('id', 'username'), + ('id', 'uid') + ] + + def get_user_id(self, details, response): + return response['id'] + + def get_user_details(self, response): + """Return user details from FI-WARE account""" + bot.debug( {'username': response.get('id'), + 'email': response.get('email') or '', + 'fullname': response.get('displayName') or ''}) + return {'username': response.get('id'), + 'email': response.get('email') or '', + 'fullname': response.get('displayName') or ''} + + def user_data(self, access_token, *args, **kwargs): + """Loads user data from service""" + url = urljoin(settings.FIWARE_IDM_ENDPOINT, '/user?' + urlencode({ + 'access_token': access_token + })) + bot.debug(self.get_json(url)) + return self.get_json(url) + + def auth_headers(self): + response = super(KeyrockOAuth2, self).auth_headers() + + keys = settings.SOCIAL_AUTH_FIWARE_KEY + \ + ":" + settings.SOCIAL_AUTH_FIWARE_SECRET + authorization_basic = base64.b64encode( + keys.encode('ascii')).decode('ascii') + response['Authorization'] = 'Basic ' + authorization_basic + + bot.debug(response) + return response + + def auth_complete_params(self, state=None): + # response = super(KeyrockOAuth2, self).auth_complete_params(state) + # response['grant_type'] = 'authorization_code' + \ + # '&code=' + response['code'] + \ + # '&redirect_uri=' + response['redirect_uri'] + # return response + + bot.debug( { + 'grant_type': 'authorization_code', # request auth code + 'code': self.data.get('code', ''), # server response code + 'redirect_uri': self.get_redirect_uri(state) + } ) + return { + 'grant_type': 'authorization_code', # request auth code + 'code': self.data.get('code', ''), # server response code + 'redirect_uri': self.get_redirect_uri(state) + } diff --git a/shub/plugins/fiware/urls.py b/shub/plugins/fiware/urls.py new file mode 100644 index 00000000..637600f5 --- /dev/null +++ b/shub/plugins/fiware/urls.py @@ -0,0 +1 @@ +urlpatterns = [] diff --git a/shub/settings/auth.py b/shub/settings/auth.py index bc1b775c..86fbee32 100644 --- a/shub/settings/auth.py +++ b/shub/settings/auth.py @@ -1,8 +1,8 @@ ''' -Copyright (C) 2017-2018 The Board of Trustees of the Leland Stanford Junior +Copyright (C) 2017 The Board of Trustees of the Leland Stanford Junior University. -Copyright (C) 2017-2018 Vanessa Sochat. +Copyright (C) 2017 Vanessa Sochat. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by diff --git a/shub/settings/config.py b/shub/settings/config.py index d8e12505..4979b37c 100644 --- a/shub/settings/config.py +++ b/shub/settings/config.py @@ -26,6 +26,8 @@ ENABLE_TWITTER_AUTH=True ENABLE_GITHUB_AUTH=False ENABLE_GITLAB_AUTH=False +ENABLE_FIWARE_AUTH=False + # NOTE you will need to set autehtication methods up. # Configuration goes into secrets.py @@ -103,5 +105,6 @@ # - ldap_auth: Allows sregistry to authenitcate against an LDAP directory PLUGINS_ENABLED = [ -# 'ldap_auth' +# 'ldap_auth', +# 'fiware', ] diff --git a/shub/settings/dummy_secrets.py b/shub/settings/dummy_secrets.py index c2e51f87..0fff42ab 100644 --- a/shub/settings/dummy_secrets.py +++ b/shub/settings/dummy_secrets.py @@ -57,6 +57,16 @@ #SOCIAL_AUTH_GITLAB_SECRET = '' +# ----------------------------------------------------------------------------- +# Fiware Keyrock OAuth2 +# Only required if ENABLE_FIWARE_AUTH=TRUE in config.py + +#FIWARE_IDM_ENDPOINT = 'https://account.lab.fiware.org' +#SOCIAL_AUTH_FIWARE_KEY = '' +#SOCIAL_AUTH_FIWARE_SECRET = '' + + + # ============================================================================= # Plugin Authentication