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
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
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
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")
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
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
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)
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)
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
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)
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
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
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
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