예제 #1
0
def user_from_facebook_auth_response(auth_response, initial_user=None, is_test=False):
    if 'accessToken' in auth_response:
        facebook_access_token = auth_response['accessToken']
    else:
        facebook_access_token = auth_response
    fb_user = fb_user_from_facebook_access_token(facebook_access_token)
    facebook_id = fb_user['id']
    try:
        linked_facebook = LinkedFacebookAccount.objects.filter(facebook_id=facebook_id).select_related(
            'user__profile').first()
        if not linked_facebook:
            raise LinkedFacebookAccount.DoesNotExist()
        save_linked_facebook(linked_facebook.user, facebook_access_token, fb_user, linked_facebook=linked_facebook)
        user = linked_facebook.user
        location = initial_user and initial_user.get('location')
        if location:
            location_controller.update_profile_location(user.ap, location)
    except LinkedFacebookAccount.DoesNotExist:
        debug_logger.debug('LinkedFacebookAccount.DoesNotExist for facebook_id %s' % facebook_id)
        if 'email' not in fb_user:
            dev_msg = 'Facebook user has no email: %s' % json.dumps(fb_user)
            debug_logger.error(dev_msg)
            raise ShoutitBadRequest(message=FB_LINK_ERROR_EMAIL, developer_message=dev_msg)
        user = user_controller.auth_with_facebook(fb_user, initial_user, is_test)
        try:
            save_linked_facebook(user, facebook_access_token, fb_user)
        except (ValidationError, IntegrityError) as e:
            raise ShoutitBadRequest(message=FB_LINK_ERROR_TRY_AGAIN, developer_message=str(e))

    return user
예제 #2
0
def delete_linked_facebook_account(facebook_user_id):
    try:
        la = LinkedFacebookAccount.objects.get(facebook_id=facebook_user_id)
    except LinkedFacebookAccount.DoesNotExist:
        debug_logger.error("LinkedFacebookAccount for facebook id: %s does not exist" % facebook_user_id)
    else:
        # Delete LinkedFacebookAccount
        user = la.user
        la.delete()

        # Send `profile_update` on Pusher
        notifications_controller.notify_user_of_profile_update(user)
예제 #3
0
def facebook_graph_object(graph_path, params):
    graph_url = FB_GRAPH_URL + graph_path
    try:
        response = requests.get(graph_url, params=params, timeout=20)
        response_data = response.json()
        error = response_data.get('error')
        if response.status_code != 200 or error:
            dev_msg = error.get('message') if isinstance(error, dict) else str(response_data)
            dev_msg = "Facebook Graph error: %s" % dev_msg
            raise ShoutitBadRequest(message=FB_ERROR_TRY_AGAIN, developer_message=dev_msg)
        return response_data
    except requests.RequestException as e:
        dev_msg = "Facebook Graph error: %s" % str(e)
        debug_logger.error(dev_msg)
        raise ShoutitBadRequest(message=FB_ERROR_TRY_AGAIN, developer_message=dev_msg)
예제 #4
0
def update_linked_facebook_account_scopes(facebook_user_id):
    try:
        la = LinkedFacebookAccount.objects.get(facebook_id=facebook_user_id)
    except LinkedFacebookAccount.DoesNotExist:
        debug_logger.error("LinkedFacebookAccount for facebook id: %s does not exist" % facebook_user_id)
    else:
        try:
            token_data = debug_token(la.access_token)
        except ShoutitBadRequest:
            la.delete()
            debug_logger.error("LinkedFacebookAccount for facebook id: %s is expired. Deleting it" % facebook_user_id)
        else:
            scopes = token_data['scopes']
            la.scopes = scopes
            la.save(update_fields=['scopes'])

        # Send `profile_update` on Pusher
        notifications_controller.notify_user_of_profile_update(la.user)
예제 #5
0
def extend_token(short_lived_token):
    exchange_url = FB_GRAPH_ACCESS_TOKEN_URL
    params = {
        'client_id': settings.FACEBOOK_APP_ID,
        'client_secret': settings.FACEBOOK_APP_SECRET,
        'grant_type': "fb_exchange_token",
        'fb_exchange_token': short_lived_token
    }
    try:
        response = requests.get(exchange_url, params=params, timeout=20)
        if response.status_code != 200:
            raise ValueError("Invalid access token: %s" % response.content)
        response_params = dict(urlparse.parse_qsl(response.content))
        access_token = response_params.get('access_token')
        if not access_token:
            raise ValueError('`access_token` not in response: %s' % response.content)
        expires = response_params.get('expires')
        # Sometimes Facebook doesn't return expiry, assume 60 days
        response_params['expires'] = expires or SIXTY_DAYS
    except (requests.RequestException, ValueError) as e:
        debug_logger.error("Facebook token extend error: %s" % str(e))
        raise ShoutitBadRequest(message=FB_ERROR_TRY_AGAIN, developer_message=str(e))
    return response_params
