class UMAUserInfo(UserInfo): def __init__(self, client_name, redirect_uris, resource_srv, acr, verify_ssl=True): UserInfo.__init__(self) # The UMA Client reginfo = {"client_name": client_name, "application_type": "native", "redirect_uris": redirect_uris} self.client = Client( {}, client_authn_methods=CLIENT_AUTHN_METHOD, registration_info=reginfo, verify_ssl=verify_ssl ) self.client.redirect_uris = redirect_uris self.resource_srv = resource_srv self.acr = acr def __call__(self, user, requestor, attrs=None, state="", **kwargs): """ This is the main API :param user: user identifier :param requestor: The entity_id of the SP that requests the information :param attrs: which attributes to return :param state: Where in the process am I """ return self.get_info(user, requestor, attrs, state, **kwargs) def rs_query(self, sp_user, user, attr=None): """ :param sp_user: an identifier representing the tuple (user, sp) :param user: user identifier common with the backend system """ try: rpt = self.client.token[sp_user]["RPT"] except KeyError: rpt = None url = create_query(self.resource_srv, urllib.parse.quote(user), attr) if rpt: kwargs = {"headers": {"Authorization": "Bearer %s" % rpt}} else: kwargs = {} return self.client.send(url, "GET", **kwargs) def get_info(self, user, requestor, attrs=None, state="", **kwargs): """ :param user: user identifier :param requestor: The entity_id of the SP that requests the information :param attrs: which attributes to return :param state: Where in the process am I """ # The real requestor is <user>@<sp_entity_id> user_and_sp = "%s@%s" % (user, requestor) resp = self.rs_query(user_and_sp, user, attrs) args = {} for attr in ["authn_method", "password"]: try: args[attr] = kwargs[attr] except KeyError: args[attr] = "" if resp.status_code == 200: return Response(resp.text) if resp.status_code == 401: # No RPT as_uri = resp.headers["as_uri"] return self.client.acquire_grant(as_uri, "RPT", user_and_sp, state, self.acr, **args) # if isinstance(resp, Redirect): # which it should be # redirect that are part of the grant code flow # return resp # elif resp.status_code == 200: # ??? # return Response(resp.text) # else: # return R2C[resp.status_code](resp.text) if resp.status_code == 403: # Permission registered, got ticket if state == "403": # loop ? return {} prr = PermissionRegistrationResponse().from_json(resp.text) resp = self.client.authorization_data_request(user_and_sp, prr["ticket"]) if resp.status_code in (200, 201): return self.get_info(user, requestor, attrs, "403") raise UMAError() def get_tokens(self, query): aresp = AuthorizationResponse().from_urlencoded(query) uid = self.client.acquire_access_token(aresp, "AAT") self.client.get_rpt(uid) return uid
class UMAUserInfo(UserInfo): def __init__(self, client_name, redirect_uris, resource_srv, acr, verify_ssl=True): UserInfo.__init__(self) # The UMA Client reginfo = { "client_name": client_name, "application_type": "native", "redirect_uris": redirect_uris } self.client = Client({}, client_authn_methods=CLIENT_AUTHN_METHOD, registration_info=reginfo, verify_ssl=verify_ssl) self.client.redirect_uris = redirect_uris self.resource_srv = resource_srv self.acr = acr def __call__(self, user, requestor, attrs=None, state="", **kwargs): """ This is the main API :param user: user identifier :param requestor: The entity_id of the SP that requests the information :param attrs: which attributes to return :param state: Where in the process am I """ return self.get_info(user, requestor, attrs, state, **kwargs) def rs_query(self, sp_user, user, attr=None): """ :param sp_user: an identifier representing the tuple (user, sp) :param user: user identifier common with the backend system """ try: rpt = self.client.token[sp_user]["RPT"] except KeyError: rpt = None url = create_query(self.resource_srv, urllib.parse.quote(user), attr) if rpt: kwargs = {"headers": {"Authorization": "Bearer %s" % rpt}} else: kwargs = {} return self.client.send(url, "GET", **kwargs) def get_info(self, user, requestor, attrs=None, state="", **kwargs): """ :param user: user identifier :param requestor: The entity_id of the SP that requests the information :param attrs: which attributes to return :param state: Where in the process am I """ # The real requestor is <user>@<sp_entity_id> user_and_sp = "%s@%s" % (user, requestor) resp = self.rs_query(user_and_sp, user, attrs) args = {} for attr in ["authn_method", "password"]: try: args[attr] = kwargs[attr] except KeyError: args[attr] = "" if resp.status_code == 200: return Response(resp.text) if resp.status_code == 401: # No RPT as_uri = resp.headers["as_uri"] return self.client.acquire_grant(as_uri, "RPT", user_and_sp, state, self.acr, **args) #if isinstance(resp, Redirect): # which it should be # redirect that are part of the grant code flow # return resp # elif resp.status_code == 200: # ??? # return Response(resp.text) # else: # return R2C[resp.status_code](resp.text) if resp.status_code == 403: # Permission registered, got ticket if state == "403": # loop ? return {} prr = PermissionRegistrationResponse().from_json(resp.text) resp = self.client.authorization_data_request( user_and_sp, prr["ticket"]) if resp.status_code in (200, 201): return self.get_info(user, requestor, attrs, "403") raise UMAError() def get_tokens(self, query): aresp = AuthorizationResponse().from_urlencoded(query) uid = self.client.acquire_access_token(aresp, "AAT") self.client.get_rpt(uid) return uid
class UmaCAS(object): def __init__( self, name, sdb, cdb, authn_broker, authz, client_authn, symkey, urlmap=None, as_keyjar=None, as_configuration=None, base_url="", client_authn_methods=None, authn_at_registration="", client_info_url="", secret_lifetime=86400, # client conf below client_id=None, ca_certs=None, client_authn_method=None, c_keyjar=None, server_info=None, authz_page="", flow_type="", password=None, registration_info=None, response_type="", scope="", acr="", resource_srv="", ): self.authzsrv = OAuth2UmaAS( name, sdb, cdb, authn_broker, authz, client_authn, symkey, urlmap, as_keyjar, configuration=as_configuration, base_url=base_url, client_authn_methods=client_authn_methods, authn_at_registration=authn_at_registration, client_info_url=client_info_url, secret_lifetime=secret_lifetime, ) self.client = Client( client_id, ca_certs, client_authn_method, c_keyjar, server_info, authz_page, flow_type, password, registration_info, response_type, scope, ) self.client.redirect_uris = self.client.registration_info["redirect_uris"] self.baseurl = self.authzsrv.baseurl self.resource_srv = resource_srv self.acr = acr self.trace = [] def get_aat(self, user): request_args = { "response_type": "code", "client_id": "internal", "redirect_uri": self.client.redirect_uris[0], "scope": [self.client.get_uma_scope("AAT")], "state": "_state", } areq = AuthorizationRequest(**request_args) self.trace.append(trace("get_aat", "C-->AS", query=areq.to_dict(), user=user)) sid = self.authzsrv.sdb.create_authz_session(user, areq) grant = self.authzsrv.sdb[sid]["code"] self.client.token[user] = {"AAT": self.authzsrv.sdb.upgrade_to_token(grant)} self.trace.append(trace("get_aat", "C<--AS", data={"AAT": self.client.token[user]["AAT"]["access_token"]})) # C <-> AS internal communication def rpt_endpoint(self, authn, **kwargs): return self.authzsrv.rpt_endpoint(authn) def get_rpt(self, user): authn = "Bearer %s" % self.client.token[user]["AAT"]["access_token"] self.trace.append(trace("*get_rpt", "C-->AS", authn_info=authn)) resp = self.rpt_endpoint(authn) rtr = RPTResponse().from_json(resp.message) self.client.token[user]["RPT"] = rtr["rpt"] self.trace.append(trace("*get_rpt", "C<--AS", data={"RPT": self.client.token[user]["RPT"]})) def authorization_request_endpoint(self, data, authn): self.trace.append(trace("*authorization_request", "C-->AS", authn_info=authn, query=data)) return self.authzsrv.authorization_request_endpoint(data, authn) def resource_sets_by_user(self, uid): return self.authzsrv.resource_sets_by_user(uid) def store_permission(self, user, requestor, resource_id, scopes): return self.authzsrv.store_permission(user, requestor, resource_id, scopes) # client stuff def rs_query(self, requestor, path): try: rpt = self.client.token[requestor]["RPT"] except KeyError: rpt = None url = "%s/%s" % (self.resource_srv, path) if rpt: kwargs = {"headers": [("Authorization", "Bearer %s" % rpt)]} self.trace.append(trace("rs_query", "C-->RS", authn_info="Bearer %s" % rpt, url=url)) else: kwargs = {} self.trace.append(trace("rs_query", "C-->RS", url=url)) return self.client.send(url, "GET", **kwargs) def get_info(self, requester, path, state=""): """ :param requester: requester """ resp = self.rs_query(requester, path) self.trace.append(trace("rs_query", "C<--RS", response=resp)) if resp.status_code == 200: return Response(resp.text) if resp.status_code == 401: # No RPT as_uri = resp.headers["as_uri"] if as_uri == self.baseurl: # It's me as it should be, means get a RPT from myself self.get_aat(requester) self.get_rpt(requester) return self.get_info(requester, path, state) else: return R2C[500]("Wrong AS") if resp.status_code == 403: # Permission registered, got ticket prr = PermissionRegistrationResponse().from_json(resp.text) kwargs = self.client.create_authorization_data_request(requester, prr["ticket"]) resp = self.authorization_request_endpoint(kwargs["data"], kwargs["headers"]["Authorization"]) self.trace.append(trace("*authorization_request", "C<--AS", response=resp)) if resp.status == "200 OK": return self.get_info(requester, path) raise UMAError() def get_tokens(self, query): aresp = AuthorizationResponse().from_urlencoded(query) uid = self.client.acquire_access_token(aresp, "AAT") self.client.get_rpt(uid) return uid
class UmaCAS(object): def __init__( self, name, sdb, cdb, authn_broker, authz, client_authn, symkey, urlmap=None, as_keyjar=None, as_configuration=None, base_url="", client_authn_methods=None, authn_at_registration="", client_info_url="", secret_lifetime=86400, # client conf below client_id=None, ca_certs=None, client_authn_method=None, c_keyjar=None, server_info=None, authz_page="", flow_type="", password=None, registration_info=None, response_type="", scope="", acr="", resource_srv=""): self.authzsrv = OAuth2UmaAS( name, sdb, cdb, authn_broker, authz, client_authn, symkey, urlmap, as_keyjar, configuration=as_configuration, base_url=base_url, client_authn_methods=client_authn_methods, authn_at_registration=authn_at_registration, client_info_url=client_info_url, secret_lifetime=secret_lifetime) self.client = Client(client_id, ca_certs, client_authn_method, c_keyjar, server_info, authz_page, flow_type, password, registration_info, response_type, scope) self.client.redirect_uris = self.client.registration_info[ "redirect_uris"] self.baseurl = self.authzsrv.baseurl self.resource_srv = resource_srv self.acr = acr self.trace = [] def get_aat(self, user): request_args = { "response_type": "code", "client_id": "internal", "redirect_uri": self.client.redirect_uris[0], "scope": [self.client.get_uma_scope("AAT")], "state": "_state" } areq = AuthorizationRequest(**request_args) self.trace.append( trace("get_aat", "C-->AS", query=areq.to_dict(), user=user)) sid = self.authzsrv.sdb.create_authz_session(user, areq) grant = self.authzsrv.sdb[sid]["code"] self.client.token[user] = { "AAT": self.authzsrv.sdb.upgrade_to_token(grant) } self.trace.append( trace("get_aat", "C<--AS", data={"AAT": self.client.token[user]["AAT"]["access_token"]})) # C <-> AS internal communication def rpt_endpoint(self, authn, **kwargs): return self.authzsrv.rpt_endpoint(authn) def get_rpt(self, user): authn = "Bearer %s" % self.client.token[user]["AAT"]["access_token"] self.trace.append(trace("*get_rpt", "C-->AS", authn_info=authn)) resp = self.rpt_endpoint(authn) rtr = RPTResponse().from_json(resp.message) self.client.token[user]["RPT"] = rtr["rpt"] self.trace.append( trace("*get_rpt", "C<--AS", data={"RPT": self.client.token[user]["RPT"]})) def authorization_request_endpoint(self, data, authn): self.trace.append( trace("*authorization_request", "C-->AS", authn_info=authn, query=data)) return self.authzsrv.authorization_request_endpoint(data, authn) def resource_sets_by_user(self, uid): return self.authzsrv.resource_sets_by_user(uid) def store_permission(self, user, requestor, resource_id, scopes): return self.authzsrv.store_permission(user, requestor, resource_id, scopes) # client stuff def rs_query(self, requestor, path): try: rpt = self.client.token[requestor]["RPT"] except KeyError: rpt = None url = "%s/%s" % (self.resource_srv, path) if rpt: kwargs = {"headers": [("Authorization", "Bearer %s" % rpt)]} self.trace.append( trace("rs_query", "C-->RS", authn_info="Bearer %s" % rpt, url=url)) else: kwargs = {} self.trace.append(trace("rs_query", "C-->RS", url=url)) return self.client.send(url, "GET", **kwargs) def get_info(self, requester, path, state=""): """ :param requester: requester """ resp = self.rs_query(requester, path) self.trace.append(trace("rs_query", "C<--RS", response=resp)) if resp.status_code == 200: return Response(resp.text) if resp.status_code == 401: # No RPT as_uri = resp.headers["as_uri"] if as_uri == self.baseurl: # It's me as it should be, means get a RPT from myself self.get_aat(requester) self.get_rpt(requester) return self.get_info(requester, path, state) else: return R2C[500]("Wrong AS") if resp.status_code == 403: # Permission registered, got ticket prr = PermissionRegistrationResponse().from_json(resp.text) kwargs = self.client.create_authorization_data_request( requester, prr["ticket"]) resp = self.authorization_request_endpoint( kwargs["data"], kwargs["headers"]["Authorization"]) self.trace.append( trace("*authorization_request", "C<--AS", response=resp)) if resp.status == "200 OK": return self.get_info(requester, path) raise UMAError() def get_tokens(self, query): aresp = AuthorizationResponse().from_urlencoded(query) uid = self.client.acquire_access_token(aresp, "AAT") self.client.get_rpt(uid) return uid