Ejemplo n.º 1
0
class GetFriendsSession(POSTSession):
    def __init__(self, global_context):
        self._users_engine = UsersEngine(global_context)
        self._access_rules = global_context.access_rules
        self._params = Params()

    def _init_session_params(self, query):
        self._params.parse(query)

    def _run_session(self):
        # Check user credentials
        self._access_rules.check_can_view_private_info(self._params.user_token,
                                                       self._params.user_id)

        page = self._users_engine.get_friends(self._params.user_id,
                                              self._params.limit,
                                              self._params.cursor)
        relations = self._users_engine.get_relations_many(
            self._params.user_id, page.data)

        friends = list()
        # Retrieve aux data
        for i, user_id in enumerate(page.data):
            if relations[i] == None or not relations[i].is_friends:
                continue

            # FIXME use group request
            info = None
            try:
                info = self._users_engine.get_info(user_id)
            except:
                pass
            if info == None:
                logging.warning(
                    'Can\'t find user profile, id = {}'.format(user_id))
                continue

            profile = {
                'user_id': info.user_id,
                'facebook_user_id': info.facebook_user_id,
                'name': info.name,
                'username': info.username,
                'email': info.email,
                'twilio_channel': relations[i].twilio_channel
            }
            friends.append(profile)

        result = {
            'success': True,
            'data': friends,
            'paging': {
                'cursor': page.cursor_code,
                'has_next': page.has_next
            }
        }
        return result
class EMailAuthStage2Session(POSTSession):

    def __init__(self, global_context):
        self._auth_engine = AuthEngine()
        self._users_engine = UsersEngine(global_context)
        self._avatar_generator = global_context.avatar_generator
        self._params = Params()

    def _init_session_params(self, query):
        self._params.parse(query)

    def _run_session(self):
        email = self._auth_engine.auth_by_email_stage2(self._params.auth_code, self._params.auth_token)

        # Check user exists
        user_id = self._find_user(email)
        if user_id == None:
            user_id = self._create_new_user(email)

        result = {
            'success': True,
            'user_id': int(user_id),
            'user_token': AccessToken.make_encoded(user_id)
        }
        return result

    def _find_user(self, email):
        user_id = self._users_engine.external_to_local_id(email)
        if user_id == None:
            return None
        try:
            info = self._users_engine.get_info(user_id)
            return info.user_id
        except:
            return None

    # TODO: move into users_engine
    def _create_new_user(self, email):
        info = UserInfo()
        info.name = ''
        info.email = email

        # Generate user id
        info.user_id = self._users_engine.gen_user_id(info)

        logging.info('create new profile, email = {}, user_id = {}'.format(email, info.user_id))

        # Create profile
        self._users_engine.put_info(info)
        self._users_engine.put_external_link(info.user_id, email)

        picture = self._avatar_generator.generate(email)
        self._users_engine.put_picture(info.user_id, picture)

        return info.user_id
Ejemplo n.º 3
0
class MakeMessagingTokenSession(POSTSession):
    def __init__(self, global_context):
        self._users_engine = UsersEngine(global_context)
        self._twilio_connector = global_context.twilio_connector
        self._params = Params()

    def _init_session_params(self, query):
        self._params.parse(query)

    def _run_session(self):
        # Check user exists
        info = self._users_engine.get_info(self._params.user_id)

        token = self._twilio_connector.make_messaging_token(
            self._params.user_id, self._params.uuid)
        result = {'success': True, 'data': {'token': token}}
        return result
Ejemplo n.º 4
0
class UpdateProfileSession(POSTSession):
    def __init__(self, global_context):
        self._users_engine = UsersEngine(global_context)
        self._access_rules = global_context.access_rules
        self._params = Params()

    def _init_session_params(self, query):
        self._params.parse(query)

    def _run_session(self):
        user_id = self._params.user_token.user_id

        # Check user credentials
        self._access_rules.check_can_edit_user_info(self._params.user_token,
                                                    user_id)

        user_info = self._users_engine.get_info(user_id)
        if user_info == None:
            raise APILogicalError('User not found')

        info_updated = False
        if self._params.name != None:
            user_info.name = self._params.name
            info_updated = True
        if self._params.username != None:
            user_info.username = self._params.username
            info_updated = True
        if self._params.email != None:
            user_info.email = self._params.email
            info_updated = True
        if info_updated:
            self._users_engine.put_info(user_info)

        if self._params.meta_blob:
            self._users_engine.put_meta(user_id, self._params.meta_blob)

        if self._params.picture_blob != None:
            self._users_engine.put_picture(user_id, self._params.picture_blob)

        result = {'success': True, 'user_token': self._params.user_token_str}
        return result
