airavata-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From machris...@apache.org
Subject [airavata-custos] 18/24: added the functionality to load server configuration from ini file
Date Fri, 11 Oct 2019 20:42:25 GMT
This is an automated email from the ASF dual-hosted git repository.

machristie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/airavata-custos.git

commit 7d3e8c8c18916e28d1776bf4a1ed470ad3ee34f2
Author: Aarushi <aarushiibisht@gmail.com>
AuthorDate: Tue Sep 17 12:22:01 2019 -0400

    added the functionality to load server configuration from ini file
---
 .../airavata_custos/admin/iam_admin_client.py      | 244 +++++++++++----------
 clients/python/airavata_custos/sample_settings.ini |  10 +
 .../security/custos_authorization_token.py         |  43 ----
 .../security/keycloak_connectors.py                |  78 +++++--
 clients/python/airavata_custos/settings.py         |  30 ++-
 clients/python/airavata_custos/utils.py            |  20 +-
 clients/python/requirements_dev.txt                |   3 +-
 7 files changed, 228 insertions(+), 200 deletions(-)

diff --git a/clients/python/airavata_custos/admin/iam_admin_client.py b/clients/python/airavata_custos/admin/iam_admin_client.py
index ee9c11b..f72df76 100644
--- a/clients/python/airavata_custos/admin/iam_admin_client.py
+++ b/clients/python/airavata_custos/admin/iam_admin_client.py
@@ -16,123 +16,135 @@
 #
 
 import logging
-from airavata_custos.utils import iamadmin_client_pool
+import configparser
+from airavata_custos import utils
+from airavata_custos.settings import ProfileSettings
 
 logger = logging.getLogger(__name__)
 
 
