Пример #1
0
    def parse_schedule_at(self, val):
        """
        Tries to parse the schedule_at parameter and get the datetime value for scheduling
        :param val: schedule_at rest parameter
        :return: countdown in seconds or raising HTTPPreconditionFailed if parsing errored
        """

        if val is None:
            return 0
        else:
            # Do we have a ISO Date format ?
            try:
                schedule_at = datetime.strptime(val, '%Y-%m-%d %H:%M:%S')

                if schedule_at < datetime.now():
                    raise HTTPPreconditionFailed(
                        'Cannot schedule batch in past date',
                        "Invalid past date given: %s" % schedule_at)
            except ValueError:
                # Do we have Seconds format ?
                m = re.match("^(\d+)s$", val)
                if not m:
                    raise HTTPPreconditionFailed(
                        'Cannot parse scheduled_at value',
                        ("Got unknown format: %s, correct formats are "
                         "'YYYY-MM-DD mm:hh:ss' or number of seconds, "
                         "c.f. http://docs.jasminsms.com/en/latest/apis/rest")
                        % val)

                return int(m.group(1))
            else:
                return (schedule_at - datetime.now()).total_seconds()
Пример #2
0
 def raise_error(self,
                 error_code=None,
                 desc='Something went wrong in server'):
     if error_code and error_code != 500:
         if error_code == 401 or error_code == 403:
             redis_cli = Redis.get_redis_client()
             if redis_cli is not None:
                 access_token = redis_cli.delete('sheets_v4_access')
             else:
                 print('Redis client is not active')
         if error_code == 400:
             raise HTTPBadRequest(description=desc or '')
         elif error_code == 401:
             raise HTTPUnauthorized(description=desc or '')
         elif error_code == 403:
             raise HTTPForbidden(description=desc or '')
         elif error_code == 404:
             raise HTTPNotFound(description=desc or '')
         elif error_code == 409:
             raise HTTPConflict(description=desc or '')
         elif error_code == 412:
             raise HTTPPreconditionFailed(description=desc or '')
         elif error_code == 422:
             raise HTTPUnprocessableEntity(description=desc or '')
         elif error_code == 503:
             raise HTTPServiceUnavailable(description=desc or '')
         else:
             raise HTTPError(HTTP_400,
                             description=desc or '',
                             code=error_code)
     else:
         raise HTTPInternalServerError(description=desc or '')
Пример #3
0
    def on_post(self, req, resp, spreadsheet_id):
        sheet_range = req.get_param('range', required=True)
        try:
            req_body = json.load(req.bounded_stream)
            if 'values' in req_body and isinstance(
                    req_body['values'], list) and len(req_body['values']):
                dimensions = 'dimensions' in req_body and req_body[
                    'dimensions'] or 'ROWS'
                value_input = 'value_input_option' in req_body and req_body[
                    'value_input_option'] or 'USER_ENTERED'
                insert_option = 'insert_option' in req_body and req_body[
                    'insert_option'] or 'INSERT_ROWS'
                try:
                    spreadsheets = DataStore.get_sheet_instance()
                except Exception as e:
                    print('Datastore is not configured properly', e)
                    raise HTTPServiceUnavailable(
                        description='Datastore is not configured properly')

                def run():
                    sheet_body = {
                        "values": req_body['values'],
                        "majorDimension": dimensions
                    }
                    response = spreadsheets.values().append(
                        spreadsheetId=spreadsheet_id,
                        body=sheet_body,
                        range=sheet_range,
                        valueInputOption=value_input,
                        insertDataOption=insert_option).execute()
                    resp.body = json.dumps(
                        dict(
                            status='Success',
                            message='Successfully Inserted data into sheet',
                            spreadsheet_id=response['spreadsheetId'],
                        ))
                    resp.status = HTTP_201

                super().main(run)
            else:
                raise HTTPPreconditionFailed(
                    description=
                    'Values is a mandatory and must be valid for this request')
        except JSONDecodeError as err:
            print('Request body received', req.bounded_stream.read())
            print('Error while processing request', err)
            raise HTTPUnprocessableEntity(
                description='Cannot parse the body from the request')
        except (HTTPServiceUnavailable, HTTPPreconditionFailed,
                HTTPError) as err:
            raise err
        except Exception as e:
            print('Exception in creating sheet', e)
            raise HTTPInternalServerError(
                description='Something went wrong while creating sheet')
Пример #4
0
    def decode_request_data(self, request):
        """Decode the request stream and return a valid json"""

        try:
            request_data = request.stream.read()
            params = json.loads(request_data)
        except Exception as e:
            raise HTTPPreconditionFailed(
                'Cannot parse JSON data',
                'Got unparseable json data: %s' % request_data)
        else:
            return params
