"""Authentication for QA users.""" from enum import Enum from math import isnan from os import getenv from pymysql import connect from requests import get class GrassAuth(object): """Authentication with Grass.""" def __init__(self, user_type, user_id=None): """Create a connection to Grass. Args: user_id (str): id for vend contact / oa user to retrieve token for """ if not user_type: raise ValueError('UserType is required.') if not isinstance(user_type, UserType): raise TypeError('User Type must be a UserType Enum.') if user_type == UserType.WORKSTATION and user_id \ and not isnan(user_id): self.user_id = user_id elif user_type == UserType.WORKSTATION: raise ValueError( 'A valid user_id is required for a workstation token.') if user_type == UserType.OA and user_id and isnan(user_id): raise ValueError( 'A valid OA user_id is required for an OA token.') else: self.user_id = user_id self.db_user = getenv('QA_DB_USER') self.db_password = getenv('QA_DB_PASS') self.db_host = getenv('QA_DB_HOST') self.db_database = getenv('QA_DB_DATABASE') self.grass_host = getenv('QA_GRASS_HOST') self.user_type = user_type if not self.db_user: raise ValueError('QA_DB_USER is required.') if not self.db_password: raise ValueError('QA_DB_PASS is required.') if not self.db_host: raise ValueError('QA_DB_HOST is required.') if not self.db_database: raise ValueError('QA_DB_DATABASE is required.') if not self.grass_host: raise ValueError('QA_GRASS_HOST is required.') self.user_string = 'alw' if self.user_type == UserType.WORKSTATION \ else 'oa' @property def grass_token(self): """Grass token for given vendor_id. Returns: str: Session token from ows-grass """ if self.user_type == UserType.OA and not self.user_id: self._get_oa_user_id() self._get_oauth_token_and_client_id() self._get_session_token() return self.session_token def fetch_oauth_token(self): """Fetch a vector API OAuth token for the given user. Returns: str: The token. """ if self.user_type == UserType.OA and not self.user_id: self._get_oa_user_id() self._get_oauth_token_and_client_id() return self.fetched_oauth_token def _get_oa_user_id(self): """Get the OA User ID. Returns: str: The OA user_id for Grass """ query = """SELECT id FROM orchadmin_users WHERE login = 'automation_qa'""" connection = connect( host=self.db_host, user=self.db_user, password=self.db_password, db=self.db_database) try: cursor = connection.cursor() cursor.execute(query) result = cursor.fetchone() self.user_id = result[0] finally: cursor.close() connection.close() def _get_oauth_token_and_client_id(self): """Get oauth token and client id from reportsAR. Returns: str, str: The oauth_token and client_id """ connection = connect( host=self.db_host, user=self.db_user, passwd=self.db_password, db=self.db_database) query = """SELECT oauth_token, client_id FROM vectorapi_access_tokens WHERE user_id=%s AND user_type=%s""" try: cursor = connection.cursor() cursor.execute(query, (self.user_id, self.user_string)) result = cursor.fetchone() if not result: raise VectorAPIAccessTokenNotFound( 'Could not find a Vector API Access Token for ' 'User Type {} with an ID of {}'.format( self.user_type.name, self.user_id)) self.fetched_oauth_token = result[0] self.client_id = result[1] finally: cursor.close() connection.close() def _get_session_token(self): """Get session token from ows-grass.""" grass_params = '/?user={}:{}&token={}&client={}'.format( self.user_string, self.user_id, self.fetched_oauth_token, self.client_id) url = self.grass_host + grass_params self.session_token = get(url).json()['token'] class VectorAPIAccessTokenNotFound(Exception): """Raised when we can't find a Vector API Access Token.""" pass class UserType(Enum): """Enum to store different user types.""" WORKSTATION = 1 OA = 2