Пример #1
0
    def redirect_url(self, request, fallback_url=settings.LOGIN_REDIRECT_URL, 
            redirect_field_name="next", session_key_value="redirect_to"):
        """
        Returns the URL to be used in login procedures by looking at different
        values in the following order:

        - a REQUEST value, GET or POST, named "next" by default.
        - LOGIN_REDIRECT_URL - the URL in the setting
        - LOGIN_REDIRECT_URLNAME - the name of a URLconf entry in the settings
        """

        redirect_to = request.REQUEST.get(redirect_field_name)
        if not redirect_to:
            logger.debug("redirect not in get params")
            # try the session if available
            if hasattr(request, "session"):
                redirect_to = request.session.get(session_key_value)
                # Heavier security check -- don't allow redirection to a different host.
                netloc = urlparse.urlparse(redirect_to)[1]
                if netloc and netloc != request.host:
                    logger.warning("redirect_to host does not match orgin")
                    redirect_to = fallback_url
        if not redirect_to:
            logger.debug("no redirect found, using fallback")
            redirect_to = fallback_url
        return redirect_to
Пример #2
0
    def redirect_url(self, request, fallback_url=settings.LOGIN_REDIRECT_URL, 
            redirect_field_name="next", session_key_value="redirect_to"):
        """
        Returns the URL to be used in login procedures by looking at different
        values in the following order:

        - a REQUEST value, GET or POST, named "next" by default.
        - LOGIN_REDIRECT_URL - the URL in the setting
        - LOGIN_REDIRECT_URLNAME - the name of a URLconf entry in the settings
        """

        #modified by Jeff. For some reason this is causing a login error so I just redirect to settings.LOGIN_REDIRECT_URL immediately
        # redirect_to = request.REQUEST.get(redirect_field_name)
        redirect_to = settings.LOGIN_REDIRECT_URL
        if not redirect_to:
            logger.debug("redirect not in get params")
            # try the session if available
            if hasattr(request, "session"):
                redirect_to = request.session.get(session_key_value)
                # Heavier security check -- don't allow redirection to a different host.
                netloc = urlparse.urlparse(redirect_to)[1]
                if netloc and netloc != request.host:
                    logger.warning("redirect_to host does not match orgin")
                    redirect_to = fallback_url
        if not redirect_to:
            logger.debug("no redirect found, using fallback")
            redirect_to = fallback_url
        return redirect_to
Пример #3
0
    def create_user(self, request, access, token, user_data):
        identifier = self.identifier_from_data(user_data)
        username = hashlib.sha224(str(identifier)).hexdigest()[:30]
        if User.objects.filter(username=username).count():
            logger.warning("DefaultFacebookCallback.create_user: A user for" \
                    "was already found, when asked to create a user for %s"
                    % username)
            user = User.objects.get(username=username)
        else:
            user = User(username=username)
            user.set_unusable_password()
            logger.debug(user_data)
            if 'email' in user_data:
                user.email = user_data["email"]
            if 'first_name' in user_data:
                user.first_name = user_data['first_name']
            if 'last_name' in user_data:
                user.last_name = user_data['last_name']
            user.save()
            logger.debug("DefaultFacebookCallback.create_user: new django" \
                    "user created for %s" % username)

        self.create_profile(request, access, token, user)
        self.handle_unauthenticated_user(request, user ,access, token, user_data)
        return user
Пример #4
0
    def create_profile(self, request, access, token, user):

        if hasattr(settings, 'AUTH_PROFILE_MODULE'):
            profile_model = get_model(*settings.AUTH_PROFILE_MODULE.split('.'))

            profile, created = profile_model.objects.get_or_create(user=user)
            profile = self.update_profile_from_graph(request, access, token, profile)
            profile.save()

        else:
            # Do nothing because users have no site profile defined
            # TODO - should we pass a warning message? Raise a SiteProfileNotAvailable error?
            logger.warning("DefaultFacebookCallback.create_profile: unable to create/update profile as no AUTH_PROFILE_MODULE setting has been defined")