Ejemplo n.º 5
0
class GetProfileSession(POSTSession):
    def __init__(self, global_context):
        self._users_engine = UsersEngine(global_context)
        self._params = Params()

    def _init_session_params(self, query):
        self._params.parse(query)

    def _run_session(self):
        info = self._users_engine.get_info(self._params.user_id)
        if info == None:
            raise APILogicalError('User not found')

        # TODO remove facebook_access_token from result
        result = {
            'user_id': info.user_id,
            'facebook_user_id': info.facebook_user_id,
            'facebook_access_token': info.facebook_access_token,
            'name': info.name,
            'username': info.username,
            'email': info.email
        }

        if 'meta_blob' in self._params.properties:
            result['meta_blob'] = self._users_engine.get_meta(
                self._params.user_id)

        if 'picture_blob' in self._params.properties:
            result['picture_blob'] = self._users_engine.get_picture(
                self._params.user_id)

        if 'friends' in self._params.properties:
            facebook_user_id = result['facebook_user_id']
            facebook_access_token = result['facebook_access_token']
            if facebook_user_id != None and facebook_access_token != None:
                result['friends'] = self._get_friends_fb(
                    info.user_id, facebook_user_id, facebook_access_token)
            else:
                result['friends'] = list()

        return result

    def _get_friends_fb(self, user_id, facebook_user_id,
                        facebook_access_token):
        logging.info(
            '_get_friends_fb: Retrieve friends from facebook, facebook_user_id = {}'
            .format(facebook_user_id))

        friends = list()
        next_page_uri = 'https://graph.facebook.com/{}/friends?access_token={}'.format(
            facebook_user_id, facebook_access_token)
        while next_page_uri:
            try:
                resp = requests.get(next_page_uri)
                # parse
                parsed = json.loads(resp.text)
                # take profiles
                data = parsed.get('data')
                for entry in data:
                    facebook_user_id = entry.get('id')

                    info = self._get_user_by_fb(facebook_user_id)
                    if info == None:
                        continue

                    profile = {
                        'user_id': info.user_id,
                        'facebook_user_id': info.facebook_user_id,
                        'name': info.name,
                        'username': info.username,
                        'email': info.email
                    }

                    relation = self._users_engine.get_relations_many(
                        user_id, [info.user_id])[0]
                    if relation != None:
                        profile['twilio_channel'] = relation.twilio_channel
                    else:
                        profile['twilio_channel'] = None

                    friends.append(profile)

                # next page
                paging = parsed.get('paging')
                if paging:
                    next_page_uri = paging.get('next')
                else:
                    next_page_uri = None
            except Exception as ex:
                logging.error(ex)
                raise

        logging.info('_get_friends_fb: Got {} entries'.format(len(friends)))
        return friends

    def _get_user_by_fb(self, facebook_user_id):
        user_id = self._users_engine.external_to_local_id(facebook_user_id)
        if user_id == None:
            logging.warning('Can\'t find user by facebook user id')

            info = UserInfo()
            info.user_id = self._gen_user_id(info)
            info.facebook_user_id = facebook_user_id

            # Create profile
            self._users_engine.put_info(info.user_id, info)
            self._users_engine.put_external_link(info.user_id,
                                                 facebook_user_id)
        else:
            info = self._users_engine.get_info(user_id)
        return info
