Пример #1
0
    def _performCall(self, parameters):
        if self.mode == 'PPMS API':
            response = self._sendToAPI(parameters)
            # check if we got a proper response, i.e. HTTP status code == 200
            if not response.status_code == 200:
                raise Errors.APIError(True,
                                      False,
                                      msg='Error ' +
                                      str(response.status_code) +
                                      ': API didn\'t return a proper response')

            # check if there is some data in the response
            if response.text:
                return response.text
            else:
                raise Errors.APIError(False,
                                      True,
                                      msg='Empty response from API')

        elif self.mode == 'Proxy':
            response = self._sendToProxy(parameters)
            # the proxy may forward an exception or a proper response
            try:
                raise response
            except TypeError:
                return response
        else:
            raise Errors.FatalError(
                msg=
                'Unknown communication method, must be \'PPMS API\' or \'Proxy\''
            )
Пример #2
0
 def checkKeys(self, required_keys):
     for key in required_keys:
         try:
             _ = self.options[key]
         except KeyError:
             raise Errors.FatalError(key + ' was not found in ' +
                                     self.option_file)
Пример #3
0
    def _sendToProxy(self, param_dict):

        pickled_dict = pickle.dumps(param_dict, protocol=2)

        iv = Random.new().read(AES.block_size)

        AES_plainkey = self.SYSTEMoptions.getValue('AES_key').encode('utf8')
        AES_key = SHA256.new()
        AES_key.update(AES_plainkey)
        AES_key = AES_key.digest()

        encryptor = AES.new(AES_key, AES.MODE_CFB, iv)
        encrypted_dict = iv + encryptor.encrypt(pickled_dict)
        packed_dict = bytes(struct.pack('>I',
                                        len(encrypted_dict))) + encrypted_dict

        proxy_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            proxy_socket.connect(
                (self.SYSTEMoptions.getValue('proxy_address'),
                 int(self.SYSTEMoptions.getValue('API_port'))))
            proxy_socket.sendall(packed_dict)
        except socket.error as e:
            raise Errors.APIError(msg=e)

        # From here we handle the encrypted response from the proxy
        encrypted_call = self._receive_data(proxy_socket)
        proxy_socket.close()
        iv_response = encrypted_call[:AES.block_size]
        encrypted_response = encrypted_call[AES.block_size:]

        decryptor = AES.new(AES_key, AES.MODE_CFB, iv_response)
        decrypted_response = decryptor.decrypt(encrypted_response)

        # try to catch wrong AES-keys at unpickle step with KeyError
        try:
            response = pickle.loads(decrypted_response)
        except KeyError:
            raise Errors.APIError(
                msg='Unpickle step failed, probably AES-keys don\'t match')
        return response
Пример #4
0
    def __init__(self, mode, system_options=None):
        self.mode = mode

        # if we want to contact the Proxy, we need SystemOptions.txt for the AESkey and Proxy address:port
        if self.mode == 'Proxy':
            if system_options is not None:
                self.SYSTEMoptions = system_options
                required_keys = ('AES_key', 'proxy_address', 'API_port')
                self.SYSTEMoptions.checkKeys(required_keys)
            else:
                raise Errors.FatalError(
                    msg=
                    'SystemOptions info not provided, only direct API calls possible'
                )

        # if we want to contact the API directly, we need ProxyOptions for the APIkeys and URLs
        if self.mode == 'PPMS API':
            try:
                self.APIoptions = Options.OptionReader('ProxyOptions.txt')
            except:
                raise Errors.FatalError(
                    msg='ProxyOptions.txt is missing, only Proxy calls possible'
                )
Пример #5
0
 def setUserRight(self, system_id, user_login, user_right=None):
     valid_user_rights = ['A', 'N', 'S', 'D']
     if not user_right:
         user_right = 'A'
     if user_right not in valid_user_rights:
         raise Errors.APIError(
             "User right abbreviation not valid! Must be 'A', 'N', 'S' or 'D'"
         )
     parameters = {
         'action': 'setright',
         'id': str(system_id),
         'login': user_login,
         'type': user_right,
         'API_type': 'PUMAPI',
     }
     self._performCall(parameters)
Пример #6
0
    def _sendToAPI(self, parameters):

        header = {'Content-Type': 'application/x-www-form-urlencoded'}
        API_type = parameters.pop('API_type')

        if API_type == 'PUMAPI':
            parameters['apikey'] = self.APIoptions.getValue('PUMAPI_key')
            URL = self.APIoptions.getValue('PUMAPI_URL')
        elif API_type == 'API2':
            parameters['apikey'] = self.APIoptions.getValue('API2_key')
            URL = self.APIoptions.getValue('API2_URL')
        else:
            raise Errors.APIError(
                msg='Unknown API interface type, must be \'PUMAPI\' or \'API2\''
            )

        return requests.post(URL, headers=header, data=parameters)
Пример #7
0
    def __init__(self, file_name, required_keys=()):

        self.option_file = os.path.join(sys.path[0], file_name)

        try:
            with open(self.option_file, 'r') as f:
                content = f.readlines()
        except FileNotFoundError:
            raise Errors.FatalError(file_name + ' not found!')

        self.options = {}
        for line in content:
            if not (line.startswith('#') or line in ['\n', '\r\n']):
                single_option = line.strip('\r\n').split('=')
                self.options[single_option[0].strip(
                    ' ')] = single_option[1].strip(' ')

        self.checkKeys(required_keys)
Пример #8
0
 def getUserRights(self, login=None, system_id=None):
     if not (login or system_id):
         raise Errors.APIError(
             msg='User login or system id have to be specified!')
     if login:
         parameters = {
             'action': 'getuserrights',
             'login': login,
             'API_type': 'PUMAPI',
             'format': 'csv',
             'noheaders': 'true',
         }
     if system_id:
         parameters = {
             'action': 'getsysrights',
             'id': system_id,
             'API_type': 'PUMAPI',
             'format': 'csv',
             'noheaders': 'true',
         }
     return self._performCall(parameters).split()
Пример #9
0
    def getLastUsage(self, login=None, system_id=None):
        if not (login or system_id):
            raise Errors.APIError(
                msg='User login or system id have to be specified!')
        parameters = {
            'action': 'getuserexp',
            'API_type': 'PUMAPI',
            'format': 'json',
        }
        if login:
            parameters['login'] = login
        if system_id:
            parameters['id'] = system_id

        try:
            response_json = self._performCall(parameters)
        except Errors.APIError as e:
            if e.empty_response:
                response_json = '{}'
            else:
                raise e
        return json.loads(response_json)