Пример #5
0
    def on_put(self, req, resp, spreadsheet_id):
        value_input = req.get_param('value_input_option',
                                    default='USER_ENTERED')
        try:
            req_body = json.load(req.bounded_stream)
            if 'data' in req_body and isinstance(
                    req_body['data'], list) and len(req_body['data']):
                try:
                    spreadsheets = DataStore.get_sheet_instance()
                except Exception as e:
                    print('Datastore is not configured properly', e)
                    raise HTTPServiceUnavailable(
                        description='Datastore is not configured properly')

                def run():
                    sheet_body = {
                        "data": req_body['data'],
                        "valueInputOption": value_input
                    }
                    response = spreadsheets.values().batchUpdate(
                        spreadsheetId=spreadsheet_id,
                        body=sheet_body).execute()
                    resp.body = json.dumps(
                        dict(
                            status='Success',
                            message=
                            'Successfully updated the data in the sheet',
                            spreadsheet_id=response['spreadsheetId'],
                        ))
                    resp.status = HTTP_200

                super().main(run)
            else:
                raise HTTPPreconditionFailed(
                    description=
                    'Data is a mandatory and must be valid for this request')
        except JSONDecodeError as err:
            print('Request body received', req.bounded_stream.read())
            print('Error while processing request', err)
            raise HTTPUnprocessableEntity(
                description='Cannot parse the body from the request')
        except (HTTPServiceUnavailable, HTTPPreconditionFailed,
                HTTPError) as err:
            raise err
        except Exception as e:
            print('Exception in updating sheet info', e)
            raise HTTPInternalServerError(
                description='Something went wrong while updating sheet')
Пример #6
0
 def on_post(self, req, resp, username):
     try:
         req_body = json.load(req.bounded_stream)
         if username and 'password' in req_body and len(
                 req_body['password']) > 5:
             redis_cli = super().redis_client
             if redis_cli is not None:
                 password = req_body['password']
                 api_key = super().generate_token(32)
                 access_token = super().generate_token(32)
                 hash_password = hashlib.pbkdf2_hmac(
                     'sha256',
                     password.encode('utf-8'),
                     api_key[8:32].encode('utf-8'),
                     100000,
                     dklen=128)
                 user_info = dict(username=username,
                                  password=hash_password.hex(),
                                  api_key=api_key)
                 access_info = dict(username=username,
                                    is_active=True,
                                    access_token=access_token)
                 try:
                     if not redis_cli.hexists('USERS', username):
                         redis_cli.hset('USERS', username,
                                        json.dumps(user_info))
                         redis_cli.hset('USERS_APIKEY', api_key,
                                        json.dumps(access_info))
                         redis_cli.set(access_token, api_key, ex=28800)
                         resp.status = HTTP_201
                         resp.body = json.dumps(
                             dict(status='Succcess',
                                  message='Successfully created the user',
                                  user=dict(api_key=api_key,
                                            access_token=access_token,
                                            username=username)))
                     else:
                         raise HTTPConflict(
                             description=
                             'User already exists with username {}'.format(
                                 username))
                 except HTTPConflict as err:
                     raise err
                 except Exception as err:
                     raise Exception(
                         'Something went wrong while executing redis commands',
                         err)
             else:
                 raise HTTPServiceUnavailable(
                     description='Data instances are not yet active')
         else:
             raise HTTPPreconditionFailed(
                 description=
                 'Username and password are mandatory and must be valid for this request'
             )
     except JSONDecodeError as err:
         print('Request body received', req.bounded_stream.read())
         print('Error while processing request', err)
         raise HTTPUnprocessableEntity(
             description='Cannot parse the body from the request')
     except (HTTPPreconditionFailed, HTTPServiceUnavailable,
             HTTPConflict) as err:
         raise err
     except Exception as e:
         print('Exception in creating user', e)
         raise HTTPInternalServerError(
             description='Something went wrong while creating user info')