-def is_username_available(authz_token, username):
-    """
-    This method validates if the username is available or not
-    :param authz_token: Object of AuthzToken class containing access token, username, gatewayId
of the active user
-    :param username: The username whose availability needs to be verified
-    :return: boolean
-    """
-    return iamadmin_client_pool.isUsernameAvailable(authz_token, username)
-
-
-def register_user(authz_token, username, email_address, first_name, last_name, password):
-    """
-    This method registers the user with the keycloak instance returns true if successful,
false if the registration fails
-    :param authz_token: Object of AuthzToken class containing access token, username, gatewayId
of the active user
-    :param username: The username of the user that needs to be registered
-    :param email_address: The email address of the user that needs to be registered
-    :param first_name: The first name of the user that needs to be registered
-    :param last_name: The last name of the user that needs to be registered
-    :param password: The password of the user that needs to be registered
-    :return: boolean
-    """
-    return iamadmin_client_pool.registerUser(
-        authz_token,
-        username,
-        email_address,
-        first_name,
-        last_name,
-        password)
-
-
-def is_user_enabled(authz_token, username):
-    """
-    Checks the user is enabled/disabled in keycloak. Only the enabled user can login
-    :param authz_token: Object of AuthzToken class containing access token, username, gatewayId
of the active user
-    :param username: The username of the user
-    :return: boolean
-    """
-    return iamadmin_client_pool.isUserEnabled(authz_token, username)
-
-
-def enable_user(authz_token, username):
-    """
-    The method to enable a disabled user
-    :param authz_token: Object of AuthzToken class containing access token, username, gatewayId
of the active user
-    :param username: The username of the user
-    :return: Object of UserProfile class, containing user details
-    """
-    return iamadmin_client_pool.enableUser(authz_token, username)
-
-
-def delete_user(authz_token, username):
-    """
-    This method deleted the user from keycloak. Returns true if delete is successful
-    :param authz_token: Object of AuthzToken class containing access token, username, gatewayId
of the active user
-    :param username: The username of the user
-    :return: boolean
-    """
-    return iamadmin_client_pool.deleteUser(authz_token, username)
-
-
-def is_user_exist(authz_token, username):
-    """
-    This method checks if the user exists in keycloak. Returns true if the user exists otherwise
returns false
-    :param authz_token: Object of AuthzToken class containing access token, username, gatewayId
of the active user
-    :param username: The username of the user
-    :return: boolean
-    """
-    try:
-        return iamadmin_client_pool.isUserExist(authz_token, username)
-    except Exception:
-        return None
-
-
-def get_user(authz_token, username):
-    """
-
-    :param authz_token: Object of AuthzToken class containing access token, username, gatewayId
of the active user
-    :param username: username of the user
-    :return: object of class UserProfile
-    """
-    try:
-        return iamadmin_client_pool.getUser(authz_token, username)
-    except Exception:
-        return None
-
-
-def get_users(authz_token, offset=0, limit=-1, search=None):
-    """
-
-    :param authz_token: Object of AuthzToken class containing access token, username, gatewayId
of the active user
-    :param offset: start index
-    :param limit: end index
-    :param search: search criteria for filtering users
-    :return: list of UserProfile class objects
-    """
-    try:
-        return iamadmin_client_pool.getUsers(authz_token, offset, limit, search)
-    except Exception:
-        return None
-
-
-def reset_user_password(authz_token, username, new_password):
-    """
-
-    :param authz_token: Object of AuthzToken class containing access token, username, gatewayId
of the active user
-    :param username: username of the user
-    :param new_password: new password for the user
-    :return:
-    """
-    try:
-        return iamadmin_client_pool.resetUserPassword(
-            authz_token, username, new_password)
-    except Exception:
-        return None
-
+class IAMAdminClient(object):
+
+    def __init__(self, configuration_file_location):
+        """
+        constructor for IAMAdminClient class
+        :param configuration_file_location: takes the location of the ini file containing
server configuration
+        """
+        self.profile_settings = ProfileSettings()
+        self._load_settings(configuration_file_location)
+        self.iamadmin_client_pool = utils.initialize_iamadmin_client_pool(self.profile_settings.PROFILE_SERVICE_HOST,
+                                                                          self.profile_settings.PROFILE_SERVICE_PORT)
+
+    def is_username_available(self, authz_token, username):
+        """
+        This method validates if the username is available or not
+        :param authz_token: Object of AuthzToken class containing access token, username,
gatewayId of the active user
+        :param username: The username whose availability needs to be verified
+        :return: boolean
+        """
+        return self.iamadmin_client_pool.isUsernameAvailable(authz_token, username)
+
+    def register_user(self, authz_token, username, email_address, first_name, last_name,
password):
+        """
+        This method registers the user with the keycloak instance returns true if successful,
false if the registration fails
+        :param authz_token: Object of AuthzToken class containing access token, username,
gatewayId of the active user
+        :param username: The username of the user that needs to be registered
+        :param email_address: The email address of the user that needs to be registered
+        :param first_name: The first name of the user that needs to be registered
+        :param last_name: The last name of the user that needs to be registered
+        :param password: The password of the user that needs to be registered
+        :return: boolean
+        """
+        return self.iamadmin_client_pool.registerUser(
+            authz_token,
+            username,
+            email_address,
+            first_name,
+            last_name,
+            password)
+
+    def is_user_enabled(self, authz_token, username):
+        """
+        Checks the user is enabled/disabled in keycloak. Only the enabled user can login
+        :param authz_token: Object of AuthzToken class containing access token, username,
gatewayId of the active user
+        :param username: The username of the user
+        :return: boolean
+        """
+        return self.iamadmin_client_pool.isUserEnabled(authz_token, username)
+
+    def enable_user(self, authz_token, username):
+        """
+        The method to enable a disabled user
+        :param authz_token: Object of AuthzToken class containing access token, username,
gatewayId of the active user
+        :param username: The username of the user
+        :return: Object of UserProfile class, containing user details
+        """
+        return self.iamadmin_client_pool.enableUser(authz_token, username)
+
+    def delete_user(self, authz_token, username):
+        """
+        This method deleted the user from keycloak. Returns true if delete is successful
+        :param authz_token: Object of AuthzToken class containing access token, username,
gatewayId of the active user
+        :param username: The username of the user
+        :return: boolean
+        """
+        return self.iamadmin_client_pool.deleteUser(authz_token, username)
+
+    def is_user_exist(self, authz_token, username):
+        """
+        This method checks if the user exists in keycloak. Returns true if the user exists
otherwise returns false
+        :param authz_token: Object of AuthzToken class containing access token, username,
gatewayId of the active user
+        :param username: The username of the user
+        :return: boolean
+        """
+        try:
+            return self.iamadmin_client_pool.isUserExist(authz_token, username)
+        except Exception:
+            return None
+
+    def get_user(self, authz_token, username):
+        """
+
+        :param authz_token: Object of AuthzToken class containing access token, username,
gatewayId of the active user
+        :param username: username of the user
+        :return: object of class UserProfile
+        """
+        try:
+            return self.iamadmin_client_pool.getUser(authz_token, username)
+        except Exception:
+            return None
+
+    def get_users(self, authz_token, offset=0, limit=-1, search=None):
+        """
+
+        :param authz_token: Object of AuthzToken class containing access token, username,
gatewayId of the active user
+        :param offset: start index
+        :param limit: end index
+        :param search: search criteria for filtering users
+        :return: list of UserProfile class objects
+        """
+        try:
+            return self.iamadmin_client_pool.getUsers(authz_token, offset, limit, search)
+        except Exception:
+            return None
+
+    def reset_user_password(self, authz_token, username, new_password):
+        """
+
+        :param authz_token: Object of AuthzToken class containing access token, username,
gatewayId of the active user
+        :param username: username of the user
+        :param new_password: new password for the user
+        :return:
+        """
+        try:
+            return self.iamadmin_client_pool.resetUserPassword(
+                authz_token, username, new_password)
+        except Exception:
+            return None
+
+    def _load_settings(self, configuration_file_location):
+        config = configparser.ConfigParser()
+        config.read(configuration_file_location)
+        settings = config['ProfileServerSettings']
+        self.profile_settings.PROFILE_SERVICE_HOST = settings['PROFILE_SERVICE_HOST']
+        self.profile_settings.PROFILE_SERVICE_PORT = settings['PROFILE_SERVICE_PORT']
diff --git a/clients/python/airavata_custos/sample_settings.ini b/clients/python/airavata_custos/sample_settings.ini
new file mode 100644
index 0000000..c9a1e1c
--- /dev/null
+++ b/clients/python/airavata_custos/sample_settings.ini
@@ -0,0 +1,10 @@
+[IAMSeverSettings]
+KEYCLOAK_AUTHORIZE_URL = https://localhost:8443/auth/realms/default/protocol/openid-connect/auth
+KEYCLOAK_TOKEN_URL = https://localhost:8443/auth/realms/default/protocol/openid-connect/token
+KEYCLOAK_USERINFO_URL = https://localhost:8443/auth/realms/default/protocol/openid-connect/userinfo
+KEYCLOAK_LOGOUT_URL = https://localhost:8443/auth/realms/default/protocol/openid-connect/logout
+VERIFY_SSL = no
+
+[ProfileServerSettings]
+PROFILE_SERVICE_HOST = '0.0.0.0'
+PROFILE_SERVICE_PORT = '8081'
\ No newline at end of file
diff --git a/clients/python/airavata_custos/security/custos_authorization_token.py b/clients/python/airavata_custos/security/custos_authorization_token.py
deleted file mode 100644
index dd4b531..0000000
--- a/clients/python/airavata_custos/security/custos_authorization_token.py
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-from airavata_custos import settings
-from oauthlib.oauth2 import BackendApplicationClient
-from requests_oauthlib import OAuth2Session
-from custos.commons.model.security.ttypes import AuthzToken
-
-
-def get_authorization_token(client_credentials, tenant_id, username=None):
-    """
-    This method created a authorization token for the user or a service account
-    In case of a service account username will be null
-    :param client_credentials: object of class client_credentials
-    :param tenant_id: gateway id of the client
-    :param username: username of the user for which authorization token is being created
-    :return: AuthzToken
-    """
-    client = BackendApplicationClient(client_id=client_credentials.client_id)
-    oauth = OAuth2Session(client=client)
-    token = oauth.fetch_token(
-        token_url=settings.token_url,
-        client_id=client_credentials.client_id,
-        client_secret=client_credentials.client_secret,
-        verify=client_credentials.verify_ssl)
-
-    access_token = token.get('access_token')
-    return AuthzToken(
-        accessToken=access_token,
-        claimsMap={'gatewayID': tenant_id, 'userName': username})
diff --git a/clients/python/airavata_custos/security/keycloak_connectors.py b/clients/python/airavata_custos/security/keycloak_connectors.py
index d31e5a8..05816c2 100644
--- a/clients/python/airavata_custos/security/keycloak_connectors.py
+++ b/clients/python/airavata_custos/security/keycloak_connectors.py
@@ -16,13 +16,24 @@
 #
 import time
 from oauthlib.oauth2 import LegacyApplicationClient
