def resetpasswordlink(self, user_payload): ''' This method is to reset the password of the user Takes the username Email is sent in response upon succesful authentication ''' update_email_api = '/?#/pages/update-password-page' reset_email_subject = "AMZOrbit: Reset password" session = Session() user_name = user_payload['user_name'] acc_user = session.query(Account).filter( Account.user_name == user_name).one_or_none() if acc_user: user_id = acc_user.user_id user = session.query(User).filter( User.user_id == user_id).one_or_none() session.commit() if user: info = 'Hello, <br/> Please follow the below link to reset your password. <br/> <br/>' tag_name = 'Reset Your Password' self.send_jwt_token( user, update_email_api, reset_email_subject, info, tag_name) return ('success', 'An Email is successfully sent', None) else: return ('error', 'Couldnot find an accout with the provided user name. Please enter a valid user name', None)
def user_email_validate(self, token): ''' This method is to validate the email ''' session = Session() # calling method to decode the token data = self.jwt_token_decode(token) # Extracting the user_id and tenant_id from the decoded data of the payload user_id = data['identity'] tenant_id = data['user_claims']['tenant_id'] user = session.query(User).filter( User.user_id == user_id).filter( User.tenant_id == tenant_id).one_or_none() if user is None: return ('error', 'Unable to verify the account, please request again', None) else: user.email_validation = True session.add(user) session.commit() return('success', 'E-mail is successfully validated', None)
def send_jwt_token(self, user, api, subject, info, tag_name): ''' send_jwt_token ''' logger.info('Progressing the process of sending jwt token') jwt_token = self.jwt_generate(user) user_id = user.user_id token = jwt_token['access_token'] session = Session() default_info = {'create_dt': datetime.utcnow(), 'update_dt': datetime.utcnow()} account_info = {'user_id': user_id, 'jwt_token': token} account_obj_info = {**account_info, **default_info} session.query(Account).filter( Account.user_id == user_id).update(account_obj_info) session.commit() link = '{0}{1}?digest={2}'.format( APP_IP, api, jwt_token['access_token']) # formating the e-mail email_context = self.email_formatting( subject, user.email_id, link, info, tag_name) # sending the e-mail self.send_email(email_context)
def password_update(self, account_payload): ''' This method is to update the password Needs to test yet ''' session = Session() user_id = account_payload['user_id'] acc_user = session.query(Account).filter( Account.user_id == user_id).one_or_none() if bcrypt.checkpw(account_payload['old_password'].encode('utf-8'), acc_user.password.encode('utf-8')): updated_pwd = bcrypt.hashpw( account_payload['new_password'].encode('utf-8'), bcrypt.gensalt(12)) default_info = {'create_dt': datetime.utcnow(), 'update_dt': datetime.utcnow()} account_info = {'user_id': user_id, 'password': updated_pwd} account_obj_info = {**account_info, **default_info} session.query(Account).filter( Account.user_id == user_id).update(account_obj_info) session.commit() logger.info( 'Password is sucessfully updated for the user with id {0}'.format(user_id)) return ('success', 'Password Successfully Updated', None) else: return ('error', 'Password Entered is Incorrect', None)
def status_count(self, tenant_id): ''' This method is to retrieve the healthy status count of the products for each tenant ''' session = Session() logger.debug( 'Product health status count is being retreived for the tenant {0}' .format(tenant_id)) total_count = session.query( func.count('*')).filter(Product.tenant_id == tenant_id).filter( Product.archive != True).all() healthy_count = session.query( func.count('*')).filter(Product.tenant_id == tenant_id).filter( Product.health_status == 'Healthy').filter( Product.archive != True).all() unhealthy_count = session.query( func.count('*')).filter(Product.tenant_id == tenant_id).filter( Product.health_status == 'Unhealthy').filter( Product.archive != True).all() session.commit() product_count = { 'total': total_count[0][0], 'healthy': healthy_count[0][0], 'unhealthy': unhealthy_count[0][0] } logger.debug( 'product healthy status count for the tenant {0} is {1}'.format( tenant_id, json.dumps(product_count))) return product_count
def authenticate_user(self, account_payload): ''' This method is to authenticate the user Takes the username and password. Validates the password with the existing password using bcrypt. Jwt token is sent in response upon succesful authentication ''' session = Session() user_name = account_payload['user_name'] password = account_payload['password'] acc_user = session.query(Account).filter( Account.user_name == user_name).one_or_none() session.commit() if acc_user: if bcrypt.checkpw( password.encode('utf-8'), acc_user.password.encode('utf-8')): jwt_token = self.jwt_generate(acc_user) logger.info( 'User info is validated the authentication is successful for the user {0}'.format(user_name)) return ('success', 'User Authentication Is Successful', jwt_token) else: logger.info( 'User info couldnot be validated for the user name {0}'.format(user_name)) return ('error', 'Either User Name or Password is Incorrect', None)
def update(self, user_payload): ''' This method is to update the user info ''' session = Session() user_payload['update_dt'] = datetime.utcnow() # calling method to remove transient variables user = user_from_dict(user_payload) if 'alert_preference' in user_payload: user_payload['alert_preference'] = json.dumps( user_payload['alert_preference']) session.query(User).filter( User.user_id == user.user_id).filter( User.tenant_id == user.tenant_id).update(user_payload) session.commit() updated_user = self.get(user.user_id, user.tenant_id) if updated_user[0] == 'error': logger.error('User info cant be updated as user with user_id {0} and tenant_id {1} doesnot exist '.format( user_payload['user_id'], user_payload['tenant_id'])) return ('error', 'User doesnt exist', None) return ('success', 'User Info Updated Sucessfully', updated_user[2])
def account_create(self, account_payload): ''' This method is to create the account for the user User name and password are manadatory ''' logger.info('an account is being created with the user name {0}'.format( account_payload['user_name'])) session = Session() account_exists = self.account_verify(account_payload['user_name']) default_info = {'create_dt': datetime.utcnow(), 'update_dt': datetime.utcnow()} hashed_pwd = bcrypt.hashpw( account_payload['password'].encode('utf-8'), bcrypt.gensalt(12)) account_info = {'user_name': account_payload['user_name'], 'password': hashed_pwd, 'user_id': account_payload['user_id'], 'tenant_id': account_payload['tenant_id']} account_obj_info = {**account_info, **default_info} account_obj = Account(**account_obj_info) if not account_exists: session.add(account_obj) session.commit() logger.info('An account is created for the user {0}'.format( account_obj.user_name)) else: logger.info('An account already exists with the user name {0}'.format( account_info['user_name'])) return ('error', 'An Account already exists for the user', None) return ('success', 'Account successfully created', None)
def addPayment(self, payload): ''' This method is for the payment information insertion. ''' session = Session() default_info = {'create_dt': datetime.utcnow(), 'update_dt': datetime.utcnow()} payment = payload['payment_payload'] subscription = payload['subscription'] plan_id = subscription['plan_id'] stripe_token = payment['id'] user_id = payment['user_id'] logger.info('Payment information is being added for the prospective user with the given user name {0}'.format( payment['card']['name'])) payment_payload = {'last4': payment['card']['last4'], 'brand': payment['card']['brand'], 'exp_month': payment['card']['exp_month'], 'exp_year': payment['card']['exp_year'], 'name': payment['card']['name'], 'stripe_token': payment['id'], 'user_id': payment['user_id']} payment_obj = {**payment_payload, **default_info} payment = Payment(**payment_obj) session.add(payment) plan = session.query(Subscription).filter( Subscription.id == plan_id).one_or_none() # logger.info('plan id is {0}'.format(plan.plan_id)) user = session.query(User).filter( User.user_id == user_id).one_or_none() user_email_id = user.email_id # stripe_token should be a source id customer_id = stripe.Customer.create( email=user_email_id, source=stripe_token, ) logger.info('customer id :{0} '.format(customer_id)) subscription = stripe.Subscription.create( customer=customer_id, items=[{'plan': plan.plan_id}], ) # update subscription_expiry to "valid" user.suscription_expiry = None user.subscription_id = plan.id session.add(user) session.commit() return ('success', 'Payment is Successful', None)
def jwt_token_refresh(self, user_id): ''' In progress ''' session = Session() acc_user = session.query(Account).filter( Account.user_name == user_id).one_or_none() jwt_token = self.jwt_generate(acc_user) session.commit() return jwt_token
def update(self, alert_payload, user_id, tenant_id): ''' This method is update the alert with the given info ''' session = Session() logger.debug('Updating the alerts') alert_payload['update_dt'] = datetime.utcnow() alert_payload['updated_by'] = int(user_id) alert = Alert(**alert_payload) session.query(Alert).filter(Alert.id == alert.id).filter( Alert.tenant_id == alert.tenant_id).update(alert_payload) session.commit() return 'Alert Status Updated'
def user_create(self, user_payload): ''' A method to create an user ''' session = Session() default_info = {'create_dt': datetime.utcnow(), 'update_dt': datetime.utcnow()} logger.info('User registration is in progress') user_obj = {**user_payload, **default_info} user = User(**user_obj) session.add(user) session.commit() return user
def search(self, criteria, tenant_id): ''' This method to retreive the alerts for a given tenant and product alert will be sent along with the product info ''' session = Session() logger.info( 'alerts are being retreived for the given tenant and product info') query = 'SELECT alert.*, product.title, product.image, product.asin FROM alert, product where alert.product_id = product.id' if (criteria != None and 'product_id' in criteria and criteria['product_id'] != None): query = query + ' and alert.product_id = ' + \ str(criteria['product_id']) if 'status' in criteria and (criteria['status'] != None): query = query + \ ' and alert.status ="{0}" '.format( str(criteria['status'])) query = query + ' and alert.tenant_id = ' + \ str(tenant_id) + ' order by alert.create_dt desc limit 100' alert = session.execute(query, {}) session.commit() alerts = [] for row in alert: alerts.append({ 'status': row.status, 'id': row.id, 'alert_type': row.alert_type, 'status': row.status, 'create_dt': str(row.create_dt), 'title': row.title, 'asin': row.asin, 'image': row.image, 'product_id': row.product_id, 'meat_data': row.meta_data, 'tenant_id': row.tenant_id }) return alerts
def update(self, product_payload, user_id, tenant_id): ''' This method is to update the product for each given user ''' session = Session() product_payload['update_dt'] = datetime.utcnow() product_payload['updated_by'] = int(user_id) product = Product(**product_payload) logger.info( 'The product {0} with user_id {1} and tenant_id {2} is being updated' .format(json.dumps(product_payload['asin']), user_id, tenant_id)) session.query(Product).filter(Product.id == product.id).filter( Product.tenant_id == int(tenant_id)).update(product_payload) session.commit() return self.get(product.id, tenant_id)
def tenant_create(self, tenant_name): ''' This method is to create the tenant. Tenant name can be null ''' session = Session() default_info = {'create_dt': datetime.utcnow(), 'update_dt': datetime.utcnow()} tenant_obj_info = {**{'tenant_name': tenant_name}, **default_info} tenant = Tenant(**tenant_obj_info) session.add(tenant) session.commit() logger.info( 'Tenant is created with the id {0}'.format(tenant.tenant_id)) return tenant.tenant_id
def get_subscription_plans(self, user_id): # def get(self,user_id,tenant_id): ''' This method retrieves the user info ''' payload = {} session = Session() # subscription = session.query(Subscription).filter(Subscription.tenant_id == tenant_id) plans = session.query(Subscription).all() session.commit() payload['plans'] = plans if plans is None: logger.error("no plans to show") return ('error', 'There are no Plans to', None) else: logger.info('Card info is retreived for the user_id {0} '.format( plans)) return ('success', 'plans Info Retrieved', payload)
def tenant_update(self, tenant_id, tenant_payload): ''' This method is to update the tenant ''' session = Session() logger.info('The tenant with the id {0} is being updated with the info {1} '.format( tenant_id, json.dumps(tenant_payload))) tenant_payload['update_dt'] = datetime.utcnow() if 'settings' in tenant_payload: tenant_payload['settings'] = json.dumps(tenant_payload['settings']) tenant = session.query(Tenant).filter(Tenant.tenant_id == tenant_id).update(tenant_payload) session.commit() tenant = self.tenant_get(tenant_id) return('success', 'Tenant Info Updated Successfully', tenant[2])
def search(self, criteria, tenant_id): ''' This method is to filter the products given any criteria As of now, it supports only filtering by tenant_id ''' session = Session() logger.info( 'The products for the tenant_id {0} are being retrieved'.format( tenant_id)) products = session.query(Product).filter( Product.archive != True).filter( Product.tenant_id == int(tenant_id)).all() session.commit() return products
def tenant_get(self, tenant_id): ''' This method is to retrieve the tenant info ''' session = Session() tenant = session.query(Tenant).filter(Tenant.tenant_id == tenant_id).one_or_none() session.commit() if tenant is None: logger.error( 'Tenant with the id {0} couldnt be found'.format(tenant_id)) return('error', 'Tenant could not be found', None) else: logger.info( 'Tenant info sucessfully retrived for the tenant {0}'.format(tenant_id)) return('success', 'Tenant Info Retrieved Successfully', tenant)
def get(self, user_id): # def get(self,user_id,tenant_id): ''' This method retrieves the user info ''' payload = {} session = Session() card = session.query(Payment).filter( Payment.user_id == user_id).one_or_none() # subscription = session.query(Subscription).filter(Subscription.tenant_id == tenant_id) session.commit() payload['cardDetails'] = card if card is None: logger.error('Card with user_id {0} doesnot exist'.format( user_id)) return ('error', 'Card doesnt exist', None) else: logger.info('Card info is retreived for the user_id {0} '.format( card)) return ('success', 'Card Info Retrieved', payload)
def scrape_limited(self, criteria): ''' This method is to Scrape Based on Criteria The product will be retrieved and sent to kafka by updating product info status ''' session = Session() products = session.query(Product).filter( Product.archive != True).filter( Product.tenant_id == int(criteria['tenant_id'])).filter( Product.id == int(criteria['id'])).all() for product in products: logger.info( 'The product {0} for the tenant {1} is being scrapped'.format( product.asin, product.tenant_id)) product.product_info_status = 'Verification In Progress' session.commit() for product in products: self.kafkaproducer_call(self.row2dict(product))
def delete(self, productId, tenant_id): ''' This method is delete the product for a given tenant The product archive status will be set to true rather than deleting the info ''' session = Session() logger.info( 'The product with product_id {0} and tenant_id {1} is being archived' .format(productId, tenant_id)) product_id = {'id': productId} product = Product(**product_id) product = session.query(Product).filter( Product.id == product.id).filter( Product.tenant_id == int(tenant_id)).one_or_none() product.archive = True session.add(product) session.commit()
def get(self, productId, tenant_id): ''' This method is to retrieve the product info for the given tenant ''' session = Session() logger.info( 'The product with product_id {0} and tenant_id {1} is being retrieved' .format(productId, tenant_id)) product = session.query(Product).filter( Product.id == productId).filter(Product.archive != True).filter( Product.tenant_id == int(tenant_id)).one_or_none() session.commit() if product == None: logger.error( 'The product with product_id {0} and tenant_id {1} doesnt exist' .format(productId, tenant_id)) return "Product Doesn't Exist" else: return product
def scrape_all(self): ''' This method is to send all the products for scrapping. All the products will be retrieved and sent to kafka que ''' session = Session() products = session.query(Product).filter(Product.archive != True).all() logger.debug( 'The products for scraping are retrived and being sent to kafka que' ) for product in products: product.product_info_status = 'Verification In Progress' session.commit() for product in products: logger.debug( 'The product {0} is being sent to kafka que for scraping'. format(product.asin)) self.kafkaproducer_call(self.row2dict(product))
def password_reset(self, user_payload): ''' This method is to reset the password of the user Takes the username and tokenn ''' session = Session() token = user_payload['token'] validation = self.validate_jwt_token(token) if (validation[0] == 'success'): jwt_token = None token = token['digest'] data = self.jwt_token_decode(token) user_id = data['identity'] tenant_id = data['user_claims']['tenant_id'] updated_pwd = bcrypt.hashpw( user_payload['new_password'].encode('utf-8'), bcrypt.gensalt(12)) default_info = {'create_dt': datetime.utcnow(), 'update_dt': datetime.utcnow()} # make the jwt token invalid account_info = {'user_id': user_id, 'password': updated_pwd, 'jwt_token': jwt_token} account_obj_info = {**account_info, **default_info} session.query(Account).filter( Account.user_id == user_id).filter( Account.tenant_id == tenant_id).update(account_obj_info) session.commit() logger.info( 'Password is sucessfully updated for the user with id {0}'.format(user_id)) return ('success', 'Password reset is Successful', None) else: return('error', ' The linked is not valided. Please request for a new reset link again', None)
def add(self, products): ''' This method is to add new product(s) in the db It checks if the products exists or archvied earlier. If archived, it sets the archive to false A few default attributes will be added Once the products are added, the product info will be sent to kafka que for further scraping ''' session = Session() product_list = [] ideal_state = {} added_products = [] existing_products = [] invalid_products = [] default_input = { 'health_status': 'Healthy', 'ideal_state': json.dumps(ideal_state), 'product_info_status': 'Pending Update', 'create_dt': datetime.utcnow(), 'created_by': products['user_id'], 'title': 'Hold Tight! We are Retrieving Product Info', 'archive': False, 'tenant_id': int(products['tenant_id']) } for product_info in products['products']: if len(product_info['asin'].strip()) == 10: default_input['uid'] = str(uuid.uuid1()) product_info['asin'] = product_info['asin'].strip() product_input = {**product_info, **default_input} product = Product(**product_input) instance = session.query(Product).filter( Product.asin == product.asin).filter( Product.tenant_id == int( products['tenant_id'])).one_or_none() archived_product = session.query(Product).filter( Product.asin == product.asin).filter( Product.tenant_id == int(products['tenant_id']) ).filter(Product.archive == True).one_or_none() if instance == None and archived_product == None: logger.debug( 'The product with asin {0} is being added'.format( product_info['asin'])) product_list.append(product) added_products.append({'asin': product_info['asin']}) elif archived_product != None: logger.debug( 'The product {0} is being retrieved from the archived state' .format(product_info['asin'])) archived_product.archive = False session.add(archived_product) else: logger.debug('The product {0} already exists'.format( product_info['asin'])) existing_products.append({ 'asin': product_info['asin'], 'message': 'This asin is already present so ignored' }) session.add_all(product_list) session.commit() else: logger.info('The given asin {0} is invalid'.format( product_info['asin'])) invalid_products.append({ 'asin': product_info['asin'], 'message': 'Invalid asin length' }) products_new = session.query(Product).filter( Product.product_info_status == 'Pending Update').filter( Product.archive != True).filter( Product.tenant_id == int(products['tenant_id'])).all() for instance in products_new: logger.info( 'The product {0} is added and being sent to kafka que for scraping' .format(instance.asin)) self.kafkaproducer_call(self.row2dict(instance)) # wait for 1-3 seconds for each product sleep(randint(1, 3)) status = { 'success': added_products, 'warning': existing_products, 'error': invalid_products } return status