From 58b91dd3baaaf72ab65062a4804403cd4a5935b2 Mon Sep 17 00:00:00 2001 From: xudan Date: Thu, 5 Jul 2018 22:37:35 -0400 Subject: Move OVP web portal code to a separate repo The new repo for web portal is https://gerrit.opnfv.org/gerrit/dovetail-webportal JIRA: DOVETAIL-671 Change-Id: Iac085abc3d175b9a091d70d0448af56c7a6845e9 Signed-off-by: xudan --- cvp/opnfv_testapi/ui/__init__.py | 0 cvp/opnfv_testapi/ui/auth/__init__.py | 0 cvp/opnfv_testapi/ui/auth/base.py | 35 ---- cvp/opnfv_testapi/ui/auth/constants.py | 18 --- cvp/opnfv_testapi/ui/auth/jira_util.py | 66 -------- cvp/opnfv_testapi/ui/auth/rsa.pem | 27 ---- cvp/opnfv_testapi/ui/auth/sign.py | 281 --------------------------------- cvp/opnfv_testapi/ui/auth/user.py | 35 ---- cvp/opnfv_testapi/ui/root.py | 10 -- 9 files changed, 472 deletions(-) delete mode 100644 cvp/opnfv_testapi/ui/__init__.py delete mode 100644 cvp/opnfv_testapi/ui/auth/__init__.py delete mode 100644 cvp/opnfv_testapi/ui/auth/base.py delete mode 100644 cvp/opnfv_testapi/ui/auth/constants.py delete mode 100644 cvp/opnfv_testapi/ui/auth/jira_util.py delete mode 100644 cvp/opnfv_testapi/ui/auth/rsa.pem delete mode 100644 cvp/opnfv_testapi/ui/auth/sign.py delete mode 100644 cvp/opnfv_testapi/ui/auth/user.py delete mode 100644 cvp/opnfv_testapi/ui/root.py (limited to 'cvp/opnfv_testapi/ui') diff --git a/cvp/opnfv_testapi/ui/__init__.py b/cvp/opnfv_testapi/ui/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/cvp/opnfv_testapi/ui/auth/__init__.py b/cvp/opnfv_testapi/ui/auth/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/cvp/opnfv_testapi/ui/auth/base.py b/cvp/opnfv_testapi/ui/auth/base.py deleted file mode 100644 index bea87c4d..00000000 --- a/cvp/opnfv_testapi/ui/auth/base.py +++ /dev/null @@ -1,35 +0,0 @@ -import random -import string - -from six.moves.urllib import parse - -from opnfv_testapi.resources import handlers - - -class BaseHandler(handlers.GenericApiHandler): - def __init__(self, application, request, **kwargs): - super(BaseHandler, self).__init__(application, request, **kwargs) - self.table = 'users' - - def set_cookies(self, cookies): - for cookie_n, cookie_v in cookies: - self.set_secure_cookie(cookie_n, cookie_v) - - -def get_token(length=30): - """Get random token.""" - return ''.join(random.choice(string.ascii_lowercase) - for i in range(length)) - - -def set_query_params(url, params): - """Set params in given query.""" - url_parts = parse.urlparse(url) - url = parse.urlunparse(( - url_parts.scheme, - url_parts.netloc, - url_parts.path, - url_parts.params, - parse.urlencode(params), - url_parts.fragment)) - return url diff --git a/cvp/opnfv_testapi/ui/auth/constants.py b/cvp/opnfv_testapi/ui/auth/constants.py deleted file mode 100644 index 44ccb46d..00000000 --- a/cvp/opnfv_testapi/ui/auth/constants.py +++ /dev/null @@ -1,18 +0,0 @@ -OPENID = 'openid' -ROLE = 'role' -DEFAULT_ROLE = 'user' - -# OpenID parameters -OPENID_MODE = 'openid.mode' -OPENID_NS = 'openid.ns' -OPENID_RETURN_TO = 'openid.return_to' -OPENID_CLAIMED_ID = 'openid.claimed_id' -OPENID_IDENTITY = 'openid.identity' -OPENID_REALM = 'openid.realm' -OPENID_NS_SREG = 'openid.ns.sreg' -OPENID_NS_SREG_REQUIRED = 'openid.sreg.required' -OPENID_NS_SREG_EMAIL = 'openid.sreg.email' -OPENID_NS_SREG_FULLNAME = 'openid.sreg.fullname' -OPENID_ERROR = 'openid.error' - -CSRF_TOKEN = 'csrf_token' diff --git a/cvp/opnfv_testapi/ui/auth/jira_util.py b/cvp/opnfv_testapi/ui/auth/jira_util.py deleted file mode 100644 index 5ec91a71..00000000 --- a/cvp/opnfv_testapi/ui/auth/jira_util.py +++ /dev/null @@ -1,66 +0,0 @@ -############################################################################## -# Copyright (c) 2016 Max Breitenfeldt and others. -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - - -import base64 -import os - -import oauth2 as oauth -from jira import JIRA -from tlslite.utils import keyfactory -from opnfv_testapi.common.config import CONF - - -class SignatureMethod_RSA_SHA1(oauth.SignatureMethod): - name = 'RSA-SHA1' - - def signing_base(self, request, consumer, token): - if not hasattr(request, 'normalized_url') or \ - request.normalized_url is None: - raise ValueError("Base URL for request is not set.") - - sig = ( - oauth.escape(request.method), - oauth.escape(request.normalized_url), - oauth.escape(request.get_normalized_parameters()), - ) - - key = '%s&' % oauth.escape(consumer.secret) - if token: - key += oauth.escape(token.secret) - raw = '&'.join(sig) - return key, raw - - def sign(self, request, consumer, token): - """Builds the base signature string.""" - key, raw = self.signing_base(request, consumer, token) - - module_dir = os.path.dirname(__file__) # get current directory - with open(module_dir + '/rsa.pem', 'r') as f: - data = f.read() - privateKeyString = data.strip() - privatekey = keyfactory.parsePrivateKey(privateKeyString) - raw = str.encode(raw) - signature = privatekey.hashAndSign(raw) - return base64.b64encode(signature) - - -def get_jira(access_token): - module_dir = os.path.dirname(__file__) # get current directory - with open(module_dir + '/rsa.pem', 'r') as f: - key_cert = f.read() - - oauth_dict = { - 'access_token': access_token['oauth_token'], - 'access_token_secret': access_token['oauth_token_secret'], - 'consumer_key': CONF.jira_oauth_consumer_key, - 'key_cert': key_cert - } - - return JIRA(server=CONF.jira_jira_url, oauth=oauth_dict) diff --git a/cvp/opnfv_testapi/ui/auth/rsa.pem b/cvp/opnfv_testapi/ui/auth/rsa.pem deleted file mode 100644 index 5ec1bbf1..00000000 --- a/cvp/opnfv_testapi/ui/auth/rsa.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAyDe0zz8Gpr1dh31c7R8LGV4p+wT0s2sUTtha1ex3GXzhEewQ -Cx3WUW/tttnBGd0oVVNMzoaIPbQJgPnuyVx2VugELLIdPHd9ngPDq09YWzK/J3VW -3I0sQLA5xVmGv32z4Uz7vbc7/4UM+FXPqUmhWBysR0zsm/nlLqbLs08GEyt2ZT+v -rNQnYtWA6YuL2OHSHvkQlwibpezHzs6LV7A8mQjWbptu0FL229h6pNSyV7YM459w -Z5RzBsPybl07P5HOVtkSizIFJ+HLc6yp4cVxjCgk4rMKyPBSG9dBEaHMlBCis61R -2lTbCJiy7SnWGiMd28WKuvu2k8T4A9k2FzvYwwIDAQABAoIBAGqhOFtTjqBIo8If -4tiqOsgE3UjBp+zR71vaX+4kZH2fg2J/HUA+YMC4YpqKOAwlO3DNz08CWRa7hoA5 -G5ID+0ZnhKmlJmronG8GRDQ9KqpPSXyjQmJtkQ7Wi73t4xSixqUL0dqE9qAr5O9x -DAp1m0cI5juG3VBoc0U4Ma5KPMsB3jceeV446ZsU07LSgTIOfLNzq6oEWLWhBzLj -rDRcGyB6iNxCsNacruW3DKrDg1cMqWqjxt6Tf4LuTWYFmGedTIktmn7VZDgXcbkK -a7sCRr7P0br6zuIFak1ugkUECDwNznLz3+QgW/iaay6NL6qEpnMLg3Z44kP+BLma -h5g/SvECgYEA7ewD4lG8s/iz5OIinVHIW10Bc8pEMX3+8cVCo+rq7YbWG+HqXFrv -DUcyRu/O3SHpc4ozkhRMTsVK5xGUuWGlLG9Hit5R4Ra8oHurJMsFUqjaptd9roHi -CMmynCFupqBwDoxMig5KxvuDqbOmo2yQOelP/UEnC+qlrux5+lClx4sCgYEA125H -KPAi30FkRJ/7pzlNtcqzNYQh6xdgcrDIsU1zHRa4AOPYSD+WSkb7wAbns5WLlOM8 -wScpUijyfu56YDizHuID4QW4ddKGVLEbx4tt8CiPLzweeFsP/FSfpd+OK0EDs8wP -S0b81rCkJKvGljfdl/wY3mYXOu0RZzXB55N1GqkCgYAscy+2lLbAmPJjDKyS37ii -+RlQXLWo2XVMDiKJJVaG0e4mf2qdno+S135ZKmxne/J1l5hS7l/jR5Da4rn6eHe3 -eYLQOwDpIKpVAUXUNenkq49OJGxisflc0vH/oW9eyhKlZSjXkhv+WPccOWgkmB/J -8gDzu7xjyY7yw1N2pKKUSQKBgQCfhdB5twALk698xX6igGNT10pGuZYoMEJCCzhB -WlmAU79jIVSZg0R1sgRfWH2gVH9se6wUVzxY02tlpI/HypSQrMo0iXji/kZsVk18 -wHljGZWVY44ojz3SGpOxT05GJzlnnRZCJsm47EpPwUcnGy0iixGbNbvD7aIya/Mu -2NkhKQKBgBgLvhfU3sU6XYrF99L63W1vcDyoXcsmQQtz2EzPflFkdcLYoeHo13XW -Apv7EeX+zqaeqx0v7xuVYWyde5ux9+vII4al0jToabLcd0y2k0Oxmjv40K1YVYsu -ZqoLXriNHf4NkqgQAFu8FfV1S9RTl6+3X4z6yzf09ustxiw3KWCz ------END RSA PRIVATE KEY----- diff --git a/cvp/opnfv_testapi/ui/auth/sign.py b/cvp/opnfv_testapi/ui/auth/sign.py deleted file mode 100644 index dbb40ed0..00000000 --- a/cvp/opnfv_testapi/ui/auth/sign.py +++ /dev/null @@ -1,281 +0,0 @@ -############################################################################## -# Copyright (c) 2015 Orange -# guyrodrigue.koffi@orange.com / koffirodrigue@gmail.com -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - - -from six.moves.urllib import parse -from tornado import gen -from tornado import web - -from cas import CASClient -from opnfv_testapi.ui.auth.jira_util import SignatureMethod_RSA_SHA1 -from opnfv_testapi.ui.auth.jira_util import get_jira - -from opnfv_testapi.common.config import CONF -from opnfv_testapi.db import api as dbapi -from opnfv_testapi.ui.auth import base -from opnfv_testapi.ui.auth import constants as const - -import logging -import oauth2 as oauth - -root = logging.getLogger() -root.setLevel(logging.DEBUG) - - -class SigninHandler(base.BaseHandler): - def get(self): - signin_type = self.get_query_argument("type") - self.set_secure_cookie("signin_type", signin_type) - if signin_type == "openstack": - self.signin_with_openstack() - if signin_type == "jira": - self.signin_with_jira() - if signin_type == "cas": - self.signin_with_cas() - - def signin_with_cas(self): - client = CASClient( - version='2', - renew=False, - extra_login_params=False, - server_url=CONF.lfid_url, - service_url=CONF.lfid_return_url - ) - redirect_url = client.get_login_url() - self.redirect(url=redirect_url, permanent=False) - - def signin_with_openstack(self): - csrf_token = base.get_token() - return_endpoint = parse.urljoin(CONF.api_url, - CONF.osid_openid_return_to) - return_to = base.set_query_params(return_endpoint, - {const.CSRF_TOKEN: csrf_token}) - - params = { - const.OPENID_MODE: CONF.osid_openid_mode, - const.OPENID_NS: CONF.osid_openid_ns, - const.OPENID_RETURN_TO: return_to, - const.OPENID_CLAIMED_ID: CONF.osid_openid_claimed_id, - const.OPENID_IDENTITY: CONF.osid_openid_identity, - const.OPENID_REALM: CONF.api_url, - const.OPENID_NS_SREG: CONF.osid_openid_ns_sreg, - const.OPENID_NS_SREG_REQUIRED: CONF.osid_openid_sreg_required, - } - url = CONF.osid_openstack_openid_endpoint - url = base.set_query_params(url, params) - self.redirect(url=url, permanent=False) - - def signin_with_jira(self): - consumer = oauth.Consumer(CONF.jira_oauth_consumer_key, - CONF.jira_oauth_consumer_secret) - client = oauth.Client(consumer) - client.set_signature_method(SignatureMethod_RSA_SHA1()) - - # Step 1. Get a request token from Jira. - try: - resp, content = client.request(CONF.jira_oauth_request_token_url, - "POST") - except Exception as e: - logging.error('Connect jira exception: %s', e) - self._auth_failure('Error: Connection to Jira failed. \ - Please contact an Administrator') - return - - if resp['status'] != '200': - logging.error('Connect jira error: %s', resp) - self._auth_failure('Error: Connection to Jira failed. \ - Error code(%s). \ - Please contact an Administrator' % (resp['status'])) - return - - # Step 2. Store the request token in a session for later use. - logging.warning('content is %s', content) - request_token = dict(parse.parse_qsl(content.decode())) - self.set_secure_cookie('oauth_token', request_token['oauth_token']) - self.set_secure_cookie('oauth_token_secret', - request_token['oauth_token_secret']) - - # Step 3. Redirect the user to the authentication URL. - url = CONF.jira_oauth_authorize_url + '?oauth_token=' + \ - request_token['oauth_token'] + \ - '&oauth_callback=' + CONF.jira_oauth_callback_url - self.redirect(url=url, permanent=False) - - def _auth_failure(self, message): - params = {'message': message} - url = parse.urljoin(CONF.ui_url, - '/#/auth_failure?' + parse.urlencode(params)) - self.redirect(url) - - -class SigninReturnHandler(base.BaseHandler): - @web.asynchronous - @gen.coroutine - def get(self): - if self.get_query_argument(const.OPENID_MODE) == 'cancel': - self._auth_failure('Authentication canceled.') - - openid = self.get_query_argument(const.OPENID_CLAIMED_ID) - role = const.DEFAULT_ROLE - new_user_info = { - 'openid': openid, - 'email': self.get_query_argument(const.OPENID_NS_SREG_EMAIL), - 'fullname': self.get_query_argument(const.OPENID_NS_SREG_FULLNAME), - const.ROLE: role - } - user = yield dbapi.db_find_one(self.table, {'openid': openid}) - if not user: - dbapi.db_save(self.table, new_user_info) - else: - role = user.get(const.ROLE) - - self.clear_cookie(const.OPENID) - self.clear_cookie(const.ROLE) - self.set_secure_cookie(const.OPENID, openid) - self.set_secure_cookie(const.ROLE, role) - self.redirect(url=CONF.ui_url) - - -class SigninReturnCasHandler(base.BaseHandler): - @web.asynchronous - @gen.coroutine - def get(self): - logging.warning("cas return") - ticket = self.get_query_argument('ticket') - logging.warning("ticket:%s", ticket) - client = CASClient( - version='2', - renew=False, - extra_login_params=False, - server_url=CONF.lfid_url, - service_url=CONF.lfid_return_url - ) - user, attrs, _ = client.verify_ticket(ticket) - logging.debug("user:%s", user) - logging.debug("attr:%s", attrs) - openid = user - role = const.DEFAULT_ROLE - new_user_info = { - 'openid': openid, - 'email': attrs['mail'], - 'fullname': attrs['profile_name_full'], - const.ROLE: role - } - user = yield dbapi.db_find_one(self.table, {'openid': openid}) - if not user: - dbapi.db_save(self.table, new_user_info) - else: - role = user.get(const.ROLE) - - self.clear_cookie(const.OPENID) - self.clear_cookie(const.ROLE) - self.clear_cookie('ticket') - self.set_secure_cookie(const.OPENID, openid) - self.set_secure_cookie(const.ROLE, role) - self.set_secure_cookie('ticket', ticket) - - self.redirect("/") - - -class SigninReturnJiraHandler(base.BaseHandler): - @web.asynchronous - @gen.coroutine - def get(self): - logging.warning("jira return") - # Step 1. Use the request token in the session to build a new client. - consumer = oauth.Consumer(CONF.jira_oauth_consumer_key, - CONF.jira_oauth_consumer_secret) - token = oauth.Token(self.get_secure_cookie('oauth_token'), - self.get_secure_cookie('oauth_token_secret')) - client = oauth.Client(consumer, token) - client.set_signature_method(SignatureMethod_RSA_SHA1()) - - # Step 2. Request the authorized access token from Jira. - try: - resp, content = client.request(CONF.jira_oauth_access_token_url, - "POST") - except Exception as e: - logging.error("Connect jira exception:%s", e) - self._auth_failure('Error: Connection to Jira failed. \ - Please contact an Administrator') - if resp['status'] != '200': - logging.error("Connect jira error:%s", resp) - self._auth_failure('Error: Connection to Jira failed. \ - Please contact an Administrator') - access_token = dict(parse.parse_qsl(content.decode())) - logging.warning("access_token: %s", access_token) - - # jira = JIRA(server=CONF.jira_jira_url, oauth=oauth_dict) - jira = get_jira(access_token) - lf_id = jira.current_user() - logging.warning("lf_id: %s", lf_id) - user = jira.myself() - logging.warning("user: %s", user) - # Step 3. Lookup the user or create them if they don't exist. - role = const.DEFAULT_ROLE - new_user_info = { - 'openid': lf_id, - 'email': user['emailAddress'], - 'fullname': user['displayName'], - const.ROLE: role - } - user = yield dbapi.db_find_one(self.table, {'openid': lf_id}) - if not user: - dbapi.db_save(self.table, new_user_info) - else: - role = user.get(const.ROLE) - - self.clear_cookie(const.OPENID) - self.clear_cookie(const.ROLE) - self.set_secure_cookie(const.OPENID, lf_id) - self.set_secure_cookie(const.ROLE, role) - self.redirect(url=CONF.ui_url) - - def _auth_failure(self, message): - params = {'message': message} - url = parse.urljoin(CONF.ui_url, - '/#/auth_failure?' + parse.urlencode(params)) - self.redirect(url) - - -class SignoutHandler(base.BaseHandler): - def get(self): - """Handle signout request.""" - self.clear_cookie(const.OPENID) - self.clear_cookie(const.ROLE) - signin_type = self.get_secure_cookie("signin_type") - if signin_type == "openstack": - self.signout_openstack() - if signin_type == "jira": - self.signout_jira() - if signin_type == 'cas': - self.signout_cas() - - def signout_openstack(self): - params = {'openid_logout': CONF.osid_openid_logout_endpoint} - url = parse.urljoin(CONF.ui_url, - '/#/logout?' + parse.urlencode(params)) - self.redirect(url) - - def signout_jira(self): - params = {'alt_token': ''} - url = parse.urljoin(CONF.jira_jira_url, - '/logout?' + parse.urlencode(params)) - self.redirect(url) - - def signout_cas(self): - client = CASClient( - version='2', - renew=False, - extra_login_params=False, - server_url=CONF.lfid_url, - service_url=CONF.lfid_return_url - ) - url = client.get_logout_url(CONF.ui_url) - self.redirect(url) diff --git a/cvp/opnfv_testapi/ui/auth/user.py b/cvp/opnfv_testapi/ui/auth/user.py deleted file mode 100644 index a695da45..00000000 --- a/cvp/opnfv_testapi/ui/auth/user.py +++ /dev/null @@ -1,35 +0,0 @@ -############################################################################## -# Copyright (c) 2015 Orange -# guyrodrigue.koffi@orange.com / koffirodrigue@gmail.com -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - -from tornado import gen -from tornado import web - -from opnfv_testapi.common import raises -from opnfv_testapi.db import api as dbapi -from opnfv_testapi.ui.auth import base - - -class ProfileHandler(base.BaseHandler): - @web.asynchronous - @gen.coroutine - def get(self): - openid = self.get_secure_cookie('openid') - if openid: - try: - user = yield dbapi.db_find_one(self.table, {'openid': openid}) - self.finish_request({ - "openid": user.get('openid'), - "email": user.get('email'), - "fullname": user.get('fullname'), - "role": user.get('role', 'user'), - "type": self.get_secure_cookie('signin_type') - }) - except Exception: - pass - raises.Unauthorized('Unauthorized') diff --git a/cvp/opnfv_testapi/ui/root.py b/cvp/opnfv_testapi/ui/root.py deleted file mode 100644 index 5b2c922d..00000000 --- a/cvp/opnfv_testapi/ui/root.py +++ /dev/null @@ -1,10 +0,0 @@ -from opnfv_testapi.resources.handlers import GenericApiHandler -from opnfv_testapi.common.config import CONF - - -class RootHandler(GenericApiHandler): - def get_template_path(self): - return CONF.static_path - - def get(self): - self.render('testapi-ui/index.html') -- cgit 1.2.3-korg