class GetExternalFriendsSession(POSTSession):
    def __init__(self, global_context):
        self._users_engine = UsersEngine(global_context)
        self._access_rules = global_context.access_rules
        self._params = Params()

    def _init_session_params(self, query):
        self._params.parse(query)

    def _run_session(self):
        # Check user credentials
        self._access_rules.check_can_view_private_info(self._params.user_token,
                                                       self._params.user_id)

        info = self._users_engine.get_info(self._params.user_id)
        if info == None:
            raise APILogicalError('User {} not found'.format(
                self._params.user_id))

        friends = list()
        cursor = ''
        has_next = False

        if info.facebook_user_id != None and info.facebook_access_token != None:
            friends, cursor, has_next = self._get_fb_friends(
                info.facebook_user_id, info.facebook_access_token)

        result = {
            'success': True,
            'data': friends,
            'paging': {
                'cursor': cursor,
                'has_next': has_next
            }
        }
        return result

    def _get_fb_friends(self, facebook_user_id, facebook_access_token):
        friends = list()

        page_uri = 'https://graph.facebook.com/{}/friends?access_token={}&limit={}&after={}'.format(
            facebook_user_id, facebook_access_token, self._params.limit,
            self._params.cursor)
        try:
            resp = requests.get(page_uri)
            # parse
            parsed = json.loads(resp.text)
            # check errors
            error = parsed.get('error')
            if error != None:
                logging.error('Facebook error: {}'.format(
                    error.get('message')))
                raise Exception('Can\'t get data from Facebook')
            # take profiles
            data = parsed.get('data')

            profiles = list()
            external_ids = list()
            for entry in data:
                profile = {
                    'facebook_user_id': entry.get('id'),
                    'name': entry.get('name')
                }
                profiles.append(profile)
                external_ids.append(entry.get('id'))

            local_ids = self._users_engine.external_to_local_id_many(
                external_ids)
            for i in range(len(local_ids) - 1, -1, -1):
                if local_ids[i] == None:
                    del local_ids[i]
                    del profiles[i]
                profiles[i]['user_id'] = local_ids[i]

            check_result = self._users_engine.check_friends_many(
                self._params.user_id, local_ids)
            for i in range(len(check_result)):
                if not check_result[i]:
                    friends.append(profiles[i])

            # paging
            cursor, has_next = self._parse_paging(parsed.get('paging'))
        except Exception as ex:
            logging.error(ex)
            raise

        return (friends, cursor, has_next)

    def _parse_paging(self, paging):
        cursor = ''
        has_next = False

        if paging == None:
            return (cursor, has_next)

        cursors = paging.get('cursors')
        if cursors != None:
            cursor = cursors.get('after', '')

        if 'next' in paging:
            has_next = True

        return (cursor, has_next)
Ejemplo n.º 7
0
class FacebookAuthSession(POSTSession):
    def __init__(self, global_context):
        self._users_engine = UsersEngine(global_context)
        self._avatar_generator = global_context.avatar_generator
        self._facebook_profile_uri = 'https://graph.facebook.com/me'
        self._timeout_sec = 1
        self._params = Params()

    def _init_session_params(self, query):
        self._params.parse(query)

    def _run_session(self):
        facebook_prof = self._get_facebook_profile(self._params.access_token)
        facebook_user_id = facebook_prof['id']
        facebook_name = facebook_prof.get('name')

        # Check fb user id
        if self._params.facebook_user_id != facebook_user_id:
            raise Exception('facebook_user_id mismatch')

        # Check user exists
        user_id = self._find_user(facebook_user_id)
        if user_id == None:
            user_id = self._create_new_user(facebook_name, facebook_user_id,
                                            self._params.access_token)

        result = {
            'success': True,
            'user_token': AccessToken.make_encoded(user_id),
            'user_id': user_id
        }
        return result

    def _get_facebook_profile(self, access_token):
        url = '{}?access_token={}'.format(self._facebook_profile_uri,
                                          access_token)
        try:
            resp = requests.get(url, timeout=self._timeout_sec)
        except Exception as ex:
            logging.error(ex)
            raise Exception('Request to facebook failed')

        profile = json.loads(resp.text)
        if 'id' not in profile:
            logging.error('Facebook bad response: {}'.format(profile))
            raise Exception('Request to facebook failed. Bad response.')
        return profile

    def _find_user(self, facebook_user_id):
        user_id = self._users_engine.external_to_local_id(facebook_user_id)
        if user_id == None:
            return None
        try:
            info = self._users_engine.get_info(user_id)
            return info.user_id
        except:
            return None

    def _create_new_user(self, name, facebook_user_id, facebook_access_token):
        info = UserInfo()
        info.facebook_user_id = facebook_user_id
        info.facebook_access_token = facebook_access_token
        info.name = name

        # Generate user id
        info.user_id = self._users_engine.gen_user_id(info)

        # Create profile
        self._users_engine.put_info(info)
        self._users_engine.put_external_link(info.user_id, facebook_user_id)

        picture = self._avatar_generator.generate(name)
        self._users_engine.put_picture(info.user_id, picture)

        return info.user_id