Пример #5
0
    def check_token(self, unauth_token, parameters):
        """
            check token
            check to see if unauthorized token
            if authorized token get code parameters
            return OAuth token
        """
        if unauth_token:
            logger.debug("OAuthAccess.check_token: have unauth_token %s"
                    % unauth_token)
            logger.debug("OAuthAccess.check_token: parameters: %s"
                    % parameters)
            token = oauth.Token.from_string(unauth_token)
            if token.key == parameters.get("oauth_token", "no_token"):
                verifier = parameters.get("oauth_verifier")
                return self.authorized_token(token, verifier)
            else:
                return None
        else:
            code = parameters.get("code")
            if code:
                params = dict(
                    client_id = self.key,
                    redirect_uri = self.callback_url,
                )
                params["client_secret"] = self.secret
                params["code"] = code
                logger.debug("OAuthAccess.check_token: token access params: "\
                        "%s, sent to %s" % (params, self.access_token_url))
                raw_data = urllib.urlopen(
                    "%s?%s" % (
                        self.access_token_url, urllib.urlencode(params)
                    )
                ).read()
                response = cgi.parse_qs(raw_data)
                logger.debug("OAuthAccess.check_token: response from code"\
                        "request: %s" % response)
                if 'expires' in response:
                    expires = int(response["expires"][-1])
                else:
                    expires = None

                return OAuth20Token(
                    response["access_token"][-1],
                    expires
                )
            else:
                # @@@ this error case is not nice
                logger.warning("OAuth20Token.check_token: no unauthorized" \
                        "token or code provided")
                return None
Пример #6
0
    def check_token(self, unauth_token, parameters):
        """
            check token
            check to see if unauthorized token
            if authorized token get code parameters
            return OAuth token
        """
        if unauth_token:
            logger.debug("OAuthAccess.check_token: have unauth_token %s"
                    % unauth_token)
            logger.debug("OAuthAccess.check_token: parameters: %s"
                    % parameters)
            token = oauth.Token.from_string(unauth_token)
            if token.key == parameters.get("oauth_token", "no_token"):
                verifier = parameters.get("oauth_verifier")
                return self.authorized_token(token, verifier)
            else:
                return None
        else:
            code = parameters.get("code")
            if code:
                params = dict(
                    client_id = self.key,
                    redirect_uri = self.callback_url,
                )
                params["client_secret"] = self.secret
                params["code"] = code
                logger.debug("OAuthAccess.check_token: token access params: "\
                        "%s, sent to %s" % (params, self.access_token_url))
                raw_data = urllib.urlopen(
                    "%s?%s" % (
                        self.access_token_url, urllib.urlencode(params)
                    )
                ).read()
                response = cgi.parse_qs(raw_data)
                logger.debug("OAuthAccess.check_token: response from code"\
                        "request: %s" % response)
                if 'expires' in response:
                    expires = int(response["expires"][-1])
                else:
                    expires = None

                return OAuth20Token(
                    response["access_token"][-1],
                    expires
                )
            else:
                # @@@ this error case is not nice
                logger.warning("OAuth20Token.check_token: no unauthorized" \
                        "token or code provided")
                return None
Пример #7
0
    def create_profile(self, user, user_data):
        """ Create user profile if one is defined """
        if hasattr(settings, 'AUTH_PROFILE_MODULE'):
            profile_model = get_model(*settings.AUTH_PROFILE_MODULE.split('.'))

            profile, created = profile_model.objects.get_or_create(user=user, )
            profile = self.update_profile(user_data, profile)
            profile.save()

        else:
            # Do nothing because users have no site profile defined
            # TODO - should we pass a warning message? Raise a SiteProfileNotAvailable error?
            logger.warning("DefaultFacebookCallback.create_profile: unable to" \
                    "create/update profile as no AUTH_PROFILE_MODULE setting" \
                    "has been defined")
            pass