Пример #7
0
    def on_post(self, request, response):
        """
        POST /secure/sendbatch request processing

        Note: Calls Jasmin http api /send resource
        """

        # Authentify user before proceeding
        status, _ = self.call_jasmin('balance',
                                     params={
                                         'username':
                                         request.context.get('username'),
                                         'password':
                                         request.context.get('password')
                                     })
        if status != 200:
            raise HTTPPreconditionFailed(
                'Authentication failed', "Authentication failed for user: %s" %
                request.context.get('username'))

        batch_id = uuid.uuid4()
        params = self.decode_request_data(request)
        config = {
            'throughput': http_throughput_per_worker,
            'smart_qos': smart_qos
        }

        # Batch scheduling
        countdown = self.parse_schedule_at(
            params.get('batch_config', {}).get('schedule_at', None))

        message_count = 0
        for _message_params in params.get('messages', {}):
            # Construct message params
            message_params = {
                'username': request.context.get('username'),
                'password': request.context.get('password')
            }
            message_params.update(params.get('globals', {}))
            message_params.update(_message_params)

            # Convert _ to -
            # Added for compliance with json encoding/decoding constraints on dev env like .Net
            _message_params = message_params.copy(
            )  # Avoid dictionary key changed error in python 3.8
            for k, v in _message_params.items():
                del (message_params[k])
                message_params[re.sub('_', '-', k)] = v

            del _message_params  # Unset the variable

            # Ignore message if these args are not found
            if 'to' not in message_params or ('content' not in message_params
                                              and 'hex-content'
                                              not in message_params):
                continue

            # Do we have multiple destinations for this message ?
            if isinstance(message_params.get('to', ''), list):
                to_list = message_params.get('to')
                for _to in to_list:
                    message_params['to'] = _to
                    if countdown == 0:
                        httpapi_send.delay(batch_id,
                                           params.get('batch_config', {}),
                                           message_params, config)
                    else:
                        httpapi_send.apply_async(args=[
                            batch_id,
                            params.get('batch_config', {}), message_params,
                            config
                        ],
                                                 countdown=countdown)
                    message_count += 1
            else:
                if countdown == 0:
                    httpapi_send.delay(batch_id,
                                       params.get('batch_config',
                                                  {}), message_params, config)
                else:
                    httpapi_send.apply_async(args=[
                        batch_id,
                        params.get('batch_config', {}), message_params, config
                    ],
                                             countdown=countdown)
                message_count += 1

        response.body = {
            'data': {
                "batchId": '%s' % batch_id,
                "messageCount": message_count
            }
        }
        if countdown > 0:
            response.body['data']['scheduled'] = '%ss' % countdown
Пример #8
0
 def on_post(self, req, resp, auth_type):
     if auth_type == 'login':
         try:
             req_body = json.load(req.bounded_stream)
             if 'username' in req_body and req_body[
                     'username'] and 'password' in req_body and len(
                         req_body['password']) > 5:
                 username = req_body['username']
                 redis_cli = super().redis_client
                 if redis_cli is not None:
                     user_info = redis_cli.hget('USERS', username)
                     if user_info is not None:
                         user_info = json.loads(user_info)
                         api_key = user_info['api_key']
                         hash_password = hashlib.pbkdf2_hmac(
                             'sha256',
                             req_body['password'].encode('utf-8'),
                             api_key[8:32].encode('utf-8'),
                             100000,
                             dklen=128)
                         if user_info['password'] == hash_password.hex():
                             access_info = redis_cli.hget(
                                 'USERS_APIKEY', api_key)
                             access_info = json.loads(access_info)
                             if access_info is not None and access_info[
                                     'is_active']:
                                 access_token = access_info['access_token']
                                 if not redis_cli.exists(access_token):
                                     access_token = super().generate_token(
                                         32)
                                     access_info[
                                         'access_token'] = access_token
                                     access_info = redis_cli.hset(
                                         'USERS_APIKEY', api_key,
                                         json.dumps(access_info))
                                 redis_cli.set(access_token,
                                               api_key,
                                               ex=28800)
                                 resp.status = HTTP_200
                                 resp.body = json.dumps(
                                     dict(status='Success',
                                          user=dict(
                                              api_key=api_key,
                                              access_token=access_token,
                                              username=username)))
                             else:
                                 raise HTTPNotAcceptable(
                                     description='User is not active')
                         else:
                             raise HTTPUnauthorized(
                                 description=
                                 'Username and password doesnot match')
                     else:
                         raise HTTPNotFound(
                             description='No user with username {}'.format(
                                 username))
                 else:
                     raise HTTPServiceUnavailable(
                         description='Data instances are not yet active')
             else:
                 raise HTTPPreconditionFailed(
                     description=
                     'Username and password are mandatory and must be valid for this request'
                 )
         except JSONDecodeError as err:
             print('Request body received', req.bounded_stream.read())
             print('Error while processing request', err)
             raise HTTPUnprocessableEntity(
                 description='Cannot parse the body from the request')
         except (HTTPPreconditionFailed, HTTPServiceUnavailable,
                 HTTPNotFound, HTTPUnauthorized, HTTPNotAcceptable) as err:
             raise err
         except Exception as e:
             print('Exception in signing in user', e)
             raise HTTPInternalServerError(
                 description='Something went wrong while creating user info'
             )
     elif auth_type == 'logout':
         try:
             api_key = req.get_header('Authorization')
             redis_cli = super().redis_client
             if redis_cli is not None:
                 access_info = redis_cli.hget('USERS_APIKEY', api_key)
                 access_info = json.loads(access_info)
                 access_token = access_info['access_token']
                 redis_cli.delete(access_token)
                 resp.status = HTTP_200
                 resp.body = json.dumps(
                     dict(status='Succcess',
                          message='Successfully signed out'))
             else:
                 raise HTTPServiceUnavailable(
                     description='Data instances are not yet active')
         except Exception as err:
             print('Exception while signing out', err)
             raise HTTPInternalServerError(
                 description='Something went wrong while signing out')
     else:
         raise HTTPBadRequest(description='The request is not valid')