def do_login(self, after_complete_checks=True, user_data_body=None, expected_username=None): self.strategy.set_settings({ 'SOCIAL_AUTH_GITHUB_KEY': 'a-key', 'SOCIAL_AUTH_GITHUB_SECRET': 'a-secret-key', 'SOCIAL_AUTH_LOGIN_REDIRECT_URL': self.login_redirect_url, 'SOCIAL_AUTH_AUTHENTICATION_BACKENDS': ('social.backends.github.GithubOAuth2', ) }) start_url = do_auth(self.backend).url target_url = self.strategy.build_absolute_uri( '/complete/github/?code=foobar') start_query = parse_qs(urlparse(start_url).query) location_url = target_url + ('?' in target_url and '&' or '?') + \ 'state=' + start_query['state'] location_query = parse_qs(urlparse(location_url).query) HTTPretty.register_uri(HTTPretty.GET, start_url, status=301, location=location_url) HTTPretty.register_uri(HTTPretty.GET, location_url, status=200, body='foobar') response = requests.get(start_url) expect(response.url).to.equal(location_url) expect(response.text).to.equal('foobar') HTTPretty.register_uri(HTTPretty.POST, uri=self.backend.ACCESS_TOKEN_URL, status=200, body=self.access_token_body or '', content_type='text/json') if self.user_data_url: user_data_body = user_data_body or self.user_data_body or '' HTTPretty.register_uri(HTTPretty.GET, self.user_data_url, body=user_data_body, content_type='text/json') self.strategy.set_request_data(location_query, self.backend) def _login(backend, user, social_user): backend.strategy.session_set('username', user.username) redirect = do_complete(self.backend, user=self.user, login=_login) if after_complete_checks: expect(self.strategy.session_get('username')).to.equal( expected_username or self.expected_username) expect(redirect.url).to.equal(self.login_redirect_url) return redirect
def do_login(self, after_complete_checks=True, user_data_body=None, expected_username=None): self.strategy.set_settings({ 'SOCIAL_AUTH_GITHUB_KEY': 'a-key', 'SOCIAL_AUTH_GITHUB_SECRET': 'a-secret-key', 'SOCIAL_AUTH_LOGIN_REDIRECT_URL': self.login_redirect_url, 'SOCIAL_AUTH_AUTHENTICATION_BACKENDS': ( 'social.backends.github.GithubOAuth2', ) }) start_url = do_auth(self.strategy).url target_url = self.strategy.build_absolute_uri( '/complete/github/?code=foobar' ) start_query = parse_qs(urlparse(start_url).query) location_url = target_url + ('?' in target_url and '&' or '?') + \ 'state=' + start_query['state'] location_query = parse_qs(urlparse(location_url).query) HTTPretty.register_uri(HTTPretty.GET, start_url, status=301, location=location_url) HTTPretty.register_uri(HTTPretty.GET, location_url, status=200, body='foobar') response = requests.get(start_url) expect(response.url).to.equal(location_url) expect(response.text).to.equal('foobar') HTTPretty.register_uri(HTTPretty.GET, uri=self.backend.ACCESS_TOKEN_URL, status=200, body=self.access_token_body or '', content_type='text/json') if self.user_data_url: user_data_body = user_data_body or self.user_data_body or '' HTTPretty.register_uri(HTTPretty.GET, self.user_data_url, body=user_data_body, content_type='text/json') self.strategy.set_request_data(location_query) class Request(object):session = {} self.strategy.request = Request() def _login_lambda(strategy, user, social_user): strategy.request = Request() return strategy.session_set('username', user.username) redirect = do_complete( self.strategy, user=self.user, login=_login_lambda ) if after_complete_checks: expect(self.strategy.session_get('username')).to.equal( expected_username or self.expected_username ) expect(redirect.url).to.equal(self.login_redirect_url) return redirect
def auth_by_token(request, backend): key, secret = request.backend.get_key_and_secret() response = requests.get(request.backend.ACCESS_TOKEN_URL, params={ 'client_id': key, 'redirect_uri': request.data.get('redirect_uri'), 'client_secret': secret, 'code': request.data.get('code') }) try: response = response.json() except ValueError: response = parse_qs(response.text) try: access_token = response['access_token'] # check if user has signed up email = request.backend.user_data(access_token).get('email') try: User.objects.get(email=email) new_user = False except User.DoesNotExist: new_user = True return new_user, request.backend.do_auth(access_token) except KeyError: raise APIException(response['error']['message'])
def auth_complete(self, *args, **kwargs): """Return user, might be logged in""" # Multiple unauthorized tokens are supported (see #521) self.process_error(self.data) name = self.name + 'unauthorized_token_name' token = None unauthed_tokens = self.strategy.session_get(name, []) if not unauthed_tokens: raise AuthTokenError(self, 'Missing unauthorized token') token_param_name = self.OAUTH_TOKEN_PARAMETER_NAME data_token = self.data.get(token_param_name, 'no-token') for unauthed_token in unauthed_tokens: orig_unauthed_token = unauthed_token if not isinstance(unauthed_token, dict): unauthed_token = parse_qs(unauthed_token) if unauthed_token.get(token_param_name) == data_token: self.strategy.session_set(name, list( set(unauthed_tokens) - set([orig_unauthed_token])) ) token = unauthed_token break else: raise AuthTokenError(self, 'Incorrect tokens') try: access_token = self.access_token(token) except HTTPError as err: if err.response.status_code == 400: raise AuthCanceled(self) else: raise return self.do_auth(access_token, *args, **kwargs)
def test_disconnect_with_partial_pipeline(self): self.strategy.set_settings({ 'SOCIAL_AUTH_DISCONNECT_PIPELINE': ('social.pipeline.partial.save_status_to_session', 'social.tests.pipeline.ask_for_password', 'social.tests.pipeline.set_password', 'social.pipeline.disconnect.allowed_to_disconnect', 'social.pipeline.disconnect.get_entries', 'social.pipeline.disconnect.revoke_tokens', 'social.pipeline.disconnect.disconnect') }) self.do_login() user = User.get(self.expected_username) redirect = do_disconnect(self.backend, user) url = self.strategy.build_absolute_uri('/password') self.assertEqual(redirect.url, url) HTTPretty.register_uri(HTTPretty.GET, redirect.url, status=200, body='foobar') HTTPretty.register_uri(HTTPretty.POST, redirect.url, status=200) password = '******' requests.get(url) requests.post(url, data={'password': password}) data = parse_qs(HTTPretty.last_request.body) self.assertEqual(data['password'], password) self.strategy.session_set('password', data['password']) redirect = do_disconnect(self.backend, user) self.assertEqual(len(user.social), 0)
def post(self, request, *args, **kwargs): input_data = self.get_serializer_in_data() provider_name = self.get_provider_name(input_data) if not provider_name: return self.respond_error("Provider is not specified") self.set_input_data(request, input_data) decorate_request(request, provider_name) serializer_in = self.get_serializer_in(data=input_data) if self.oauth_v1( ) and request.backend.OAUTH_TOKEN_PARAMETER_NAME not in input_data: # oauth1 first stage (1st is get request_token, 2nd is get access_token) request_token = parse_qs(request.backend.set_unauthorized_token()) return Response(request_token) serializer_in.is_valid(raise_exception=True) try: user = self.get_object() except (AuthException, HTTPError) as e: return self.respond_error(e) if isinstance( user, HttpResponse ): # An error happened and pipeline returned HttpResponse instead of user return user resp_data = self.get_serializer(instance=user) self.do_login(request.backend, user) return Response(resp_data.data)
def test_disconnect_with_partial_pipeline(self): self.strategy.set_settings({ 'SOCIAL_AUTH_DISCONNECT_PIPELINE': ( 'social.pipeline.partial.save_status_to_session', 'social.tests.pipeline.ask_for_password', 'social.tests.pipeline.set_password', 'social.pipeline.disconnect.allowed_to_disconnect', 'social.pipeline.disconnect.get_entries', 'social.pipeline.disconnect.revoke_tokens', 'social.pipeline.disconnect.disconnect' ) }) self.do_login() user = User.get(self.expected_username) redirect = do_disconnect(self.backend, user) url = self.strategy.build_absolute_uri('/password') expect(redirect.url).to.equal(url) HTTPretty.register_uri(HTTPretty.GET, redirect.url, status=200, body='foobar') HTTPretty.register_uri(HTTPretty.POST, redirect.url, status=200) password = '******' requests.get(url) requests.post(url, data={'password': password}) data = parse_qs(HTTPretty.last_request.body) expect(data['password']).to.equal(password) self.strategy.session_set('password', data['password']) redirect = do_disconnect(self.backend, user) expect(len(user.social)).to.equal(0)
def auth_complete(self, *args, **kwargs): """Return user, might be logged in""" # Multiple unauthorized tokens are supported (see #521) self.process_error(self.data) name = self.name + 'unauthorized_token_name' token = None unauthed_tokens = self.strategy.session_get(name, []) if not unauthed_tokens: raise AuthTokenError(self, 'Missing unauthorized token') token_param_name = self.OAUTH_TOKEN_PARAMETER_NAME data_token = self.data.get(token_param_name, 'no-token') for unauthed_token in unauthed_tokens: orig_unauthed_token = unauthed_token if not isinstance(unauthed_token, dict): unauthed_token = parse_qs(unauthed_token) if unauthed_token.get(token_param_name) == data_token: self.strategy.session_set( name, list(set(unauthed_tokens) - set([orig_unauthed_token]))) token = unauthed_token break else: raise AuthTokenError(self, 'Incorrect tokens') try: access_token = self.access_token(token) except HTTPError as err: if err.response.status_code == 400: raise AuthCanceled(self) else: raise return self.do_auth(access_token, *args, **kwargs)
def run_oauth(self, m, user=None): strategy = DjangoStrategy(DjangoStorage) backend = self.Backend_Class(strategy, redirect_uri=self.client_complete_url) start_url = do_auth(backend).url start_query = parse_qs(urlparse(start_url).query) # set 'state' in client backend.data.update({'state': start_query['state']}) m.get(backend.USER_DATA_URL, json={"username": self.social_username, "email": self.social_email}, status_code=200) m.post(backend.ACCESS_TOKEN_URL, json={'access_token': self.access_token, 'token_type': self.token_type, 'expires_in': self.expires_in, 'scope': self.scope, 'refresh_token': self.refresh_token}, status_code=200) def _login(backend, user, social_user): backend.strategy.session_set('username', user.username) do_complete(backend, user=user, login=_login) social = backend.strategy.storage.user.get_social_auth(backend.name, self.social_username) return strategy.session_get('username'), social, backend
def handle_state(self, start_url, target_url): start_query = parse_qs(urlparse(start_url).query) redirect_uri = start_query.get('redirect_uri') if getattr(self.backend, 'STATE_PARAMETER', False): if start_query.get('state'): target_url = url_add_parameters( target_url, {'state': start_query['state']}) if redirect_uri and getattr(self.backend, 'REDIRECT_STATE', False): redirect_query = parse_qs(urlparse(redirect_uri).query) if redirect_query.get('redirect_state'): target_url = url_add_parameters( target_url, {'redirect_state': redirect_query['redirect_state']}) return target_url
def do_start(self): start_url = self.strategy.start().url target_url = self.auth_handlers(start_url) response = requests.get(start_url) expect(response.url).to.equal(target_url) expect(response.text).to.equal('foobar') self.strategy.set_request_data(parse_qs(urlparse(target_url).query)) return self.strategy.complete()
def access_token_body(self, request, _url, headers): """ Get the nonce from the request parameters, add it to the id_token, and return the complete response. """ nonce = parse_qs(request.body).get('nonce') body = self.prepare_access_token_body(nonce=nonce) return 200, headers, body
def parse_nonce_and_return_access_token_body(self, request, _url, headers): """ Get the nonce from the request parameters, add it to the id_token, and return the complete response. """ nonce = parse_qs(request.body).get('nonce') body = self.prepare_access_token_body(nonce=nonce) return 200, headers, body
def handle_state(self, start_url, target_url): start_query = parse_qs(urlparse(start_url).query) redirect_uri = start_query.get('redirect_uri') if getattr(self.backend, 'STATE_PARAMETER', False): if start_query.get('state'): target_url = url_add_parameters(target_url, { 'state': start_query['state'] }) if redirect_uri and getattr(self.backend, 'REDIRECT_STATE', False): redirect_query = parse_qs(urlparse(redirect_uri).query) if redirect_query.get('redirect_state'): target_url = url_add_parameters(target_url, { 'redirect_state': redirect_query['redirect_state'] }) return target_url
def do_login(self, after_complete_checks=True, user_data_body=None, expected_username=None): self.strategy.set_settings( { "SOCIAL_AUTH_GITHUB_KEY": "a-key", "SOCIAL_AUTH_GITHUB_SECRET": "a-secret-key", "SOCIAL_AUTH_LOGIN_REDIRECT_URL": self.login_redirect_url, "SOCIAL_AUTH_AUTHENTICATION_BACKENDS": ("social.backends.github.GithubOAuth2",), } ) start_url = do_auth(self.backend).url target_url = self.strategy.build_absolute_uri("/complete/github/?code=foobar") start_query = parse_qs(urlparse(start_url).query) location_url = target_url + ("?" in target_url and "&" or "?") + "state=" + start_query["state"] location_query = parse_qs(urlparse(location_url).query) HTTPretty.register_uri(HTTPretty.GET, start_url, status=301, location=location_url) HTTPretty.register_uri(HTTPretty.GET, location_url, status=200, body="foobar") response = requests.get(start_url) expect(response.url).to.equal(location_url) expect(response.text).to.equal("foobar") HTTPretty.register_uri( HTTPretty.POST, uri=self.backend.ACCESS_TOKEN_URL, status=200, body=self.access_token_body or "", content_type="text/json", ) if self.user_data_url: user_data_body = user_data_body or self.user_data_body or "" HTTPretty.register_uri(HTTPretty.GET, self.user_data_url, body=user_data_body, content_type="text/json") self.strategy.set_request_data(location_query, self.backend) def _login(backend, user, social_user): backend.strategy.session_set("username", user.username) redirect = do_complete(self.backend, user=self.user, login=_login) if after_complete_checks: expect(self.strategy.session_get("username")).to.equal(expected_username or self.expected_username) expect(redirect.url).to.equal(self.login_redirect_url) return redirect
def do_start(self): start_url = self.strategy.build_absolute_uri(self.strategy.start().url) HTTPretty.register_uri(HTTPretty.GET, start_url, status=200, body=self.form.format(self.complete_url)) HTTPretty.register_uri( HTTPretty.POST, self.complete_url, status=200, body=self.response_body, content_type='application/x-www-form-urlencoded') response = requests.get(start_url) expect(response.text).to.equal(self.form.format(self.complete_url)) response = requests.post(self.complete_url, data=parse_qs(self.response_body)) self.strategy.set_request_data(parse_qs(response.text)) return self.strategy.complete()
def do_auth(self, access_token, *args, **kwargs): """Finish the auth process once the access_token was retrieved""" if not isinstance(access_token, dict): access_token = parse_qs(access_token) data = self.user_data(access_token) if data is not None and 'access_token' not in data: data['access_token'] = access_token kwargs.update({'response': data, 'backend': self}) return self.strategy.authenticate(*args, **kwargs)
def do_start(self): start_url = self.backend.start().url target_url = self.auth_handlers(start_url) response = requests.get(start_url) self.assertEqual(response.url, target_url) self.assertEqual(response.text, 'foobar') self.strategy.set_request_data(parse_qs(urlparse(target_url).query), self.backend) return self.backend.complete()
def pipeline_slug_handling(self, url): slug = 'foo-bar' requests.get(url) requests.post(url, data={'slug': slug}) data = parse_qs(HTTPretty.last_request.body) self.assertEqual(data['slug'], slug) self.strategy.session_set('slug', data['slug']) return slug
def oauth_authorization_request(self, token): """Generate OAuth request to authorize token.""" if not isinstance(token, dict): token = parse_qs(token) params = self.auth_extra_arguments() or {} params.update(self.get_scope_argument()) params['oauth_token'] = token.get('oauth_token') params['redirect_uri'] = self.redirect_uri return self.AUTHORIZATION_URL + '?' + urlencode(params)
def pipeline_password_handling(self, url): password = '******' requests.get(url) requests.post(url, data={'password': password}) data = parse_qs(HTTPretty.last_request.body) self.assertEqual(data['password'], password) self.strategy.session_set('password', data['password']) return password
def pipeline_password_handling(self, url): password = '******' requests.get(url) requests.post(url, data={'password': password}) data = parse_qs(HTTPretty.last_request.body) expect(data['password']).to.equal(password) self.strategy.session_set('password', data['password']) return password
def pipeline_password_handling(self, url): password = "******" requests.get(url) requests.post(url, data={"password": password}) data = parse_qs(HTTPretty.last_request.body) expect(data["password"]).to.equal(password) self.strategy.session_set("password", data["password"]) return password
def pipeline_slug_handling(self, url): slug = 'foo-bar' requests.get(url) requests.post(url, data={'slug': slug}) data = parse_qs(HTTPretty.last_request.body) expect(data['slug']).to.equal(slug) self.strategy.session_set('slug', data['slug']) return slug
def pipeline_slug_handling(self, url): slug = "foo-bar" requests.get(url) requests.post(url, data={"slug": slug}) data = parse_qs(HTTPretty.last_request.body) expect(data["slug"]).to.equal(slug) self.strategy.session_set("slug", data["slug"]) return slug
def oauth_authorization_request(self, token): """Generate OAuth request to authorize token.""" if not isinstance(token, dict): token = parse_qs(token) params = self.auth_extra_arguments() or {} params.update(self.get_scope_argument()) params[self.OAUTH_TOKEN_PARAMETER_NAME] = token.get( self.OAUTH_TOKEN_PARAMETER_NAME) params[self.REDIRECT_URI_PARAMETER_NAME] = self.redirect_uri return self.AUTHORIZATION_URL + '?' + urlencode(params)
def oauth_authorization_request(self, token): """Generate OAuth request to authorize token.""" if not isinstance(token, dict): token = parse_qs(token) params = self.auth_extra_arguments() or {} params.update(self.get_scope_argument()) params[self.OAUTH_TOKEN_PARAMETER_NAME] = token.get(self.OAUTH_TOKEN_PARAMETER_NAME) state = self.get_or_create_state() params[self.REDIRECT_URI_PARAMETER_NAME] = self.get_redirect_uri(state) return "{0}?{1}".format(self.authorization_url(), urlencode(params))
def do_start(self): name = self.backend.name.upper().replace('-', '_') self.strategy.set_settings({ 'SOCIAL_AUTH_' + name + '_KEY': 'a-key', 'SOCIAL_AUTH_' + name + '_SECRET': 'a-secret-key', }) start_url = self.strategy.start().url target_url = self.strategy.build_absolute_uri(self.complete_url) start_query = parse_qs(urlparse(start_url).query) if self.backend.STATE_PARAMETER: location_url = target_url + ('?' in target_url and '&' or '?') + \ 'state=' + start_query['state'] elif self.backend.REDIRECT_STATE: location_url = target_url + ('?' in target_url and '&' or '?') + \ 'redirect_state=' + start_query['redirect_state'] else: location_url = target_url location_query = parse_qs(urlparse(location_url).query) HTTPretty.register_uri(HTTPretty.GET, start_url, status=301, location=location_url) HTTPretty.register_uri(HTTPretty.GET, location_url, status=200, body='foobar') response = requests.get(start_url) expect(response.url).to.equal(location_url) expect(response.text).to.equal('foobar') method = self.backend.ACCESS_TOKEN_METHOD == 'GET' and HTTPretty.GET \ or HTTPretty.POST HTTPretty.register_uri(method, uri=self.backend.ACCESS_TOKEN_URL, status=200, body=self.access_token_body or '', content_type='text/json') if self.user_data_url: HTTPretty.register_uri(HTTPretty.GET, self.user_data_url, body=self.user_data_body or '', content_type='text/json') self.strategy.set_request_data(location_query)
def handle_state(self, start_url, target_url): try: if self.backend.STATE_PARAMETER or self.backend.REDIRECT_STATE: query = parse_qs(urlparse(start_url).query) target_url = target_url + ('?' in target_url and '&' or '?') if 'state' in query or 'redirect_state' in query: name = 'state' in query and 'state' or 'redirect_state' target_url += '{0}={1}'.format(name, query[name]) except AttributeError: pass return target_url
def test_login_social_oauth1_session(self): resp = self.client.post(reverse('login_social_session'), data={'provider': 'twitter'}) self.assertEqual(resp.status_code, 200) self.assertEqual(resp.data, parse_qs(self.request_token_body)) resp = self.client.post(reverse('login_social_session'), data={ 'provider': 'twitter', 'oauth_token': 'foobar', 'oauth_verifier': 'overifier' }) self.assertEqual(resp.status_code, 200)
def oauth_authorization_request(self, token): """Generate OAuth request to authorize token.""" if not isinstance(token, dict): token = parse_qs(token) params = self.auth_extra_arguments() or {} params.update(self.get_scope_argument()) params[self.OAUTH_TOKEN_PARAMETER_NAME] = token.get( self.OAUTH_TOKEN_PARAMETER_NAME) state = self.get_or_create_state() params[self.REDIRECT_URI_PARAMETER_NAME] = self.get_redirect_uri(state) return '{0}?{1}'.format(self.authorization_url(), urlencode(params))
def handle_state(backend, start_url, target_url): try: if backend.STATE_PARAMETER or backend.REDIRECT_STATE: query = parse_qs(urlparse(start_url).query) target_url = target_url + ("?" in target_url and "&" or "?") if "state" in query or "redirect_state" in query: name = "state" in query and "state" or "redirect_state" target_url += "{0}={1}".format(name, query[name]) except AttributeError: pass return bytes(target_url)
def oauth_authorization_request(self, token): """Generate OAuth request to authorize token.""" if not isinstance(token, dict): token = parse_qs(token) params = self.auth_extra_arguments() or {} params.update(self.get_scope_argument()) params[self.OAUTH_TOKEN_PARAMETER_NAME] = token.get( self.OAUTH_TOKEN_PARAMETER_NAME ) params[self.REDIRECT_URI_PARAMETER_NAME] = self.redirect_uri return self.AUTHORIZATION_URL + '?' + urlencode(params)
def do_start(self): HTTPretty.register_uri( HTTPretty.GET, self.openid_url(), status=200, body=self.discovery_body, content_type="application/xrds+xml" ) start = self.strategy.start() self.post_start() form, inputs = self.get_form_data(start) HTTPretty.register_uri(HTTPretty.POST, form.get("action"), status=200, body=self.server_response) response = requests.post(form.get("action"), data=inputs) self.strategy.set_request_data(parse_qs(response.content)) HTTPretty.register_uri(HTTPretty.POST, form.get("action"), status=200, body="is_valid:true\n") return self.strategy.complete()
def auth_complete(self, *args, **kwargs): """Yammer API is a little strange""" self.process_error(self.data) # now we need to clean up the data params data = self.data.copy() redirect_state = data.get('redirect_state') if redirect_state and '?' in redirect_state: redirect_state, extra = redirect_state.split('?', 1) extra = parse_qs(extra) data['redirect_state'] = redirect_state if 'code' in extra: data['code'] = extra['code'] self.data = data return super(YammerOAuth2, self).auth_complete(*args, **kwargs)
def do_start(self): start_url = self.strategy.build_absolute_uri(self.strategy.start().url) HTTPretty.register_uri( HTTPretty.GET, start_url, status=200, body=self.form.format(self.complete_url) ) HTTPretty.register_uri( HTTPretty.POST, self.complete_url, status=200, body=self.response_body, content_type='application/x-www-form-urlencoded' ) response = requests.get(start_url) expect(response.text).to.equal(self.form.format(self.complete_url)) response = requests.post( self.complete_url, data=parse_qs(self.response_body) ) self.strategy.set_request_data(parse_qs(response.text)) return self.strategy.complete()
def auth_complete(self, *args, **kwargs): """Yammer API is a little strange""" if "error" in self.data: raise AuthCanceled(self) # now we need to clean up the data params data = self.data.copy() redirect_state = data.get("redirect_state") if redirect_state and "?" in redirect_state: redirect_state, extra = redirect_state.split("?", 1) extra = parse_qs(extra) data["redirect_state"] = redirect_state if "code" in extra: data["code"] = extra["code"] self.data = data return super(YammerOAuth2, self).auth_complete(*args, **kwargs)
def test_login_social_oauth1_token(self): """ Currently oauth1 works only if session is enabled. Probably it is possible to make it work without session, but it will be needed to change the logic in python-social-auth. """ resp = self.client.post(reverse('login_social_token_user'), data={'provider': 'twitter'}) self.assertEqual(resp.status_code, 200) self.assertEqual(resp.data, parse_qs(self.request_token_body)) resp = self.client.post(reverse('login_social_token_user'), data={ 'provider': 'twitter', 'oauth_token': 'foobar', 'oauth_verifier': 'overifier' }) self.assertEqual(resp.status_code, 200)
def auth_complete(self, *args, **kwargs): """Performs check of authentication in VKontakte, returns User if succeeded""" session_value = self.strategy.session_get("vk_app_" + self.setting("APP_ID")) if "id" not in self.data or not session_value: raise ValueError("VK.com authentication is not completed") mapping = parse_qs(session_value) check_str = "".join(item + "=" + mapping[item] for item in ["expire", "mid", "secret", "sid"]) key, secret = self.get_key_and_secret() hash = md5((check_str + secret).encode("utf-8")).hexdigest() if hash != mapping["sig"] or int(mapping["expire"]) < time(): raise ValueError("VK.com authentication failed: Invalid Hash") kwargs.update({"backend": self, "response": self.user_data(mapping["mid"])}) return self.strategy.authenticate(*args, **kwargs)
def post(self, request, *args, **kwargs): input_data = self.get_serializer_in_data() self.set_input_data(request, input_data) decorate_request(request, input_data['provider']) serializer_in = self.get_serializer_in(data=input_data) if (isinstance(serializer_in, OAuth1InputSerializer) and request.backend.OAUTH_TOKEN_PARAMETER_NAME not in input_data): # If this is oauth1 and first stage (1st is get request_token, 2nd is get access_token) request_token = parse_qs(request.backend.set_unauthorized_token()) return Response(request_token) serializer_in.is_valid(raise_exception=True) try: user = self.get_object() except (AuthException, HTTPError) as e: l.exception(e) return self.respond_error(e) resp_data = self.get_serializer(instance=user) self.do_login(request.backend, user) return Response(resp_data.data)
def do_start(self): HTTPretty.register_uri(HTTPretty.GET, self.openid_url(), status=200, body=self.discovery_body, content_type='application/xrds+xml') start = self.strategy.start() self.post_start() form, inputs = self.get_form_data(start) HTTPretty.register_uri(HTTPretty.POST, form.get('action'), status=200, body=self.server_response) response = requests.post(form.get('action'), data=inputs) self.strategy.set_request_data(parse_qs(response.content)) HTTPretty.register_uri(HTTPretty.POST, form.get('action'), status=200, body='is_valid:true\n') return self.strategy.complete()
def post(self, request, *args, **kwargs): input_data = self.get_serializer_in_data() provider_name = self.get_provider_name(input_data) if not provider_name: return self.respond_error("Provider is not specified") self.set_input_data(request, input_data) decorate_request(request, provider_name) serializer_in = self.get_serializer_in(data=input_data) if self.oauth_v1() and request.backend.OAUTH_TOKEN_PARAMETER_NAME not in input_data: # oauth1 first stage (1st is get request_token, 2nd is get access_token) request_token = parse_qs(request.backend.set_unauthorized_token()) return Response(request_token) serializer_in.is_valid(raise_exception=True) try: user = self.get_object() except (AuthException, HTTPError) as e: return self.respond_error(e) resp_data = self.get_serializer(instance=user) self.do_login(request.backend, user) return Response(resp_data.data)
def auth_complete(self, *args, **kwargs): """Performs check of authentication in VKontakte, returns User if succeeded""" session_value = self.strategy.session_get( 'vk_app_' + self.setting('APP_ID') ) if 'id' not in self.data or not session_value: raise ValueError('VK.com authentication is not completed') mapping = parse_qs(session_value) check_str = ''.join(item + '=' + mapping[item] for item in ['expire', 'mid', 'secret', 'sid']) key, secret = self.get_key_and_secret() hash = md5((check_str + secret).encode('utf-8')).hexdigest() if hash != mapping['sig'] or int(mapping['expire']) < time(): raise ValueError('VK.com authentication failed: Invalid Hash') kwargs.update({'backend': self, 'response': self.user_data(mapping['mid'])}) return self.strategy.authenticate(*args, **kwargs)
def auth_complete(self, *args, **kwargs): """Completes loging process, must return user instance""" self.process_error(self.data) if not self.data.get('code'): raise AuthMissingParameter(self, 'code') state = self.validate_state() key, secret = self.get_key_and_secret() response = self.request(self.ACCESS_TOKEN_URL, params={ 'client_id': key, 'redirect_uri': self.get_redirect_uri(state), 'client_secret': secret, 'code': self.data['code'] }) # API v2.3 returns a JSON, according to the documents linked at issue # #592, but it seems that this needs to be enabled(?), otherwise the # usual querystring type response is returned. try: response = response.json() except ValueError: response = parse_qs(response.text) access_token = response['access_token'] return self.do_auth(access_token, response, *args, **kwargs)
def run_oauth(self, m, user=None): strategy = DjangoStrategy(DjangoStorage) backend = self.Backend_Class(strategy, redirect_uri=self.client_complete_url) start_url = do_auth(backend).url start_query = parse_qs(urlparse(start_url).query) # set 'state' in client backend.data.update({'state': start_query['state']}) m.get(backend.USER_DATA_URL, json={ "username": self.social_username, "email": self.social_email }, status_code=200) m.post(backend.ACCESS_TOKEN_URL, json={ 'access_token': self.access_token, 'token_type': self.token_type, 'expires_in': self.expires_in, 'scope': self.scope, 'refresh_token': self.refresh_token }, status_code=200) def _login(backend, user, social_user): backend.strategy.session_set('username', user.username) do_complete(backend, user=user, login=_login) social = backend.strategy.storage.user.get_social_auth( backend.name, self.social_username) return strategy.session_get('username'), social, backend
def get_unauthorized_token(self): name = self.name + self.UNATHORIZED_TOKEN_SUFIX unauthed_tokens = self.strategy.session_get(name, []) if not unauthed_tokens: raise AuthTokenError(self, 'Missing unauthorized token') data_token = self.data.get(self.OAUTH_TOKEN_PARAMETER_NAME) if data_token is None: raise AuthTokenError(self, 'Missing unauthorized token') token = None for utoken in unauthed_tokens: orig_utoken = utoken if not isinstance(utoken, dict): utoken = parse_qs(utoken) if utoken.get(self.OAUTH_TOKEN_PARAMETER_NAME) == data_token: self.strategy.session_set( name, list(set(unauthed_tokens) - set([orig_utoken]))) token = utoken break else: raise AuthTokenError(self, 'Incorrect tokens') return token
def process_refresh_token_response(self, response, *args, **kwargs): return parse_qs(response.content)
def _access_token_body(self, request, _url, headers, username): nonce = parse_qs(request.body).get('nonce') body = json.dumps(self.get_access_token_response(nonce, username)) return 200, headers, body
def get_querystring(self, url, *args, **kwargs): return parse_qs(self.request(url, *args, **kwargs).text)
def do_login_with_partial_pipeline(self, before_complete=None): self.strategy.set_settings({ 'SOCIAL_AUTH_GITHUB_KEY': 'a-key', 'SOCIAL_AUTH_GITHUB_SECRET': 'a-secret-key', 'SOCIAL_AUTH_LOGIN_REDIRECT_URL': self.login_redirect_url, 'SOCIAL_AUTH_AUTHENTICATION_BACKENDS': ('social.backends.github.GithubOAuth2', ), 'SOCIAL_AUTH_PIPELINE': ('social.pipeline.social_auth.social_details', 'social.pipeline.social_auth.social_uid', 'social.pipeline.social_auth.auth_allowed', 'social.pipeline.partial.save_status_to_session', 'social.tests.pipeline.ask_for_password', 'social.pipeline.social_auth.social_user', 'social.pipeline.user.get_username', 'social.pipeline.user.create_user', 'social.pipeline.social_auth.associate_user', 'social.pipeline.social_auth.load_extra_data', 'social.tests.pipeline.set_password', 'social.pipeline.user.user_details') }) start_url = do_auth(self.strategy).url target_url = self.strategy.build_absolute_uri( '/complete/github/?code=foobar') start_query = parse_qs(urlparse(start_url).query) location_url = target_url + ('?' in target_url and '&' or '?') + \ 'state=' + start_query['state'] location_query = parse_qs(urlparse(location_url).query) HTTPretty.register_uri(HTTPretty.GET, start_url, status=301, location=location_url) HTTPretty.register_uri(HTTPretty.GET, location_url, status=200, body='foobar') response = requests.get(start_url) expect(response.url).to.equal(location_url) expect(response.text).to.equal('foobar') HTTPretty.register_uri(HTTPretty.GET, uri=self.backend.ACCESS_TOKEN_URL, status=200, body=self.access_token_body or '', content_type='text/json') if self.user_data_url: HTTPretty.register_uri(HTTPretty.GET, self.user_data_url, body=self.user_data_body or '', content_type='text/json') self.strategy.set_request_data(location_query) def _login(strategy, user, social_user): strategy.session_set('username', user.username) redirect = do_complete(self.strategy, user=self.user, login=_login) url = self.strategy.build_absolute_uri('/password') expect(redirect.url).to.equal(url) HTTPretty.register_uri(HTTPretty.GET, redirect.url, status=200, body='foobar') HTTPretty.register_uri(HTTPretty.POST, redirect.url, status=200) password = '******' requests.get(url) requests.post(url, data={'password': password}) data = parse_qs(HTTPretty.last_request.body) expect(data['password']).to.equal(password) self.strategy.session_set('password', data['password']) if before_complete: before_complete() redirect = do_complete(self.strategy, user=self.user, login=_login) expect(self.strategy.session_get('username')).to.equal( self.expected_username) expect(redirect.url).to.equal(self.login_redirect_url)
def request_access_token(self, url, data, *args, **kwargs): response = self.request(url, params=data, *args, **kwargs) return parse_qs(response.content)