Пример #8
0
def facebook_callback(request, error_template_name="la_facebook/fb_error.html", fb_callback_path=None):
    """
        1. define RequestContext
        2. access OAuth
        3. check session
        4. autheticate token
        5. raise exception if missing token
        6. return access callback
        7. raise exception if mismatch token
        8. render error 
    """
    
    ctx = RequestContext(request)
    access = OAuthAccess(fb_callback_path=fb_callback_path)
    # TODO: Check to make sure the session cookie is setting correctly
    unauth_token = request.session.get("unauth_token", None)
    try:
        protocol = "https" if request.is_secure() else "http"
        auth_token = access.check_token(unauth_token, request.GET, protocol=protocol)
    except MissingToken:
        ctx.update({"error": "token_missing"})
        logger.error('la_facebook.views.facebook_callback: missing token')
    else:
        if auth_token:
            logger.debug('la_facebook.views.facebook_callback: token success '\
                    ', sending to callback')
            return access.callback(request, access, auth_token)
        else:
            # @@@ not nice for OAuth 2
            ctx.update({"error": "token_mismatch"})
            logger.error('la_facebook.views.facebook_callback: token mismatch'\
                    ', error getting token, or user denied FB login')

    # we either have a missing token or a token mismatch
    # Facebook provides some error details in the callback URL
    fb_errors = []
    for fb_error_detail in ['error', 'error_description', 'error_reason']:
        if fb_error_detail in request.GET:
            ctx['fb_' + fb_error_detail] = request.GET[fb_error_detail]
            fb_errors.append(request.GET[fb_error_detail])

    logger.warning('la_facebook.views.facebook_callback: %s'
            % ', '.join(fb_errors))

    # Can't change to 401 error because that prompts basic browser auth
    return render_to_response(error_template_name, ctx)
Пример #9
0
def facebook_callback(request,
                      error_template_name="la_facebook/fb_error.html"):
    """
        1. define RequestContext
        2. access OAuth
        3. check session
        4. autheticate token
        5. raise exception if missing token
        6. return access callback
        7. raise exception if mismatch token
        8. render error 
    """

    ctx = RequestContext(request)
    access = OAuthAccess()
    # TODO: Check to make sure the session cookie is setting correctly
    unauth_token = request.session.get("unauth_token", None)
    try:
        auth_token = access.check_token(unauth_token, request.GET)
    except MissingToken:
        ctx.update({"error": "token_missing"})
        logger.error('la_facebook.views.facebook_callback: missing token')
    else:
        if auth_token:
            logger.debug('la_facebook.views.facebook_callback: token success '\
                    ', sending to callback')
            return access.callback(request, access, auth_token)
        else:
            # @@@ not nice for OAuth 2
            ctx.update({"error": "token_mismatch"})
            logger.error('la_facebook.views.facebook_callback: token mismatch'\
                    ', error getting token, or user denied FB login')

    # we either have a missing token or a token mismatch
    # Facebook provides some error details in the callback URL
    fb_errors = []
    for fb_error_detail in ['error', 'error_description', 'error_reason']:
        if fb_error_detail in request.GET:
            ctx['fb_' + fb_error_detail] = request.GET[fb_error_detail]
            fb_errors.append(request.GET[fb_error_detail])

    logger.warning('la_facebook.views.facebook_callback: %s' %
                   ', '.join(fb_errors))

    # Can't change to 401 error because that prompts basic browser auth
    return render_to_response(error_template_name, ctx)
Пример #10
0
    def create_profile(self, user, user_data):
        """ Create user profile if one is defined """
        if hasattr(settings, 'AUTH_PROFILE_MODULE'):
            profile_model = get_model(*settings.AUTH_PROFILE_MODULE.split('.'))

            profile, created = profile_model.objects.get_or_create(
              user = user,
            )
            profile = self.update_profile(user_data, profile)
            profile.save()

        else:
            # Do nothing because users have no site profile defined
            # TODO - should we pass a warning message? Raise a SiteProfileNotAvailable error?
            logger.warning("DefaultFacebookCallback.create_profile: unable to" \
                    "create/update profile as no AUTH_PROFILE_MODULE setting" \
                    "has been defined")
            pass
Пример #11
0
def facebook_callback(request):
    """
        1. define RequestContext
        2. access OAuth
        3. check session
        4. autheticate token
        5. raise exception if missing token
        6. return access callback
        7. raise exception if mismatch token
        8. render error 
    """
    
    ctx = RequestContext(request)
    access = OAuthAccess()
    # TODO: Check to make sure the session cookie is setting correctly
    unauth_token = request.session.get("unauth_token", None)
    try:
        auth_token = access.check_token(unauth_token, request.GET)
    except MissingToken:
        ctx.update({"error": "token_missing"})
        logger.error('la_facebook.views.facebook_login: missing token')
    else:
        if auth_token:
            return access.callback(request, access, auth_token)
        else:
            # @@@ not nice for OAuth 2
            ctx.update({"error": "token_mismatch"})
            logger.error('la_facebook.views.facebook_callback: token mismatch'\
                    ', error getting token, or user denied FB login')

    # we either have a missing token or a token mismatch
    # Facebook provides some error details in the callback URL
    fb_errors = []
    for fb_error_detail in ['error', 'error_description', 'error_reason']:
        if fb_error_detail in request.GET:
            ctx['fb_' + fb_error_detail] = request.GET[fb_error_detail]
            fb_errors.append(request.GET[fb_error_detail])

    logger.warning('la_facebook.views.facebook_callback: %s'
            % ', '.join(fb_errors))

    return render_to_response("la_facebook/fb_error.html", ctx)