-from requests_oauthlib import OAuth2Session
 import requests
-from airavata_custos import settings
+import configparser
+from airavata_custos.settings import IAMSettings
+from oauthlib.oauth2 import BackendApplicationClient
+from requests_oauthlib import OAuth2Session
+from custos.commons.model.security.ttypes import AuthzToken
 
 
 class KeycloakBackend(object):
 
+    def __init__(self, configuration_file_location):
+        """
+        constructor for KeycloakBackend class
+        :param configuration_file_location: takes the location of the ini file containing
server configuration
+        """
+        self.keycloak_settings = IAMSettings()
+        self._load_settings(configuration_file_location)
+
     def authenticate_user(self, user_credentials):
         """
         Method to authenticate a gateway user with keycloak
@@ -60,42 +71,61 @@ class KeycloakBackend(object):
         except Exception as e:
             return None
 
-    @classmethod
-    def _get_token_and_user_info_password_flow(cls, client_credentials):
+    def _get_token_and_user_info_password_flow(self, client_credentials):
 
         oauth2_session = OAuth2Session(client=LegacyApplicationClient(client_id=client_credentials.client_id))
-        token = oauth2_session.fetch_token(token_url=settings.KEYCLOAK_TOKEN_URL,
+        token = oauth2_session.fetch_token(token_url=self.keycloak_settings.KEYCLOAK_TOKEN_URL,
                                            username=client_credentials.username,
                                            password=client_credentials.password,
                                            client_id=client_credentials.client_id,
                                            client_secret=client_credentials.client_secret,
-                                           verify=settings.VERIFY_SSL)
-        user_info = oauth2_session.get(settings.KEYCLOAK_USERINFO_URL).json()
-        return cls._process_token(token), cls._process_userinfo(user_info)
+                                           verify=self.keycloak_settings.VERIFY_SSL)
+        user_info = oauth2_session.get(self.keycloak_settings.KEYCLOAK_USERINFO_URL).json()
+        return self._process_token(token), self._process_userinfo(user_info)
 
-    @classmethod
-    def _get_token_and_user_info_redirect_flow(cls, client_credentials):
+    def _get_token_and_user_info_redirect_flow(self, client_credentials):
         oauth2_session = OAuth2Session(client_credentials.client_id,
                                        scope='openid',
                                        redirect_uri=client_credentials.redirect_uri,
                                        state=client_credentials.state)
-        token = oauth2_session.fetch_token(settings.KEYCLOAK_TOKEN_URL,
+        token = oauth2_session.fetch_token(self.keycloak_settings.KEYCLOAK_TOKEN_URL,
                                            client_secret=client_credentials.client_secret,
                                            authorization_response=client_credentials.authorization_code_url,
-                                           verify=settings.VERIFY_SSL)
-        user_info = oauth2_session.get(settings.KEYCLOAK_USERINFO_URL).json()
-        return cls._process_token(token), cls._process_userinfo(user_info)
+                                           verify=self.keycloak_settings.VERIFY_SSL)
+        user_info = oauth2_session.get(self.keycloak_settings.KEYCLOAK_USERINFO_URL).json()
+        return self._process_token(token), self._process_userinfo(user_info)
 
-    @classmethod
-    def _get_token_from_refresh_token(cls, client_credentials, refresh_token):
+    def _get_token_from_refresh_token(self, client_credentials, refresh_token):
 
         oauth2_session = OAuth2Session(client_credentials.client_id, scope='openid')
         auth = requests.auth.HTTPBasicAuth(client_credentials.client_id, client_credentials.client_secret)
-        token = oauth2_session.refresh_token(token_url=settings.KEYCLOAK_TOKEN_URL,
+        token = oauth2_session.refresh_token(token_url=self.keycloak_settings.KEYCLOAK_TOKEN_URL,
                                              refresh_token=refresh_token,
                                              auth=auth,
-                                             verify=settings.VERIFY_SSL)
-        return cls._process_token(token)
+                                             verify=self.keycloak_settings.VERIFY_SSL)
+        return self._process_token(token)
+
+    def get_authorization_token(self, client_credentials, tenant_id, username=None):
+        """
+        This method created a authorization token for the user or a service account
+        In case of a service account username will be null
+        :param client_credentials: object of class client_credentials
+        :param tenant_id: gateway id of the client
+        :param username: username of the user for which authorization token is being created
+        :return: AuthzToken
+        """
+        client = BackendApplicationClient(client_id=client_credentials.client_id)
+        oauth = OAuth2Session(client=client)
+        token = oauth.fetch_token(
+            token_url=self.keycloak_settings.token_url,
+            client_id=client_credentials.client_id,
+            client_secret=client_credentials.client_secret,
+            verify=client_credentials.verify_ssl)
+
+        access_token = token.get('access_token')
+        return AuthzToken(
+            accessToken=access_token,
+            claimsMap={'gatewayID': tenant_id, 'userName': username})
 
     @classmethod
     def _process_token(cls, token):
@@ -116,6 +146,16 @@ class KeycloakBackend(object):
         last_name = userinfo['family_name']
         return UserInfo(username, email, first_name, last_name)
 
+    def _load_settings(self, configuration_file_location):
+        config = configparser.ConfigParser()
+        config.read(configuration_file_location)
+        settings = config['IAMSeverSettings']
+        self.keycloak_settings.KEYCLOAK_AUTHORIZE_URL = settings['KEYCLOAK_AUTHORIZE_URL']
+        self.keycloak_settings.KEYCLOAK_LOGOUT_URL = settings['KEYCLOAK_LOGOUT_URL']
+        self.keycloak_settings.KEYCLOAK_TOKEN_URL = settings['KEYCLOAK_TOKEN_URL']
+        self.keycloak_settings.KEYCLOAK_USERINFO_URL = settings['KEYCLOAK_USERINFO_URL']
+        self.keycloak_settings.VERIFY_SSL = settings.getboolean('VERIFY_SSL')
+
 
 class Token(object):
 
diff --git a/clients/python/airavata_custos/settings.py b/clients/python/airavata_custos/settings.py
index 89a05ef..dc4d101 100644
--- a/clients/python/airavata_custos/settings.py
+++ b/clients/python/airavata_custos/settings.py
@@ -15,19 +15,25 @@
 # limitations under the License.
 #
 
-KEYCLOAK_AUTHORIZE_URL = 'https://localhost:8443/auth/realms/default/protocol/openid-connect/auth'
-KEYCLOAK_TOKEN_URL = 'https://localhost:8443/auth/realms/default/protocol/openid-connect/token'
-KEYCLOAK_USERINFO_URL = 'https://localhost:8443/auth/realms/default/protocol/openid-connect/userinfo'
-KEYCLOAK_LOGOUT_URL = 'https://localhost:8443/auth/realms/default/protocol/openid-connect/logout'
+
+class ProfileSettings(object):
+    # Profile Service Configuration
+
+    def __init__(self):
+        self.PROFILE_SERVICE_HOST = '0.0.0.0'
+        self.PROFILE_SERVICE_PORT = '8081'
+
+
+class IAMSettings(object):
+
+    def __init__(self):
+        self.KEYCLOAK_AUTHORIZE_URL = 'https://localhost:8443/auth/realms/default/protocol/openid-connect/auth'
+        self.KEYCLOAK_TOKEN_URL = 'https://localhost:8443/auth/realms/default/protocol/openid-connect/token'
+        self.KEYCLOAK_USERINFO_URL = 'https://localhost:8443/auth/realms/default/protocol/openid-connect/userinfo'
+        self.KEYCLOAK_LOGOUT_URL = 'https://localhost:8443/auth/realms/default/protocol/openid-connect/logout'
+        self.VERIFY_SSL = False
 
 # Seconds each connection in the pool is able to stay alive. If open connection
 # has lived longer than this period, it will be closed.
 # (https://github.com/Thriftpy/thrift_connector)
-THRIFT_CLIENT_POOL_KEEPALIVE = 5
-
-# Profile Service Configuration
-PROFILE_SERVICE_HOST = '0.0.0.0'
-PROFILE_SERVICE_PORT = '8081'
-PROFILE_SERVICE_SECURE = False
-
-VERIFY_SSL = False
+THRIFT_CLIENT_POOL_KEEPALIVE = 5
\ No newline at end of file
diff --git a/clients/python/airavata_custos/utils.py b/clients/python/airavata_custos/utils.py
index 17fdf59..e025077 100644
--- a/clients/python/airavata_custos/utils.py
+++ b/clients/python/airavata_custos/utils.py
@@ -21,8 +21,8 @@ from thrift.protocol import TBinaryProtocol
 from thrift.protocol.TMultiplexedProtocol import TMultiplexedProtocol
 from thrift.transport import TSocket, TSSLSocket, TTransport
 
-from airavata_custos import settings
 from custos.profile.iam.admin.services.cpi import IamAdminServices, constants
+from airavata_custos import settings
 
 log = logging.getLogger(__name__)
 
@@ -63,14 +63,16 @@ class CustomThriftClient(connection_pool.ThriftClient):
 class IAMAdminServiceThriftClient(MultiplexThriftClientMixin,
                                   CustomThriftClient):
     service_name = constants.IAM_ADMIN_SERVICES_CPI_NAME
-    secure = settings.PROFILE_SERVICE_SECURE
+    secure = True
 
 
-iamadmin_client_pool = connection_pool.ClientPool(
-    IamAdminServices,
-    settings.PROFILE_SERVICE_HOST,
-    settings.PROFILE_SERVICE_PORT,
-    connection_class=IAMAdminServiceThriftClient,
-    keepalive=settings.THRIFT_CLIENT_POOL_KEEPALIVE
-)
+def initialize_iamadmin_client_pool(host, port):
+    iamadmin_client_pool = connection_pool.ClientPool(
+        IamAdminServices,
+        host,
+        port,
+        connection_class=IAMAdminServiceThriftClient,
+        keepalive=settings.THRIFT_CLIENT_POOL_KEEPALIVE
+    )
+    return iamadmin_client_pool
 
diff --git a/clients/python/requirements_dev.txt b/clients/python/requirements_dev.txt
index 353a50e..e0209cb 100644
--- a/clients/python/requirements_dev.txt
+++ b/clients/python/requirements_dev.txt
@@ -15,4 +15,5 @@ oauthlib==3.1.0
 requests_oauthlib==1.2.0
 requests==2.22.0
 thrift_connector==0.24
-thrift==0.11.0
\ No newline at end of file
+thrift==0.11.0
+configparser==4.0.2


Mime
View raw message