예제 #6
0
def link_facebook_account(user, facebook_access_token):
    """
    Add LinkedFacebookAccount to user
    """
    fb_user = fb_user_from_facebook_access_token(facebook_access_token)
    facebook_id = fb_user['id']
    linked_page_ids = []

    # Check whether the Facebook account is already linked
    try:
        la = LinkedFacebookAccount.objects.get(facebook_id=facebook_id)
        debug_logger.warning('User %s tried to link already linked facebook account id: %s.' % (user, facebook_id))
        if la.user != user:
            raise ShoutitBadRequest(_("Facebook account is already linked to somebody else's profile"))
        linked_page_ids = list(la.pages.values_list('facebook_id', flat=True))  # copy the list
    except LinkedFacebookAccount.DoesNotExist:
        pass

    # Unlink previous Facebook account
    unlink_facebook_user(user, strict=False)

    # Link Facebook account
    try:
        linked_facebook = save_linked_facebook(user, facebook_access_token, fb_user)
    except (ValidationError, IntegrityError) as e:
        debug_logger.error("LinkedFacebookAccount creation error: %s" % str(e))
        raise ShoutitBadRequest(message=FB_LINK_ERROR_TRY_AGAIN, developer_message=str(e))

    # Link Facebook Pages if any existed in the previous LinkedFacebookAccount
    for facebook_page_id in linked_page_ids:
        link_facebook_page(linked_facebook, facebook_page_id)

    # Activate the user if not yet activated
    if not user.is_activated:
        user.notify = False
        user.activate()
예제 #7
0
    def handle(self, *args, **options):
        # Get XML CRM Sources
        count = options['count']
        xml_crm_sources = XMLLinkCRMSource.objects.filter(
            status=XML_LINK_ENABLED)
        processed_sources = []
        errors = []

        # Load XML from source
        for source in xml_crm_sources:
            try:
                self.process_source(source, count)
                processed_sources.append(source)
            except Exception as e:
                errors.append(e)
                debug_logger.error("Error processing source: %s" % str(source))
                debug_logger.error(str(e))

        debug_logger.info("Successfully processed %s sources" %
                          len(processed_sources))
        if len(errors):
            debug_logger.error("Encountered %s errors" % len(errors))
예제 #8
0
    def process_source(self, source, count):
        # load source xml
        xml = self.xml_from_source(source)

        # Parse XML
        data = xmltodict.parse(xml)

        # Map data
        mapping = source.mapping
        raw_shouts = (map_data(data, mapping) or [])[:count]

        # Collect crm ids
        source_ids = map(lambda rs: rs.get('id_on_source'), raw_shouts)

        # Disable current source Shouts with no matching crm ids
        current_crm_shouts = source.crm_shouts.filter(shout__is_disabled=False)
        discarded_crm_shouts = current_crm_shouts.filter(~Q(
            id_on_source__in=source_ids))
        discarded_shouts_ids = map(lambda d_crm_s: str(d_crm_s.shout_id),
                                   discarded_crm_shouts)
        Shout.objects.filter(id__in=discarded_shouts_ids).update(
            is_disabled=True)
        # Remove them from the index too
        ShoutIndex()._get_connection().delete_by_query(
            index=ShoutIndex()._get_index(),
            body={"query": {
                "terms": {
                    "_id": discarded_shouts_ids
                }
            }})

        # Create or update Shouts
        for raw_shout in raw_shouts:
            id_on_source = raw_shout.get('id_on_source')
            try:
                crm_shout = XMLCRMShout.objects.get(id_on_source=id_on_source)
                op = 'updated'
            except XMLCRMShout.DoesNotExist:
                crm_shout = None
                op = 'created'
            finally:
                shout = crm_shout.shout if crm_shout else None
            try:
                if shout:
                    if shout.images:
                        raw_shout['images'] = shout.images
                    shout.is_disabled = False
                raw_shout['text'] = text_from_html(raw_shout['text'])
                serializer = ShoutDetailSerializer(
                    instance=shout,
                    data=raw_shout,
                    context={'user': source.user})
                serializer.is_valid(raise_exception=True)
                shout = serializer.save()
                if not crm_shout:
                    crm_shout = XMLCRMShout.create(attached_object=source,
                                                   id_on_source=id_on_source,
                                                   shout=shout,
                                                   xml_data="test")
                debug_logger.info("Listing %s was %s successfully" %
                                  (id_on_source, op))
            except ValidationError as e:
                debug_logger.error("Listing %s has the following errors %s" %
                                   (id_on_source, str(e)))