def test_urlencode_sequences(self): # Other tests incidentally urlencode things; test non-covered cases: # Sequence and object values. result = urllib_parse.urlencode({'a': [1, 2], 'b': (3, 4, 5)}, True) # we cannot rely on ordering here assert set(result.split('&')) == set(['a=1', 'a=2', 'b=3', 'b=4', 'b=5']) class Trivial(object): def __str__(self): return 'trivial' result = urllib_parse.urlencode({'a': Trivial()}, True) self.assertEqual(result, 'a=trivial')
def test_urlencode_sequences(self): # Other tests incidentally urlencode things; test non-covered cases: # Sequence and object values. result = urllib_parse.urlencode({'a': [1, 2], 'b': (3, 4, 5)}, True) # we cannot rely on ordering here assert set(result.split('&')) == set(['a=1', 'a=2', 'b=3', 'b=4', 'b=5']) class Trivial(object): def __str__(self): return 'trivial' result = urllib_parse.urlencode({'a': Trivial()}, True) self.assertEqual(result, 'a=trivial')
def person_card_to_words(self, picPath): access_token = self.__token__( ) if orc_baidu_token is None else orc_baidu_token url = 'https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=' + access_token # 二进制方式打开图文件 f = open(picPath, 'rb') # 参数image:图像base64编码 img = base64.b64encode(f.read()) params = { "image": img, "id_card_side": "front", "detect_direction": "true", "detect_risk": "true" } params = parse.urlencode(params).encode("utf-8") self.headers["Content-Type"] = 'application/x-www-form-urlencoded' request = Request(url, data=params, headers=self.headers) response = urlopen(request) content = response.read() result = {} if (content): words_result = (eval(bytes.decode(content))["words_result"]) for key in words_result: result[key] = words_result[key]["words"] print(result) return result
def test_registration_request(self): req = RegistrationRequest( operation="register", default_max_age=10, require_auth_time=True, default_acr="foo", application_type="web", redirect_uris=["https://example.com/authz_cb"]) assert req.verify() js = req.to_json() js_obj = json.loads(js) expected_js_obj = { "redirect_uris": ["https://example.com/authz_cb"], "application_type": "web", "default_acr": "foo", "require_auth_time": True, "operation": "register", "default_max_age": 10, "response_types": ["code"] } assert js_obj == expected_js_obj flattened_list_dict = { k: v[0] if isinstance(v, list) else v for k, v in expected_js_obj.items() } assert query_string_compare(req.to_urlencoded(), urlencode(flattened_list_dict))
def claims_ser(val, sformat="urlencoded", lev=0): # everything in c_extension if isinstance(val, six.string_types): item = val elif isinstance(val, list): item = val[0] else: item = val if isinstance(item, Message): return item.serialize(method=sformat, lev=lev + 1) if sformat == "urlencoded": res = urlencode(item) elif sformat == "json": if lev: res = item else: res = json.dumps(item) elif sformat == "dict": if isinstance(item, dict): res = item else: raise MessageException("Wrong type: %s" % type(item)) else: raise OicMsgError("Unknown sformat: %s" % sformat, val) return res
def set_start_page(oper, args): _conf = oper.sh['test_conf'] _url = _conf['start_page'] _iss = oper.conv.entity.baseurl _params = _conf['params'].replace('<issuer>', _iss) _args = dict([p.split('=') for p in _params.split('&')]) oper.start_page = _url + '?' + urlencode(_args)
def set_start_page(oper, args): _conf = oper.sh['test_conf'] _url = _conf['start_page'] _iss = oper.conv.entity.baseurl _params = _conf['params'].replace('<issuer>', _iss) _args = dict([p.split('=') for p in _params.split('&')]) oper.start_page = _url + '?' + urlencode(_args)
def create_redirect(self, query): """ Performs the redirect to the CAS server. :rtype : Response :param query: All query parameters to be added to the return_to URL after successful authentication. :return: A redirect response to the CAS server. """ try: req = parse_qs(query) acr = req['acr_values'][0] except KeyError: acr = None nonce = uuid.uuid4().get_urn() service_url = urlencode( {self.CONST_SERVICE: self.get_service_url(nonce, acr)}) cas_url = self.cas_server + self.CONST_CASLOGIN + service_url cookie = self.create_cookie( '{"' + self.CONST_NONCE + '": "' + base64.b64encode( nonce) + '", "' + self.CONST_QUERY + '": "' + base64.b64encode(query) + '"}', self.CONST_CAS_COOKIE, self.CONST_CAS_COOKIE) return SeeOther(cas_url, headers=[cookie])
def create_return_form_env(user, password, query): _dict = { "login": user, "password": password, "query": query } return urlencode(_dict)
def url_encode_params(params=None): if not isinstance(params, dict): raise InstantiationError("You must pass in a dictionary!") params_list = [] for k, v in params.items(): if isinstance(v, list): params_list.extend([(k, x) for x in v]) else: params_list.append((k, v)) return urlencode(params_list)
def url_encode_params(params=None): if not isinstance(params, dict): raise InstantiationError("You must pass in a dictionary!") params_list = [] for k, v in params.items(): if isinstance(v, list): params_list.extend([(k, x) for x in v]) else: params_list.append((k, v)) return urlencode(params_list)
def test_post_types(self): """Ensure various POST formats""" r = self.client.post('/bitbucket/', data=json.dumps(self.hg_payload), content_type='application/json') self.assertEqual(r.status_code, 200) r = self.client.post('/bitbucket/', data=urlencode({'payload': json.dumps(self.hg_payload)}), content_type='application/x-www-form-urlencoded') self.assertEqual(r.status_code, 200)
def update_url_with_kwargs(url, **kwargs): if not url: return url_parts = list(urlparse(url)) query = dict(parse_qsl(url_parts[4])) query.update(kwargs) url_parts[4] = urlencode(query) return urlunparse(url_parts)
def test_post_types(self): """Ensure various POST formats""" r = self.client.post('/bitbucket/', data=json.dumps(self.hg_payload), content_type='application/json') self.assertEqual(r.status_code, 200) r = self.client.post('/bitbucket/', data=urlencode({'payload': json.dumps(self.hg_payload)}), content_type='application/x-www-form-urlencoded') self.assertEqual(r.status_code, 200)
def test_parse_authz_without_code(self): sid, loc = self.consumer.begin("http://localhost:8087", "http://localhost:8088/authorization") atr = AuthorizationResponse(code="SplxlOBeZQQYbYS6WxSbIA", state=sid) adict = atr.to_dict() del adict["code"] with pytest.raises(MissingRequiredAttribute): self.consumer.handle_authorization_response(query=urlencode(adict))
def test_endsession_endpoint_with_id_token_hint(self): id_token = self._auth_with_id_token() assert self.provider.sdb.get_sids_by_sub( id_token["sub"]) # verify we got valid session id_token_hint = id_token.to_jwt(algorithm="none") resp = self.provider.endsession_endpoint( urlencode({"id_token_hint": id_token_hint})) assert not self.provider.sdb.get_sids_by_sub( id_token["sub"]) # verify session has been removed self._assert_cookies_expired(resp.headers)
def test_endsession_endpoint_with_id_token_hint(self): id_token = self._auth_with_id_token() assert self.provider.sdb.get_sids_by_sub( id_token["sub"]) # verify we got valid session id_token_hint = id_token.to_jwt(algorithm="none") resp = self.provider.endsession_endpoint( urlencode({"id_token_hint": id_token_hint})) assert not self.provider.sdb.get_sids_by_sub( id_token["sub"]) # verify session has been removed self._assert_cookies_expired(resp.headers)
def test_parse_authz_without_code(self): sid, loc = self.consumer.begin("http://localhost:8087", "http://localhost:8088/authorization") atr = AuthorizationResponse(code="SplxlOBeZQQYbYS6WxSbIA", state=sid) adict = atr.to_dict() del adict["code"] with pytest.raises(MissingRequiredAttribute): self.consumer.handle_authorization_response(query=urlencode(adict))
def test_endsession_endpoint_with_post_logout_redirect_uri(self): id_token = self._auth_with_id_token() assert self.provider.sdb.get_sids_by_sub( id_token["sub"]) # verify we got valid session post_logout_redirect_uri = \ CDB[CLIENT_CONFIG["client_id"]]["post_logout_redirect_uris"][0][0] resp = self.provider.endsession_endpoint(urlencode( {"post_logout_redirect_uri": post_logout_redirect_uri})) assert isinstance(resp, SeeOther) assert not self.provider.sdb.get_sids_by_sub( id_token["sub"]) # verify session has been removed self._assert_cookies_expired(resp.headers)
def test_begin(self): sid, loc = self.consumer.begin("http://localhost:8087", "http://localhost:8088/authorization") # state is dynamic params = {"scope": "openid", "state": sid, "redirect_uri": "http://localhost:8087/authz", "response_type": "code", "client_id": "number5"} url = "http://localhost:8088/authorization?{}".format(urlencode(params)) assert url_compare(loc, url)
def test_endsession_endpoint_with_post_logout_redirect_uri(self): id_token = self._auth_with_id_token() assert self.provider.sdb.get_sids_by_sub( id_token["sub"]) # verify we got valid session post_logout_redirect_uri = \ CDB[CLIENT_CONFIG["client_id"]]["post_logout_redirect_uris"][0][0] resp = self.provider.endsession_endpoint( urlencode({"post_logout_redirect_uri": post_logout_redirect_uri})) assert isinstance(resp, SeeOther) assert not self.provider.sdb.get_sids_by_sub( id_token["sub"]) # verify session has been removed self._assert_cookies_expired(resp.headers)
def gravatar(email, size=48): """ Hacked from djangosnippets.org, but basically given an email address render an img tag with the hashed up bits needed for leetness omgwtfstillreading """ url = "http://www.gravatar.com/avatar.php?%s" % urlencode({ 'gravatar_id': hashlib.md5(email).hexdigest(), 'size': str(size) }) return ('<img src="%s" width="%s" height="%s" alt="gravatar" ' 'class="gravatar" border="0" />' % (url, size, size))
def test_begin(self): sid, loc = self.consumer.begin("http://localhost:8087", "http://localhost:8088/authorization") # state is dynamic params = {"scope": "openid", "state": sid, "redirect_uri": "http://localhost:8087/authz", "response_type": "code", "client_id": "number5"} url = "http://localhost:8088/authorization?{}".format(urlencode(params)) assert url_compare(loc, url)
def post_logout_redirect_uri_with_query_component(oper, args): """ Context: AsyncAuthn Action: Add a query component to the post_logout_redirect_uri Args: Dictionary with keys and values to build the query part from Example: "post_logout_redirect_uri_with_query_component": {"foo": "bar"} """ ru = oper.conv.entity.registration_response['post_logout_redirect_uris'][0] ru += "?%s" % urlencode(args) oper.req_args.update({"post_logout_redirect_uri": [ru]})
def redirect_uris_with_query_component(oper, args): """ Context: AsyncAuthn Action: Add a query component to the redirect_uris Example: redirect_uris_with_query_component: foo: bar :param oper: An Operation Instance :param kwargs: Values to build the query part from """ ru = oper.conv.entity.registration_info['redirect_uris'][0] ru += "?%s" % urlencode(args) oper.req_args.update({"redirect_uris": [ru]})
def gravatar(email, size=48): """ Hacked from djangosnippets.org, but basically given an email address render an img tag with the hashed up bits needed for leetness omgwtfstillreading """ url = "http://www.gravatar.com/avatar.php?%s" % urlencode( { 'gravatar_id': hashlib.md5(email).hexdigest(), 'size': str(size) }) return ('<img src="%s" width="%s" height="%s" alt="gravatar" ' 'class="gravatar" border="0" />' % (url, size, size))
def redirect_uris_with_query_component(oper, args): """ Context: AsyncAuthn Action: Add a query component to the redirect_uris Example: redirect_uris_with_query_component: foo: bar :param oper: An Operation Instance :param kwargs: Values to build the query part from """ ru = oper.conv.entity.registration_info['redirect_uris'][0] ru += "?%s" % urlencode(args) oper.req_args.update({"redirect_uris": [ru]})
def test_parse_access_token_resp_missing_attribute(self): atresp = AccessTokenResponse(access_token="SlAV32hkKG", token_type="Bearer", refresh_token="8xLOxBtZp8", expire_in=3600) atdict = atresp.to_dict() del atdict["access_token"] # remove required access_token atj = json.dumps(atdict) with pytest.raises(MissingRequiredAttribute): self.client.parse_response(AccessTokenResponse, info=atj) with pytest.raises(MissingRequiredAttribute): self.client.parse_response(AccessTokenResponse, info=urlencode(atdict), sformat='urlencoded')
def test_set_quota_invalid_user(self): # Mock the command line call user = MagicMock() user.pw_uid = 1001 minarca_quota_api._getpwnam = MagicMock(return_value=user) # Make the query headers = [("Authorization", "Basic " + b64encode(b"minarca:secret").decode('ascii'))] body = urlencode([(b'size', b'2147483648')]) self.getPage('/quota/someuser', method='PUT', headers=headers, body=body) self.assertStatus(500) pass
def test_parse_access_token_resp_missing_attribute(self): atresp = AccessTokenResponse(access_token="SlAV32hkKG", token_type="Bearer", refresh_token="8xLOxBtZp8", expire_in=3600) atdict = atresp.to_dict() del atdict["access_token"] # remove required access_token atj = json.dumps(atdict) with pytest.raises(MissingRequiredAttribute): self.client.parse_response(AccessTokenResponse, info=atj) with pytest.raises(MissingRequiredAttribute): self.client.parse_response(AccessTokenResponse, info=urlencode(atdict), sformat='urlencoded')
def redirect_uris_with_query_component(oper, args): """ Context: Registration Action: Add a query component to the redirect_uris Args: Dictionary with attributes and values to build the query part from Example: "redirect_uris_with_query_component": { "foo": "bar" } """ ru = oper.conv.entity.registration_info['redirect_uris'][0] ru += "?%s" % urlencode(args) oper.req_args.update({"redirect_uris": [ru]})
def test_registration_request(self): req = RegistrationRequest(operation="register", default_max_age=10, require_auth_time=True, default_acr="foo", application_type="web", redirect_uris=[ "https://example.com/authz_cb"]) js = req.to_json() js_obj = json.loads(js) expected_js_obj = {"redirect_uris": ["https://example.com/authz_cb"], "application_type": "web", "default_acr": "foo", "require_auth_time": True, "operation": "register", "default_max_age": 10, "response_types": ["code"]} assert js_obj == expected_js_obj flattened_list_dict = {k: v[0] if isinstance(v, list) else v for k, v in expected_js_obj.items()} assert query_string_compare(req.to_urlencoded(), urlencode(flattened_list_dict))
def create_discovery_service_response(return_url=None, returnIDParam="entityID", entity_id=None, **kwargs): if return_url is None: return_url = kwargs["return"] if entity_id: qp = urlencode({returnIDParam: entity_id}) part = urlparse(return_url) if part.query: # Iff there is a query part add the new info at the end return_url = "%s&%s" % (return_url, qp) else: return_url = "%s?%s" % (return_url, qp) return return_url
def test_form_modify(): ori = [ ("a", "1"), ("b", "2"), ("a", "3"), ("d", "4"), ("f", ""), ] ori_text = parse.urlencode(ori) root = load(ori_text) root.children[1].reload("foo") # b=foo assert root.text == "a=1&b=foo&a=3&d=4&f=" assert root.data == QueryDict([('a', '1'), ('b', 'foo'), ('a', '3'), ('d', '4'), ('f', '')]) assert root.children[1].data == "foo" assert root.children[1].index_in_parent == 1
def test_set_quota(self): # Mock the command line call minarca_quota_api.subprocess.check_output = MagicMock(side_effect=[ '', '1121784464\n2147483648\n1122091872\n718078912672\n' ]) user = MagicMock() user.pw_uid = 1001 minarca_quota_api._getpwnam = MagicMock(return_value=user) # Make the query headers = [("Authorization", "Basic " + b64encode(b"minarca:secret").decode('ascii'))] body = urlencode([(b'size', b'2147483648')]) self.getPage('/quota/someuser', method='PUT', headers=headers, body=body) self.assertStatus(200) pass
def test_basic_form(): ori = [ ("a", "1"), ("b", "2"), ("a", "3"), ("d", "4"), ("f", ""), ] ori_text = parse.urlencode(ori) root = load(ori_text) assert isinstance(root, FormNode) assert root.data == QueryDict([('a', '1'), ('b', '2'), ('a', '3'), ('d', '4'), ('f', '')]) assert root.text == ori_text for index, node in enumerate(root.iter_tree()): assert isinstance(node, PlainNode) assert node.key == ori[index][0] assert node.data == ori[index][1] assert node.index_in_parent == index
def run(self): _client = self.conv.entity if 'add_state' in self.op_args: _state = rndstr(32) _client.logout_state2state[_state] = self.req_args['state'] self.op_args['state'] = self.req_args['state'] self.conv.end_session_state = _state self.req_args['state'] = _state logger.debug('req_args {}'.format(self.req_args)) logger.debug('op_args {}'.format(self.op_args)) url, body, ht_args, csi = _client.request_info( self.request, method=self.method, request_args=self.req_args, lax=True, **self.op_args) if 'remove_id_token_hint' in self.op_args: try: del csi['id_token_hint'] except KeyError: pass head, tail = url.split('?') _qs = parse_qs(tail) try: del _qs['id_token_hint'] except KeyError: pass _qs = {k: v[0] for k, v in _qs.items()} url = '{}?{}'.format(head, urlencode(_qs)) self.csi = csi self.conv.events.store(EV_REDIRECT_URL, url, sender=self.__class__.__name__) return Redirect(str(url))
def test_form_fork(): ori = [ ("a", "1"), ("b", "2"), ("a", "3"), ("d", "4"), ("f", ""), ] ori_text = parse.urlencode(ori) root = load(ori_text) # 新树的根节点 new_root = root.children[1].fork_tree("foo") # b=foo assert new_root.text == "a=1&b=foo&a=3&d=4&f=" assert new_root.data == QueryDict([('a', '1'), ('b', 'foo'), ('a', '3'), ('d', '4'), ('f', '')]) assert new_root.children[1].data == "foo" assert new_root.children[1].index_in_parent == 1 # 旧树不发生改变 assert root.data == QueryDict([('a', '1'), ('b', '2'), ('a', '3'), ('d', '4'), ('f', '')]) assert root.children[1] is not new_root.children[1]
def hands_pic_to_words(self, picPath): access_token = self.__token__( ) if orc_baidu_token is None else orc_baidu_token url = 'https://aip.baidubce.com/rest/2.0/ocr/v1/handwriting?access_token=' + access_token # 二进制方式打开图文件 f = open(picPath, 'rb') # 参数image:图像base64编码 img = base64.b64encode(f.read()) params = {"image": img} params = parse.urlencode(params).encode("utf-8") self.headers["Content-Type"] = 'application/x-www-form-urlencoded' request = Request(url, data=params, headers=self.headers) response = urlopen(request) content = response.read() result = "" if (content): words_result = (eval(bytes.decode(content))["words_result"]) for word in words_result: result = result + word["words"] print(result) return result
def test_full_flow(self): # make account linking request request_args = {"id": "id", "idp": "idp", "redirect_endpoint": "https://client.example.com/redirect_endpoint"} jws = JWS(json.dumps(request_args)).sign_compact([self.signing_key]) path_get_id = "/get_id?{}".format(urlencode({"jwt": jws})) resp = self.app.get(path_get_id) assert resp.status_code == 404 ticket = resp.data.decode("utf-8") # user gets redirected to the account linking page resp = self.app.get("/approve/{}".format(ticket)) assert resp.status_code == 200 # redirect user to create an account page resp = self.app.post("/create_account") assert resp.status_code == 200 # send token by email (faked by writing it to a file) resp = self.app.post("/send_token", data={"email": "*****@*****.**"}) assert resp.status_code == 200 # get token from file with open("token") as f: token = f.read() # verify token resp = self.app.post("/verify_token", data={"token": token}) assert resp.status_code == 200 # save account with a pin code resp = self.app.post("/save_account", data={"pin": "!AbC123#"}) assert resp.status_code == 302 assert resp.headers["Location"] == request_args["redirect_endpoint"] # get the id resp = self.app.get(path_get_id) assert resp.status_code == 200 assert resp.data.decode("utf-8")
def test_deep_mutant_complex(): """测试复杂的包含递归的项""" fz = make_complex_req() fz.query["c"] = json.dumps(dict( j="son", f="yet=another&form=1", )) fz.data["e"] = parse.urlencode([ ("cat", "dog"), ("j2", '{"foo":"bar"}'), ]) mutant = DeepMutant(DummyPayloadFactory) expected = [ # query b"/anything?a=a__1&b=2&c=%7B%22j%22%3A+%22son%22%2C+%22f%22%3A+%22yet%3Danother%26form%3D1%22%7D&a=x&a=y", b"/anything?a=1&b=b__2&c=%7B%22j%22%3A+%22son%22%2C+%22f%22%3A+%22yet%3Danother%26form%3D1%22%7D&a=x&a=y", b"/anything?a=1&b=2&c=c__%7B%22j%22%3A+%22son%22%2C+%22f%22%3A+%22yet%3Danother%26form%3D1%22%7D&a=x&a=y", b"/anything?a=1&b=2&c=%7B%22j%22%3A+%22son%22%2C+%22f%22%3A+%22yet%3Danother%26form%3D1%22%7D&a=a__x&a=y", b"/anything?a=1&b=2&c=%7B%22j%22%3A+%22son%22%2C+%22f%22%3A+%22yet%3Danother%26form%3D1%22%7D&a=x&a=a__y", b"/anything?a=1&b=2&c=%7B%22j%22%3A+%22j__son%22%2C+%22f%22%3A+%22yet%3Danother%26form%3D1%22%7D&a=x&a=y", b"/anything?a=1&b=2&c=%7B%22j%22%3A+%22son%22%2C+%22f%22%3A+%22f__yet%3Danother%26form%3D1%22%7D&a=x&a=y", b"/anything?a=1&b=2&c=%7B%22j%22%3A+%22son%22%2C+%22f%22%3A+%22yet%3Dyet__another%26form%3D1%22%7D&a=x&a=y", b"/anything?a=1&b=2&c=%7B%22j%22%3A+%22son%22%2C+%22f%22%3A+%22yet%3Danother%26form%3Dform__1%22%7D&a=x&a=y", # data b"a=a__b&c=d&c=e&e=cat%3Ddog%26j2%3D%257B%2522foo%2522%253A%2522bar%2522%257D&x=f", b"a=b&c=c__d&c=e&e=cat%3Ddog%26j2%3D%257B%2522foo%2522%253A%2522bar%2522%257D&x=f", b"a=b&c=d&c=c__e&e=cat%3Ddog%26j2%3D%257B%2522foo%2522%253A%2522bar%2522%257D&x=f", b"a=b&c=d&c=e&e=e__cat%3Ddog%26j2%3D%257B%2522foo%2522%253A%2522bar%2522%257D&x=f", b"a=b&c=d&c=e&e=cat%3Ddog%26j2%3D%257B%2522foo%2522%253A%2522bar%2522%257D&x=x__f", b"a=b&c=d&c=e&e=cat%3Dcat__dog%26j2%3D%257B%2522foo%2522%253A%2B%2522bar%2522%257D&x=f", b"a=b&c=d&c=e&e=cat%3Ddog%26j2%3Dj2__%257B%2522foo%2522%253A%2B%2522bar%2522%257D&x=f", b"a=b&c=d&c=e&e=cat%3Ddog%26j2%3D%257B%2522foo%2522%253A%2B%2522foo__bar%2522%257D&x=f", ] for atk_fz, correct in zip(mutant.make(fz), expected): assert correct in atk_fz.to_bare()
def bank_card_to_words(self, picPath): access_token = self.__token__( ) if orc_baidu_token is None else orc_baidu_token url = 'https://aip.baidubce.com/rest/2.0/ocr/v1/bankcard?access_token=' + access_token # 二进制方式打开图文件 f = open(picPath, 'rb') # 参数image:图像base64编码 img = base64.b64encode(f.read()) params = {"image": img} params = parse.urlencode(params).encode("utf-8") self.headers["Content-Type"] = 'application/x-www-form-urlencoded' request = Request(url, data=params, headers=self.headers) response = urlopen(request) content = response.read() result = "" if (content): words_result = (eval(bytes.decode(content))["result"]) result = words_result print(result) return result #BaiduApi().person_card_to_words(os.path.abspath("../temp/card.jpg"))
def msg_ser(inst, sformat, lev=0): if sformat in ["urlencoded", "json"]: if isinstance(inst, dict): if sformat == 'json': res = json.dumps(inst) else: res = urlencode([(k, v) for k, v in inst.items()]) elif isinstance(inst, Message): res = inst.serialize(sformat, lev) else: res = inst elif sformat == "dict": if isinstance(inst, Message): res = inst.serialize(sformat, lev) elif isinstance(inst, dict): res = inst elif isinstance(inst, six.string_types): # Iff ID Token res = inst else: raise MessageException("Wrong type: %s" % type(inst)) else: raise OicMsgError("Unknown sformat", inst) return res
def application(environ, start_response): session = environ['beaker.session'] path = environ.get('PATH_INFO', '').lstrip('/') if path == "robots.txt": return static(environ, start_response, LOGGER, "static/robots.txt") elif path.startswith("static/"): return static(environ, start_response, LOGGER, path) query = parse_qs(environ["QUERY_STRING"]) acr_values = session._params['acrs'] clients = session._params['clients'] server_env = session._params['server_env'] LOGGER.info(50 * "=") LOGGER.info("[{}] path: {}".format(session.id, path)) LOGGER.info(50 * "=") if path == '': if 'access_token' not in session: return opchoice(environ, start_response, clients) else: client = clients[session["op"]] check_session_iframe_url = None try: check_session_iframe_url = client.provider_info[ "check_session_iframe"] session["session_management"] = { "session_state": query["session_state"][0], "client_id": client.client_id, "issuer": client.provider_info["issuer"] } except KeyError: pass kwargs = dict( [(p, session[p]) for p in ['id_token', 'userinfo', 'user_id'] if p in session]) return opresult(environ, start_response, **kwargs) elif path == "rp": # After having chosen which OP to authenticate at if "uid" in query: try: client = clients.dynamic_client(userid=query["uid"][0]) except (ConnectionError, OIDCError) as err: return operror(environ, start_response, '{}'.format(err)) elif 'issuer' in query: try: client = clients[query["issuer"][0]] except KeyError: try: client = clients.dynamic_client(issuer=query["issuer"][0]) except (ConnectionError, OIDCError) as err: return operror(environ, start_response, '{}'.format(err)) else: client = clients[query["op"][0]] client.get_userinfo = session._params['userinfo'] try: client.resource_server = session._params['resource_server'] except KeyError: pass try: session['response_format'] = query["response_format"][0] except KeyError: session['response_format'] = 'html' session["op"] = client.provider_info["issuer"] try: resp = client.create_authn_request(session, acr_values) except Exception: raise else: return resp(environ, start_response) elif path.endswith('authz_post'): try: _iss = session['op'] except KeyError: LOGGER.info( '[{}] No active session with {}'.format(session.id, environ['REMOTE_ADDR'])) return opchoice(environ, start_response, clients) else: client = clients[_iss] query = parse_qs(get_post(environ)) try: info = query["fragment"][0] except KeyError: return sorry_response(environ, start_response, conf.BASE, "missing fragment ?!") if info == ['x']: return sorry_response(environ, start_response, conf.BASE, "Expected fragment didn't get one ?!") LOGGER.info('[{}] Fragment part: {}'.format(session.id, info)) try: result = client.callback(info, session, 'urlencoded') if isinstance(result, SeeOther): return result(environ, start_response) except OIDCError as err: return operror(environ, start_response, "%s" % err) except Exception as err: raise else: session.update(result) res = SeeOther(location=server_env['base_url']) return res(environ, start_response) elif path in clients.return_paths(): # After having authenticated at the OP try: _iss = session['op'] except KeyError: LOGGER.info( '[{}]No active session with {}'.format(session.id, environ['REMOTE_ADDR'])) return opchoice(environ, start_response, clients) # mismatch between callback and return_uri if _iss != clients.path[path]: LOGGER.warning( '[{}]issuer mismatch: {} != {}'.format(session.id, _iss, clients.path[path])) return operror(environ, start_response, "%s" % 'Not allowed') client = clients[session["op"]] _response_type = client.behaviour["response_type"] try: _response_mode = client.authz_req[session['state']]['response_mode'] except KeyError: _response_mode = '' LOGGER.info( "[{}]response_type: {}, response_mode: {}".format(session.id, _response_type, _response_mode)) if _response_type and _response_type != "code": # Fall through if it's a query response anyway if query: pass elif _response_mode: # form_post encoded pass else: return opresult_fragment(environ, start_response) LOGGER.info("[{}]Query part: {}".format(session.id, query)) try: result = client.callback(query, session) if isinstance(result, SeeOther): return result(environ, start_response) except OIDCError as err: return operror(environ, start_response, "%s" % err) except Exception: raise else: session.update(result) res = SeeOther(server_env['base_url']) return res(environ, start_response) elif path == "logout": # After the user has pressed the logout button try: _iss = session['op'] except KeyError: LOGGER.info( '[{}]No active session with {}'.format(session.id, environ['REMOTE_ADDR'])) return opchoice(environ, start_response, clients) client = clients[_iss] try: del client.authz_req[session['state']] except KeyError: pass logout_url = client.end_session_endpoint try: # Specify to which URL the OP should return the user after # log out. That URL must be registered with the OP at client # registration. logout_url += "?" + urlencode( {"post_logout_redirect_uri": client.registration_response[ "post_logout_redirect_uris"][0]}) except KeyError: pass else: # If there is an ID token send it along as a id_token_hint _idtoken = get_id_token(client, session) if _idtoken: logout_url += "&" + urlencode({ "id_token_hint": id_token_as_signed_jwt(client, _idtoken, "HS256")}) # Also append the ACR values logout_url += "&" + urlencode({"acr_values": acr_values}, True) LOGGER.debug("[{}]Logout URL: {}".format(session.id, logout_url)) LOGGER.debug("Logging out from session: [{}]".format(session.id)) session.delete() resp = SeeOther(str(logout_url)) return resp(environ, start_response) elif path == "logout_success": # post_logout_redirect_uri return Response("Logout successful!")(environ, start_response) elif path == "session_iframe": # session management kwargs = session["session_management"] resp = Response(mako_template="rp_session_iframe.mako", template_lookup=LOOKUP) return resp(environ, start_response, session_change_url="{}session_change".format( server_env["base_url"]), **kwargs) elif path == "session_change": try: _iss = session['op'] except KeyError: LOGGER.info( '[{}]No active session with {}'.format(session.id, environ['REMOTE_ADDR'])) return opchoice(environ, start_response, clients) try: client = clients[_iss] except KeyError: return Response("No valid session.")(environ, start_response) kwargs = {"prompt": "none"} # If there is an ID token send it along as a id_token_hint idt = get_id_token(client, session) if idt: kwargs["id_token_hint"] = id_token_as_signed_jwt(client, idt, "HS256") resp = client.create_authn_request(session, acr_values, **kwargs) return resp(environ, start_response) return opchoice(environ, start_response, clients)
def _pick_idp(self, query, end_point_index): """ If more than one idp and if none is selected, I have to do wayf or disco """ query_dict = {} if isinstance(query, six.string_types): query_dict = dict(parse_qs(query)) else: for key, value in six.iteritems(query): if isinstance(value, list): query_dict[key] = value[0] else: query_dict[key] = value query = urlencode(query_dict) _cli = self.sp # Find all IdPs idps = self.sp.metadata.with_descriptor("idpsso") idp_entity_id = None if len(idps) == 1: # idps is a dictionary idp_entity_id = list(idps.keys())[0] if not idp_entity_id and query: try: _idp_entity_id = query_dict[self.idp_query_param][0] if _idp_entity_id in idps: idp_entity_id = _idp_entity_id except KeyError: logger.debug("No IdP entity ID in query: %s" % query) pass if not idp_entity_id: cookie = self.create_cookie( '{"' + self.CONST_QUERY + '": "' + base64.b64encode(query) + '" , "' + self.CONST_HASIDP + '": "False" }', self.CONST_SAML_COOKIE, self.CONST_SAML_COOKIE) if self.sp_conf.WAYF: if query: try: wayf_selected = query_dict["wayf_selected"][0] except KeyError: return self._wayf_redirect(cookie) idp_entity_id = wayf_selected else: return self._wayf_redirect(cookie) elif self.sp_conf.DISCOSRV: if query: idp_entity_id = _cli.parse_discovery_service_response(query=query) if not idp_entity_id: sid_ = sid() self.cache_outstanding_queries[sid_] = self.verification_endpoint eid = _cli.config.entityid disco_end_point_index = end_point_index["disco_end_point_index"] ret = _cli.config.getattr("endpoints", "sp")[ "discovery_response"][disco_end_point_index][0] ret += "?sid=%s" % sid_ loc = _cli.create_discovery_service_request( self.sp_conf.DISCOSRV, eid, **{"return": ret}) return -1, SeeOther(loc, headers=[cookie]) elif not len(idps): raise ServiceErrorException( 'Misconfiguration for the SAML Service Provider!') else: return -1, NotImplemented("No WAYF or DS present!") return 0, idp_entity_id
def to_urlencoded(self, lev=0): """ Creates a string using the application/x-www-form-urlencoded format :return: A string of the application/x-www-form-urlencoded format """ _spec = self.c_param if not self.lax: for attribute, (_, req, _ser, _, na) in _spec.items(): if req and attribute not in self._dict: raise MissingRequiredAttribute("%s" % attribute, "%s" % self) params = [] for key, val in self._dict.items(): try: (_, req, _ser, _, null_allowed) = _spec[key] except KeyError: # extra attribute try: _key, lang = key.split("#") (_, req, _ser, _deser, null_allowed) = _spec[_key] except (ValueError, KeyError): try: (_, req, _ser, _, null_allowed) = _spec['*'] except KeyError: _ser = None null_allowed = False if val is None and null_allowed is False: continue elif isinstance(val, six.string_types): # Should I allow parameters with "" as value ??? params.append((key, val.encode("utf-8"))) elif isinstance(val, list): if _ser: params.append((key, str(_ser(val, sformat="urlencoded", lev=lev)))) else: for item in val: params.append((key, str(item).encode('utf-8'))) elif isinstance(val, Message): try: _val = json.dumps(_ser(val, sformat="dict", lev=lev + 1)) params.append((key, _val)) except TypeError: params.append((key, val)) elif val is None: params.append((key, val)) else: try: params.append((key, _ser(val, lev=lev))) except Exception: params.append((key, str(val))) try: return urlencode(params) except UnicodeEncodeError: _val = [] for k, v in params: try: _val.append((k, v.encode("utf-8"))) except TypeError: _val.append((k, v)) return urlencode(_val)
def authorization_endpoint(self, request="", cookie=None, **kwargs): if isinstance(request, dict): _req = request else: _req = {} for key, val in parse_qs(request).items(): if len(val) == 1: _req[key] = val[0] else: _req[key] = val # self.events.store(EV_REQUEST, _req) try: _scope = _req["scope"] except KeyError: return error_response( error="incorrect_behavior", descr="No scope parameter" ) else: # verify that openid is among the scopes _scopes = _scope.split(" ") if "openid" not in _scopes: return error_response( error="incorrect_behavior", descr="Scope does not contain 'openid'" ) client_id = _req["client_id"] try: f = response_type_cmp(self.capabilities['response_types_supported'], _req['response_type']) except KeyError: pass else: if f is False: self.events.store( EV_FAULT, 'Wrong response type: {}'.format(_req['response_type'])) return error_response(error="incorrect_behavior", descr="Not supported response_type") _rtypes = _req['response_type'].split(' ') if 'id_token' in _rtypes: try: self._update_client_keys(client_id) except TestError: return error_response(error="incorrect_behavior", descr="No change in client keys") if isinstance(request, dict): request = urlencode(request) if "max_age" in _req and _req["max_age"] == "0" and "prompt" in _req and _req["prompt"] == "none": aresp = { "error": "login_required", } if "state" in _req: aresp['state'] = _req["state"] return self.response_mode(_req, False, aresp=aresp, redirect_uri=_req['redirect_uri'], headers={}) else: _response = provider.Provider.authorization_endpoint(self, request, cookie, **kwargs) if "rotenc" in self.behavior_type: # Rollover encryption keys rsa_key = RSAKey(kid="rotated_rsa_{}".format(time.time()), use="enc").load_key(RSA.generate(2048)) ec_key = ECKey(kid="rotated_ec_{}".format(time.time()), use="enc").load_key(P256) keys = [rsa_key.serialize(private=True), ec_key.serialize(private=True)] new_keys = {"keys": keys} self.events.store("New encryption keys", new_keys) self.do_key_rollover(new_keys, "%d") self.events.store("Rotated encryption keys", '') logger.info( 'Rotated OP enc keys, new set: {}'.format( key_summary(self.keyjar, ''))) # This is just for logging purposes try: _resp = self.server.http_request(_req["request_uri"]) except KeyError: pass except requests.ConnectionError as err: self.events.store(EV_EXCEPTION, err) err = unwrap_exception(err) return error_response(error="server_error", descr=err) else: if _resp.status_code == 200: self.events.store(EV_REQUEST, "Request from request_uri: {}".format( _resp.text)) return _response
def redirect_uris_with_query_component(oper, kwargs): ru = oper.conv.get_redirect_uris()[0] ru += "?%s" % urlencode(kwargs) oper.req_args["redirect_uris"] = ru
def redirect_uri_with_query_component(oper, args): ru = oper.conv.get_redirect_uris()[0] ru += "?%s" % urlencode(args) oper.req_args.update({"redirect_uri": ru})
def application(environ, start_response): session = Session(environ['beaker.session']) path = environ.get('PATH_INFO', '').lstrip('/') if path == "robots.txt": return static(environ, start_response, LOGGER, "static/robots.txt") if path.startswith("static/"): return static(environ, start_response, LOGGER, path) query = parse_qs(environ["QUERY_STRING"]) if path == "logout": try: logoutUrl = session['client'].end_session_endpoint plru = "{}post_logout".format(SERVER_ENV["base_url"]) logoutUrl += "?" + urlencode({"post_logout_redirect_uri": plru}) try: logoutUrl += "&" + urlencode({ "id_token_hint": id_token_as_signed_jwt( session['client'], "HS256")}) except AttributeError as err: pass session.clear() resp = SeeOther(str(logoutUrl)) return resp(environ, start_response) except Exception as err: pass if path == "post_logout": return post_logout(environ, start_response) if session['callback']: _uri = "%s%s" % (conf.BASE, path) for _cli in SERVER_ENV["OIC_CLIENT"].values(): if _uri in _cli.redirect_uris: session['callback'] = False func = getattr(RP, "callback") return func(environ, SERVER_ENV, start_response, query, session) if path == "rpAcr": return choose_acr_value(environ, start_response, session) if path == "rpAuth": # Only called if multiple arc_values (that is authentications) exists. if "acr" in query and query["acr"][0] in session['acr_values']: func = getattr(RP, "create_authnrequest") return func(environ, SERVER_ENV, start_response, session, query["acr"][0]) if session["client"] is not None: session['callback'] = True func = getattr(RP, "begin") return func(environ, SERVER_ENV, start_response, session, "") if path == "rp": if "uid" in query: try: link = RP.find_srv_discovery_url(resource=query["uid"][0]) except requests.ConnectionError: resp = ServiceError("Webfinger lookup failed, connection error") return resp(environ, start_response) RP.srv_discovery_url = link md5 = hashlib.md5() md5.update(link.encode("utf-8")) opkey = base64.b16encode(md5.digest()).decode("utf-8") session['callback'] = True func = getattr(RP, "begin") return func(environ, SERVER_ENV, start_response, session, opkey) return opbyuid(environ, start_response)
def _pick_idp(self, query, end_point_index): """ If more than one idp and if none is selected, I have to do wayf or disco """ query_dict = {} if isinstance(query, six.string_types): query_dict = dict(parse_qs(query)) else: for key, value in six.iteritems(query): if isinstance(value, list): query_dict[key] = value[0] else: query_dict[key] = value query = urlencode(query_dict) _cli = self.sp # Find all IdPs idps = self.sp.metadata.with_descriptor("idpsso") idp_entity_id = None if len(idps) == 1: # idps is a dictionary idp_entity_id = list(idps.keys())[0] if not idp_entity_id and query: try: _idp_entity_id = query_dict[self.idp_query_param][0] if _idp_entity_id in idps: idp_entity_id = _idp_entity_id except KeyError: logger.debug("No IdP entity ID in query: %s" % query) pass if not idp_entity_id: cookie = self.create_cookie( '{"' + self.CONST_QUERY + '": "' + base64.b64encode(query) + '" , "' + self.CONST_HASIDP + '": "False" }', self.CONST_SAML_COOKIE, self.CONST_SAML_COOKIE) if self.sp_conf.WAYF: if query: try: wayf_selected = query_dict["wayf_selected"][0] except KeyError: return self._wayf_redirect(cookie) idp_entity_id = wayf_selected else: return self._wayf_redirect(cookie) elif self.sp_conf.DISCOSRV: if query: idp_entity_id = _cli.parse_discovery_service_response(query=query) if not idp_entity_id: sid_ = sid() self.cache_outstanding_queries[sid_] = self.verification_endpoint eid = _cli.config.entityid disco_end_point_index = end_point_index["disco_end_point_index"] ret = _cli.config.getattr("endpoints", "sp")[ "discovery_response"][disco_end_point_index][0] ret += "?sid=%s" % sid_ loc = _cli.create_discovery_service_request( self.sp_conf.DISCOSRV, eid, **{"return": ret}) return -1, SeeOther(loc, headers=[cookie]) elif not len(idps): raise ServiceErrorException( 'Misconfiguration for the SAML Service Provider!') else: return -1, NotImplemented("No WAYF or DS present!") return 0, idp_entity_id
def application(self, environ, start_response): b_session = environ['beaker.session'] jlog = JLog(LOGGER, b_session.id) path = environ.get('PATH_INFO', '').lstrip('/') try: jlog.info({'cookie': environ['HTTP_COOKIE'].split(';'), 'path': path}) except KeyError: jlog.info({'path': path}) if path == "robots.txt": return static(environ, start_response, LOGGER, "static/robots.txt") elif path.startswith("static/"): return static(environ, start_response, LOGGER, path) elif '/static/' in path: pre, post = path.split('static') return static(environ, start_response, LOGGER, 'static' + post) query = parse_qs(environ["QUERY_STRING"]) try: session = b_session['session_info'] except KeyError: session = self.find_session(**query) if session: b_session['session_info'] = session else: session = {} b_session['session_info'] = session self.session[b_session.id] = session if path == '': if 'access_token' not in session: return opchoice(environ, start_response, self.clients) else: client = self.clients[session["op"]] # check_session_iframe_url = None try: # check_session_iframe_url = client.provider_info[ # "check_session_iframe"] session["session_management"] = { "session_state": query["session_state"][0], "client_id": client.client_id, "issuer": client.provider_info["issuer"] } except KeyError: pass kwargs = dict( [(p, session[p]) for p in ['id_token', 'userinfo', 'user_id'] if p in session]) return opresult(environ, start_response, **kwargs) elif path == "rp": # After having chosen which OP to authenticate at if "uid" in query: try: client = self.clients.dynamic_client(userid=query["uid"][0]) except (ConnectionError, OIDCError) as err: return operror(environ, start_response, '{}'.format(err)) elif 'issuer' in query: try: client = self.clients[query["issuer"][0]] except (ConnectionError, OIDCError) as err: return operror(environ, start_response, '{}'.format(err)) else: client = self.clients[query["op"][0]] return self.init_client(client, session, query, environ, start_response) elif path.endswith('authz_post'): try: _iss = session['op'] except KeyError: jlog.error({'reason': 'No active session', 'remote_addr': environ['REMOTE_ADDR']}) return opchoice(environ, start_response, self.clients) else: client = self.clients[_iss] query = parse_qs(get_post(environ)) try: info = query["fragment"][0] except KeyError: return sorry_response(environ, start_response, self.base, "missing fragment ?!") if info == ['x']: return sorry_response(environ, start_response, self.base, "Expected fragment didn't get one ?!") jlog.info({'fragment': info}) try: result = client.callback(info, session, 'urlencoded') if isinstance(result, SeeOther): return result(environ, start_response) except OIDCError as err: return operror(environ, start_response, "%s" % err) except Exception as err: raise else: session.update(result) res = SeeOther(self.conf['base_url']) return res(environ, start_response) elif path in self.clients.return_paths(): # After having # authenticated at the OP jlog.info({'query': query}) _client = None for cli in self.clients.client.values(): if query['state'][0] in cli.authz_req: _client = cli break if not _client: jlog.error({ 'reason': 'No active session', 'remote_addr': environ['REMOTE_ADDR'], 'state': query['state'][0] }) return opchoice(environ, start_response, self.clients) if 'error' in query: # something amiss if query['error'][0] == 'access_denied': # Try reregistering _iss = _client.provider_info['issuer'] del self.clients[_iss] try: client = self.clients[_iss] except (ConnectionError, OIDCError) as err: return operror(environ, start_response, '{}'.format(err)) return self.init_client(client, session, query, environ, start_response) try: _iss = query['iss'][0] except KeyError: pass else: if _iss != _client.provider_info['issuer']: jlog.error({'reason': 'Got response from wrong OP'}) return opchoice(environ, start_response, self.clients) _response_type = _client.behaviour["response_type"] try: _response_mode = _client.authz_req[session['state']][ 'response_mode'] except KeyError: _response_mode = '' jlog.info({ "response_type": _response_type, "response_mode": _response_mode}) if _response_type and _response_type != "code": # Fall through if it's a query response anyway if query: pass elif _response_mode: # form_post encoded pass else: return opresult_fragment(environ, start_response) try: result = _client.callback(query, session) if isinstance(result, SeeOther): return result(environ, start_response) except OIDCError as err: return operror(environ, start_response, "%s" % err) except Exception: raise else: session.update(result) res = SeeOther(self.conf['base_url']) return res(environ, start_response) elif path == "logout": # After the user has pressed the logout button try: _iss = session['op'] except KeyError: jlog.error( {'reason': 'No active session', 'remote_addr': environ['REMOTE_ADDR']}) return opchoice(environ, start_response, self.clients) client = self.clients[_iss] try: del client.authz_req[session['state']] except KeyError: pass logout_url = client.end_session_endpoint try: # Specify to which URL the OP should return the user after # log out. That URL must be registered with the OP at client # registration. logout_url += "?" + urlencode( {"post_logout_redirect_uri": client.registration_response[ "post_logout_redirect_uris"][0]}) except KeyError: pass else: # If there is an ID token send it along as a id_token_hint _idtoken = get_id_token(client, session) if _idtoken: logout_url += "&" + urlencode({ "id_token_hint": id_token_as_signed_jwt(client, _idtoken, "HS256")}) # Also append the ACR values logout_url += "&" + urlencode({"acr_values": self.acr_values}, True) session.delete() resp = SeeOther(str(logout_url)) return resp(environ, start_response) elif path == "logout_success": # post_logout_redirect_uri return Response("Logout successful!")(environ, start_response) elif path == "session_iframe": # session management kwargs = session["session_management"] resp = Response(mako_template="rp_session_iframe.mako", template_lookup=LOOKUP) return resp(environ, start_response, session_change_url="{}session_change".format( self.conf["base_url"]), **kwargs) elif path == "session_change": try: _iss = session['op'] except KeyError: jlog.error({ 'reason': 'No active session', 'remote_addr': environ['REMOTE_ADDR']}) return opchoice(environ, start_response, self.clients) try: client = self.clients[_iss] except KeyError: return Response("No valid session.")(environ, start_response) kwargs = {"prompt": "none"} # If there is an ID token send it along as a id_token_hint idt = get_id_token(client, session) if idt: kwargs["id_token_hint"] = id_token_as_signed_jwt(client, idt, "HS256") resp = client.create_authn_request(session, self.acr_values, **kwargs) return resp(environ, start_response) return opchoice(environ, start_response, self.clients)