def check_if_auth_exists(_id): """ This method checks if a record exists in TalentbotAuth table against an id :param int|long _id: TalentbotAuth id :rtype: type (x) """ requested_auth_object = TalentbotAuth.get_by_id(_id) if id else None if not requested_auth_object: raise NotFoundError("No talentbot_auth exists against id: %d" % _id) return requested_auth_object
def save_talentbot_auth(kwargs): """ This method takes dict object of TalentbotAuth and saves in database :param dict kwargs: TalentbotAuth dict object :rtype: type (y) """ try: auth = TalentbotAuth(**kwargs) response_object = auth.save() return ApiResponse({"id": response_object.id}) except Exception as error: logger.error("Error occurred while saving talentbot auth Error: %s" % error.message) return ApiResponse( { "error": { "message": "Oops! something went wrong while saving talentbot auth" } }, status=500)
def delete(self, **kwargs): """ The method deletes record against id Example: make a get request to /v1/auth/30[DELETE] headers = { 'Authorization': 'Bearer <access_token>', 'Content-Type': 'application/json' } .. Response { "talentbot_auth_id": 2 } """ # Checking if user has permission to delete specific record _id = kwargs.get('id') requested_auth_object = check_if_auth_exists(_id) if requested_auth_object.user_id == request.user.id or request.user.role.id == 2: TalentbotAuth.delete(requested_auth_object) return ApiResponse({"talentbot_auth_id": requested_auth_object.id}) raise ForbiddenError("You don't have permission to delete this record")
def validate_and_format_request_data_for_facebook(data): """ Validates and formats request data related to Facebook :param dict data: Request data :rtype: dict """ facebook_user_id = data.get('facebook_user_id') if not facebook_user_id: raise InvalidUsage("No facebook_user_id provided") tb_auth = TalentbotAuth.get_talentbot_auth( facebook_user_id=facebook_user_id) if tb_auth: raise InvalidUsage("facebook_user_id already exists") return {"facebook_user_id": facebook_user_id.strip()}
def authenticate_user(self, mobile_number): """ Authenticates user :rtype: tuple(bool, int) :return: is_authenticated, user Id """ user_phone_id = UserPhone.get_by_phone_value(mobile_number) if user_phone_id: user_ids = TalentbotAuth.get_user_id(user_phone_id=user_phone_id[0].id) if user_ids: user = User.get_by_id(user_ids[0]) if user.is_disabled: is_authenticated, user_id = True, None return is_authenticated, user_id is_authenticated = True return is_authenticated, user_ids[0] is_authenticated, user_id = False, None return is_authenticated, user_id
def authenticate_user(self, slack_user_id, message, channel_id): """ Authenticates user :param str slack_user_id: User's slack Id :param str message: User's message :param str channel_id: Slack channel Id :rtype: tuple (True|False, None|str, None|Slack_client, TalentbotAuth.slack_user_id|None) :return: is_authenticated, user message with bot id stripped, slack_client, user_id """ talentbot_auth = TalentbotAuth.get_talentbot_auth( slack_user_id=slack_user_id) if talentbot_auth: slack_user_token = talentbot_auth.bot_token user_id = talentbot_auth.user_id if slack_user_token and user_id: slack_client = SlackClient(slack_user_token) user = User.get_by_id(user_id) if user.is_disabled: is_authenticated, user_id = True, None return is_authenticated, message, slack_client, user_id try: if talentbot_auth.bot_id: at_bot = '<@%s>' % talentbot_auth.bot_id presence = slack_client.api_call('users.getPresence') if not presence.get('online'): self.set_bot_state_active(talentbot_auth.bot_token) else: at_bot = self.get_bot_id(slack_client) except NotFoundError as error: logger.error(error.message) is_authenticated, slack_client, user_id = False, None, None return is_authenticated, message, slack_client, user_id # Slack channel Id starts with 'C' if it is a channel and # Start's with 'D' if it's a private message is_channel = channel_id[0] == 'C' is_private_message = channel_id[0] == 'D' at_bot_colon = '%s:' % at_bot if (at_bot in message or at_bot_colon in message and is_channel) \ or (is_private_message and slack_user_id != at_bot): return True, message.replace(at_bot, ''), slack_client, user_id logger.info("Not authenticated") is_authenticated, slack_client, user_id = False, None, None return is_authenticated, message, slack_client, user_id
def validate_and_format_data_for_email(data): """ Validates and formats request data related to Email :param dict data: Request data :return: dictionary of formatted data :rtype: dict """ email = data.get("email") if not email: raise InvalidUsage("No email specified") is_valid_email = re.search( r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9]+\.[a-zA-Z0-9.]*\.*[com|org|edu]{3}$)", email) if not is_valid_email: raise InvalidUsage("Invalid email") tb_auth = TalentbotAuth.get_talentbot_auth(email=email) if tb_auth: raise InvalidUsage("email already exists") return {"email": email.strip().lower()}
def authenticate_user(self, email_id, subject, email_body): """ Authenticates user and remove secret email token from message body :param str email_id: User Email Id :param str subject: Received Email subject :param str email_body: Received Email body :rtype: tuple (True|False, str|None, int|None) :return: is_authenticated, email_body, user Id """ user_id = TalentbotAuth.get_user_id(email=email_id) if user_id: user = User.get_by_id(user_id[0]) if user.is_disabled: is_authenticated, user_id = True, None return is_authenticated, email_body, user_id is_authenticated = True return is_authenticated, email_body, user_id[0] is_authenticated, user_id = False, None return is_authenticated, email_body, user_id
def empty_users_state(): """ This method removes saved users' states from redis db to avoid deadlocks """ # Getting registered user phone ids user_phone_ids = TalentbotAuth.get_all_user_phone_ids() # Getting first entry of tuples user_phone_ids = list(*zip(*user_phone_ids)) # Removing None from list user_phone_ids = filter(partial(is_not, None), user_phone_ids) """ If there is no user_phone_id available in table we get [None], that's why I'm comparing user_phone_ids[0] instead of user_phone_ids because [None] != [] """ if user_phone_ids: # Getting user ids against registered users' phone ids user_ids = UserPhone.get_user_ids_by_phone_ids(user_phone_ids) # Extracting data from tuple user_ids = list(*zip(*user_ids)) for user_id in user_ids: redis_store.delete("bot-pg-%d" % user_id) redis_store.delete("%dredis_lock" % user_id) logger.info("Flushed user states successfully")
def validate_and_format_request_data_for_sms(data, user_id): """ Validates and formats request data related to SMS :param int|long user_id: User Id :param dict data: Request data :return: dictionary of formatted data :rtype: dict """ user_phone_id = data.get('user_phone_id') user_phone = data.get('user_phone') if not bool(user_phone) ^ bool( user_phone_id): # Only one field must exist XNOR raise InvalidUsage( "One field should be provided either user_phone or user_phone_id") if user_phone_id: if not isinstance(user_phone_id, (int, long)): raise InvalidUsage("Invalid user_phone_id type") phone = UserPhone.get_by_id(user_phone_id) if not phone: raise InvalidUsage( "No resource found against specified user_phone_id") if phone.user_id != user_id: raise ForbiddenError( "user_phone against provided user_phone_id is not owned by you" ) tb_auth = TalentbotAuth.get_talentbot_auth(user_phone_id=user_phone_id) if tb_auth: raise InvalidUsage("user_phone_id is already being used") if user_phone: if not isinstance(user_phone, basestring): raise InvalidUsage("Invalid user_phone type") return { "user_phone": user_phone.strip() } if user_phone else { "user_phone_id": user_phone_id }
def get_new_user_credentials(): """ Receives user data when he installs talentbot on slack and saves in db :rtype: str """ code = request.args.get('code') client_id = app.config['SLACK_APP_CLIENT_ID'] client_secret = app.config['SLACK_APP_CLIENT_SECRET'] response = send_request('POST', SLACK_AUTH_URI, access_token=None, params={ 'client_id': client_id, 'client_secret': client_secret, 'code': code }) json_result = response.json() if json_result.get('ok'): access_token = json_result['access_token'] team_id = json_result['team_id'] team_name = json_result['team_name'] user_id = json_result['user_id'] auth_entry = TalentbotAuth.query.filter_by( slack_user_id=user_id).first() bot_id = json_result['bot']['bot_user_id'] bot_token = json_result['bot']['bot_access_token'] if not auth_entry: talent_bot_auth = TalentbotAuth(slack_user_token=access_token, slack_team_id=team_id, slack_user_id=user_id, slack_team_name=team_name, bot_id=bot_id, bot_token=bot_token) talent_bot_auth.save() return "Your Slack credentials have been saved" auth_entry.slack_user_token = access_token auth_entry.bot_id = bot_id auth_entry.bot_token = bot_token TalentbotAuth.save(auth_entry) return "Your slack token has been updated" return "Your slack id already exists"