Пример #12
0
    def create_user(self, request, access, token, user_data):
        identifier = self.identifier_from_data(user_data)
        User = get_user_model()
        USERNAME_FIELD = User.USERNAME_FIELD
        username = str(identifier)
        if User.objects.filter(**{USERNAME_FIELD: username}).count():
            logger.warning("DefaultFacebookCallback.create_user: A user for was already found, when asked to create a user for %s" % username)
            user = User.objects.get(**{USERNAME_FIELD: username})
        else:
            user = User(**{USERNAME_FIELD: str(identifier)})
            user.set_unusable_password()
            logger.debug(user_data)
            if 'email' in user_data:
                user.email = user_data["email"]
            user.save()
            logger.debug("DefaultFacebookCallback.create_user: new django user created for %s" % username)

        self.create_profile(request, access, token, user)
        self.handle_unauthenticated_user(request, user, access, token, user_data)
        return user
Пример #13
0
    def create_profile(self, request, access, token, user):

        if hasattr(settings, 'AUTH_PROFILE_MODULE'):
            profile_model = get_model(*settings.AUTH_PROFILE_MODULE.split('.'))

            #            profile, created = profile_model.objects.get_or_create(
            #              user = user,
            #            )
            profile = self.update_profile_from_graph(request, access, token,
                                                     user)
            profile.save()
            # Send out Welcome message to this user that has newly been created

        else:
            # Do nothing because users have no site profile defined
            # TODO - should we pass a warning message? Raise a SiteProfileNotAvailable error?
            logger.warning("DefaultFacebookCallback.create_profile: unable to" \
                    "create/update profile as no AUTH_PROFILE_MODULE setting" \
                    "has been defined")
            pass
Пример #14
0
    def redirect_url(
        self,
        request,
        fallback_url=settings.LOGIN_REDIRECT_URL,
        redirect_field_name="next",
        session_key_value="redirect_to",
    ):
        """
        Returns the URL to be used in login procedures by looking at different
        values in the following order:

        - a REQUEST value, GET or POST, named "next" by default.
        - LOGIN_REDIRECT_URL - the URL in the setting
        - LOGIN_REDIRECT_URLNAME - the name of a URLconf entry in the settings
        """

        redirect_to = request.REQUEST.get(redirect_field_name)
        if not redirect_to:
            logger.debug("redirect not in get params")
            # try the session if available
            if hasattr(request, "session"):
                redirect_to = request.session.get(session_key_value)
                # Heavier security check -- don't allow redirection to a different host.
                if redirect_to:
                    netloc = urlparse.urlparse(redirect_to)[1]
                    if netloc and netloc != request.host:
                        logger.warning("redirect_to host does not match orgin")
                        redirect_to = fallback_url
                else:
                    # There ought to have been a value in the session. This
                    # is probably a developer error, so log a warning.
                    logger.warning(
                        "Session found, but no redirect_to. Check "
                        "that you have set up the facebook_login "
                        "view with a 'next' querystring "
                        "parameter. Using fallback."
                    )
        if not redirect_to:
            logger.debug("no redirect found, using fallback")
            redirect_to = fallback_url
        return redirect_to
Пример #15
0
    def create_user(self, request, access, token, user_data):
        identifier = self.identifier_from_data(user_data)
        username = str(identifier)
        if User.objects.filter(username=username).count():
            logger.warning("DefaultFacebookCallback.create_user: A user for" \
                    "was already found, when asked to create a user for %s"
                    % username)
            user = User.objects.get(username=username)
        else:
            user = User(username=str(identifier))
            user.set_unusable_password()
            logger.debug(user_data)
            if 'email' in user_data:
                user.email = user_data["email"]
            user.save()
            logger.debug("DefaultFacebookCallback.create_user: new django" \
                    "user created for %s" % username)

        self.create_profile(request, access, token, user)
        self.handle_unauthenticated_user(request, user, access, token,
                                         user_data)
        return user