def _create_arbitrary_save_app_action(self): save_action = SaveApp() actionParams = SaveAppParams() actionParams.saveDeploymentModel = 'VCenter Deploy VM From Linked Clone' actionParams.savedSandboxId = str(guid()) actionParams.sourceVmUuid = str(guid()) actionParams.deploymentPathAttributes = dict() save_action.actionParams = actionParams return save_action
def _create_arbitrary_delete_saved_app_action(self): save_action = DeleteSavedApp() actionParams = DeleteSavedAppParams() actionParams.artifacts = [Artifact(artifactRef=guid(), artifactName=guid())] actionParams.saveDeploymentModel = 'VCenter Deploy VM From Linked Clone' actionParams.savedSandboxId = str(guid()) actionParams.sourceVmUuid = str(guid()) actionParams.deploymentPathAttributes = dict() save_action.actionParams = actionParams return save_action
def request_form(): header = request.headers form = request.get_json() user = dict(name=form.get('name'), phone=form.get('phone'), email=form.get('email'), device_id=header.get('X-Device-Id'), created_at=datetime.now().strftime('%Y-%m-%d %H:%M:%S')) keys = user.keys() values = list(map(lambda k: user[k], keys)) values_str = "\'" + "\', \'".join(values) + "\'" sql = f"INSERT INTO users ({', '.join(keys)}) VALUES ({values_str})" DBFetcher().execute(sql) success = json(token=guid().hex), 200 error404 = json( code=404, message= "Проблемы сервака с кодом 404. Для проверки накидываю еще текстик" ), 404 return choice([success, success, success, error404])
def verify_slr(self, payload, code, slr, account_id): templa = { "code": code, "data": { "slr": { "attributes": { "slr": slr, }, "type": "ServiceLinkRecord", }, "ssr": { "attributes": { "record_id": str(guid()), "account_id": account_id, "slr_id": payload["link_id"], "sl_status": "Active", "iat": "", "prev_record_id": "NULL" }, "type": "ServiceLinkStatusRecord" }, "surrogate_id":{ "attributes": { "account_id": "2", "service_id": payload["service_id"], "surrogate_id": payload["surrogate_id"] }, "type": "SurrogateId" } } } req = post(self.url + self.endpoint["verify_slr"].replace("{account_id}", account_id), json=templa, headers={'Api-Key': self.token}, timeout=self.timeout) return req
def on_post(self, req, resp): """ Handle a forgotpassword POST request. Arguments: req: the request resp: the response Returns: None The method expects its input as www-formencoded parameters in the request body. On success it will create a password reset request and send an email with a confirmation link. On failure it will do nothing. It will always set the `Location` header to :attr:`LOGINSCREEN`. It will always set the response status to ;attr:`falcon.HTTP_303`. Other Parameters: email: the username of the user (a valid email address) login: the literal text `Forgot` Typically these parameters would correspond to input fields in an HTML form and a submit button with a `name=Forgot` attribute and send as input parameters in the body of the request. """ logger.info('ForgotPasswordResource') global DBSession session = DBSession() # we always send the same response, no matter if the user exists or not resp.status = falcon.HTTP_303 resp.location = f"{LOGINSCREEN}?checkemail" params = req.params if not login_forgot_params.check(params): logger.info('unauthorized, login forgot params do not have proper format') else: with timing_equalizer(3.0): email = params['email'].lower() user = session.query(User).filter(User.email == email).first() user = session.query(User).filter(User.email == email).first() if not user: # no user found but we are not providing this information logger.info(f"no user found {email}") else: logger.info(f"password reset request received for existing user {email}") pr = PasswordReset(id=guid().hex, userid=user.id) session.add(pr) session.commit() logger.info(f"sending confirmation mail to {user.email} ({user.name})") logger.info(f"reset confirmation id: {pr.id}") u, p, s = fetch_smtp_params() if mail(EMAILTEMPLATE_FORGOTPASSWORD.format(name=user.name, website=WEBSITE, link=f"{RESETPASSWORD}?confirmationid={pr.id}"), "Password change request", fromaddr=u, toaddr=user.email, smtp=s, username=u, password=p): logger.success('mail successfully sent') else: logger.error('mail not sent')
def gen_rs_id(self, source_name): ## # Something to check state here? # Also store RS_ID in DB around here. ## rs_id = "{}_{}".format(source_name, str(guid())) self.storeRS_ID(rs_id) return rs_id
def gen_csr(self, account_id, consent_record_id, consent_status, previous_record_id): _tmpl = { "record_id": str(guid()), "surrogate_id": account_id, "cr_id": consent_record_id, "consent_status": consent_status, # "Active/Disabled/Withdrawn", "iat": int(time.time()), "prev_record_id": previous_record_id, } return _tmpl
def __init__(self, status=None, source=None, title="An Error occurred", detail=None, exception=None, trace=None): HTTPException.__init__(self) self.count = 0 self.code = status self.detail = detail self.title = title self.trace = trace self.source = source self.error = {"errors": []} if exception is not None: try: raise exception except DetailedHTTPException as e: self.count = exception.count + 1 if (self.code is None): self.code = e.code for errors in e.error["errors"]: print(errors) self.error["errors"].append(errors) # Incase of general exception. except Exception as e: if self.detail is None: self.detail = {"Error": repr(e)} if self.code is None: self.code = 500 if self.title is None: self.title = repr(e) if self.detail is None: self.detail = "An unspecified Error has occurred" if self.code is None: self.code = 500 uuid = str(guid()) er = { "id": uuid, "status": self.code, "source": self.source, "trace": self.trace, "title": self.title, "detail": self.detail, "count": self.count } self.error["errors"].append(er) self.description = dumps(self.error, indent=3)
def gen_cr_common(self, sur_id, rs_ID, slr_id): ## # Return common part of CR ## common_cr = { "version_number": "String", "cr_id": str(guid()), "surrogate_id": sur_id, "rs_id": rs_ID, "slr_id": slr_id, "issued": "String", "not_before": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S %Z "), "not_after": datetime.fromtimestamp(time.time()+2592000).strftime("%Y-%m-%dT%H:%M:%S %Z "), "issued_at": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S %Z "), "subject_id": "String" # TODO: Should this really be in common_cr? } return common_cr
def get(self): try: sq.task("Generate code") code = str(guid()) code_storage = {code: "{}{}".format("!", code)} sq.task("Store code in db") self.storeCode(code_storage) sq.reply_to("Operator_Components Mgmnt", "Returning code") return {'code': code} except Exception as e: raise DetailedHTTPException( exception=e, detail={ "msg": "Most likely storing code failed.", "code_json": code_storage }, title="Failure in GenCode endpoint", trace=traceback.format_exc(limit=100).splitlines())
def gen_auth_token(self, auth_token_info): gen3 = {"generate": "RSA", "size": self.keysize, "kid": "Something went wrong, check helpers.py key generation"} operator_key = jwk.JWK(**gen3) try: with open(self.cert_key_path, "r") as cert_file: operator_key2 = jwk.JWK(**loads(load(cert_file))) operator_key = operator_key2 except Exception as e: print(e) with open(self.cert_key_path, "w+") as cert_file: dump(operator_key.export(), cert_file, indent=2) slrt = SLR_tool() slrt.slr = auth_token_info debug_log.debug(dumps(slrt.get_SLR_payload(), indent=2)) debug_log.debug(dumps(slrt.get_CR_payload(), indent=2)) # JOSE header header = {"typ": "JWT", "alg": "HS256"} # Claims srv_handler = ServiceRegistryHandler(self.service_registry_search_domain, self.service_registry_search_endpoint) payload = {"iss": self.operator_id, # Operator ID, "cnf": {"kid": slrt.get_source_cr_id()}, "aud": srv_handler.getService_url(slrt.get_source_service_id()), "exp": int(time.time() + self.not_after_interval), # datetime.fromtimestamp(time.time()+2592000).strftime("%Y-%m-%dT%H:%M:%S %Z"), # 30 days in seconds # Experiation time of token on or after which token MUST NOT be accepted "nbf": int(time.time()), # datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S %Z"), # The time before which token MUST NOT be accepted "iat": int(time.time()), # datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S %Z"), # The time which the JWT was issued "jti": str(guid()), # JWT id claim provides a unique identifier for the JWT "pi_id": slrt.get_source_cr_id(), # Resource set id that was assigned in the linked Consent Record } debug_log.debug(dumps(payload, indent=2)) key = operator_key debug_log.debug(key.export()) debug_log.debug(key.export_public()) header = {"alg": "RS256"} token = jwt.JWT(header=header, claims=payload) token.make_signed_token(key) return token.serialize()
def gen_cr_common(self, sur_id, rs_ID, slr_id, issued, not_before, not_after, subject_id, operator_id, role): ## # Return common part of CR # Some of these fields are filled in consent_form.py ## common_cr = { "version": "1.2", "cr_id": str(guid()), "surrogate_id": sur_id, "rs_id": rs_ID, "slr_id": slr_id, "iat": issued, "nbf": not_before, "exp": not_after, "operator": operator_id, "subject_id": subject_id, # TODO: Should this really be in common_cr? "role": role } return common_cr
def login(): form = LoginForm() if form.validate_on_submit(): with db.cursor() as cursor: cursor.execute( "SELECT UserId, PasswordHash FROM User WHERE Email = %s", (form.email.data, )) row = cursor.fetchone() if row is not None and check_password_hash(row["PasswordHash"], form.password.data): session_id = guid().hex cursor.execute( "INSERT INTO Session (SessionId, UserId) VALUES (%s, %s)", (session_id, row["UserId"])) db.commit() session["session_id"] = session_id return redirect('/') else: flash('Tentative de connection incorrecte') return View('login.html', title='Connexion', form=form)
def verify_slr(self, payload, code, slr, account_id): templa = { "code": code, "data": { "slr": { "attributes": { "slr": slr, }, "type": "ServiceLinkRecord", }, "ssr": { "attributes": { "version": "1.2", "surrogate_id": payload["surrogate_id"], "record_id": str(guid()), "account_id": account_id, "slr_id": payload["link_id"], "sl_status": "Active", "iat": int(time.time()), "prev_record_id": "NULL" }, "type": "ServiceLinkStatusRecord" }, "surrogate_id": { "attributes": { "account_id": "2", "service_id": payload["service_id"], "surrogate_id": payload["surrogate_id"] }, "type": "SurrogateId" } } } debug_log.info("Template sent to Account Manager:") debug_log.info(dumps(templa, indent=2)) req = post(self.url + self.endpoint["verify_slr"].replace("{account_id}", account_id), json=templa, headers={'Api-Key': self.token}, timeout=self.timeout) return req
def gen_auth_token(self, auth_token_info): gen3 = {"generate": "RSA", "size": self.keysize, "kid": "Something went wrong, check helpers.py key generation"} operator_key = jwk.JWK(**gen3) try: with open(self.cert_key_path, "r") as cert_file: operator_key2 = jwk.JWK(**loads(load(cert_file))) operator_key = operator_key2 except Exception as e: print(e) with open(self.cert_key_path, "w+") as cert_file: dump(operator_key.export(), cert_file, indent=2) slrt = SLR_tool() slrt.slr = auth_token_info debug_log.debug(dumps(slrt.get_SLR_payload(), indent=2)) debug_log.debug(dumps(slrt.get_CR_payload(), indent=2)) # JOSE header header = {"typ": "JWT", "alg": "HS256"} # Claims payload = {"iss": slrt.get_operator_key(), # Operator_Key "sub": slrt.get_sink_key(), # Service_Components(Sink) Key "aud": slrt.get_dataset(), # Hard to build real "exp": datetime.fromtimestamp(time.time()+2592000).strftime("%Y-%m-%dT%H:%M:%S %Z "), # 30 days in seconds # Experiation time of token on or after which token MUST NOT be accepted "nbf": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S %Z "), # The time before which token MUST NOT be accepted "iat": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S %Z "), # The time which the JWT was issued "jti": str(guid()), # JWT id claim provides a unique identifier for the JWT "rs_id": slrt.get_rs_id(), # Resource set id that was assigned in the linked Consent Record } debug_log.debug(dumps(payload, indent=2)) key = operator_key debug_log.debug(key.export()) debug_log.debug(key.export_public()) header = {"alg": "RS256"} token = jwt.JWT(header=header, claims=payload) token.make_signed_token(key) return token.serialize()
def on_post(self, req, resp): """ Handle a register POST request. Arguments: req: the request resp: the response Returns: None The method expects its input as www-formencoded parameters in the request body. On success it will create a pending user request and send an email with a confirmation link. On failure it will do nothing. It will always set the `Location` header to :attr:`LOGINSCREEN`. It will always set the response status to :attr:`falcon.HTTP_303`. Other Parameters: email: the username of the user (a valid email address) name: the full name of the user password: the password ( 8 >= length <= 64, must contain at lease 1 lowercase, 1 uppercase, 1 digit and 1 special char. password2: must be identical to the password parameter login: the literal text `Register` Typically these parameters would correspond to input fields in an HTML form and a submit button with a `name=Register` attribute and send as input parameters in the body of the request. """ logger.info('RegisterResource') global DBSession session = DBSession() resp.status = "303 Registration pending confirmation, email sent to email address" resp.location = f"{LOGINSCREEN}?pending" if not login_register_params.check(req.params): logger.info('unauthorized, login register params do not have proper format') else: with timing_equalizer(3.0): params = req.params # TODO lowercase email everywhere email = params['email'].lower() user = session.query(User).filter(User.email == email).first() # We always return the same response (and redirect) no matter # whether the email is in use or not or if anything else is wrong # this is to prevent indexing, i.e. checking which email addresses are in use if params['password'] != params['password2']: logger.info("passwords are not identical") elif user: logger.info(f'email already in use {user.email}') else: user = session.query(PendingUser).filter(PendingUser.email == email).first() if user: # we delete previous pending registration to prevent database overfilling logger.info('previous registration not yet confirmed') session.delete(user) session.commit() else: logger.info('first registration') pu = PendingUser(id=guid().hex, email=email, password=newpassword(params['password']), name=params['name']) session.add(pu) session.commit() # TODO limit number of emails sent to same address user = session.query(PendingUser).filter(PendingUser.email == email).first() logger.info(f"sending confirmation mail to {user.email} ({user.name})") logger.info(f"confirmation id: {pu.id}") u, p, s = fetch_smtp_params() logger.info(f"mailer {u}@{s} (password not shown ...)") if mail(EMAILTEMPLATE_REGISTER.format(name=user.name, website=WEBSITE, link=f"{CONFIRMREGISTRATION}?confirmationid={pu.id}"), "Confirm your registration", fromaddr=u, toaddr=user.email, smtp=s, username=u, password=p): logger.success('mail successfully sent') else: logger.error('mail not sent')
def __init__(self): super(RegisterSur, self).__init__() self.app = current_app #print(current_app.config) keysize = current_app.config["KEYSIZE"] cert_key_path = current_app.config["CERT_KEY_PATH"] self.request_timeout = current_app.config["TIMEOUT"] SUPER_DEBUG = True account_id = "ACC-ID-RANDOM" user_account_id = account_id + "_" + str(guid()) # Keys need to come from somewhere else instead of being generated each time. gen = {"generate": "EC", "cvr": "P-256", "kid": user_account_id} gen3 = {"generate": "RSA", "size": keysize, "kid": account_id} operator_key = jwk.JWK(**gen3) try: with open(cert_key_path, "r") as cert_file: operator_key2 = jwk.JWK(**loads(load(cert_file))) operator_key = operator_key2 except Exception as e: print(e) with open(cert_key_path, "w+") as cert_file: dump(operator_key.export(), cert_file, indent=2) # Template to send the key to key server template = { account_id: { "cr_keys": loads(operator_key.export_public()), "token_keys": loads(operator_key.export_public()) } } # post("http://localhost:6666/key", json=template) self.payload = \ { "version": "1.2", "link_id": "", "operator_id": account_id, "service_id": "SRV-SH14W4S3", # How do we know this? "surrogate_id": "", "token_key": "", "operator_key": loads(operator_key.export_public()), "cr_keys": "", "created": "" # time.time(), } debug_log.info(dumps(self.payload, indent=3)) protti = {"alg": "RS256"} headeri = { "kid": user_account_id, "jwk": loads(operator_key.export_public()) } self.service_registry_handler = ServiceRegistryHandler() self.am_url = current_app.config["ACCOUNT_MANAGEMENT_URL"] self.am_user = current_app.config["ACCOUNT_MANAGEMENT_USER"] self.am_password = current_app.config["ACCOUNT_MANAGEMENT_PASSWORD"] self.timeout = current_app.config["TIMEOUT"] try: self.AM = AccountManagerHandler(self.am_url, self.am_user, self.am_password, self.timeout) except Exception as e: debug_log.warn( "Initialization of AccountManager failed. We will crash later but note it here.\n{}" .format(repr(e))) self.Helpers = Helpers(current_app.config) self.query_db = self.Helpers.query_db
def gen_rs_id(self, source_URI): ## # Something to check state here? # Also store RS_ID in DB around here. ## rs_id = "{}{}".format(source_URI.replace("http://", "").replace("https://", ""), str(guid())) self.storeRS_ID(rs_id) return rs_id
def post(self): try: debug_log.info(dumps(request.json)) sq.task("Load json payload as object") js = request.json sq.task("Load account_id and service_id from database") query = self.query_db("select * from session_store where code=%s;", (js["code"], )) debug_log.info(type(query)) debug_log.info(query) dict_query = loads(query) debug_log.debug("{} {}".format(type(query), query)) account_id = dict_query["account_id"] self.payload["service_id"] = dict_query["service_id"] # Check Surrogate_ID exists. # Fill token_key try: sq.task("Verify surrogate_id and token_key exist") token_key = js["token_key"] self.payload["surrogate_id"] = js["surrogate_id"] #self.payload["token_key"] = {"key": token_key} sq.task("Store surrogate_id and keys for CR steps later on.") key_template = { "token_key": token_key, "pop_key": token_key } # TODO: Get pop_key here? self.Helpers.store_service_key_json( kid=token_key["kid"], surrogate_id=js["surrogate_id"], key_json=key_template) except Exception as e: debug_log.exception(e) raise DetailedHTTPException( exception=e, detail={ "msg": "Received Invalid JSON that may not contain surrogate_id", "json": js }) #sq.task("Fetch and fill token_issuer_keys") # TODO: Token keys separetely when the time is right. #self.payload["token_issuer_keys"][0] = self.Helpers.get_key()["pub"] # Create template self.payload["link_id"] = str(guid()) # TODO: Currently you can generate endlessly new slr even if one exists already sq.task("Fill template for Account Manager") template = { "code": js["code"], "data": { "slr": { "type": "ServiceLinkRecord", "attributes": self.payload, }, "surrogate_id": { "type": "SurrogateId", "attributes": { "surrogate_id": self.payload["surrogate_id"], "service_id": self.payload["service_id"], "account_id": account_id } } }, } debug_log.info("###########Template for Account Manager#") debug_log.info(dumps(template, indent=3)) debug_log.info("########################################") sq.send_to("Account Manager", "Sign SLR at Account Manager") try: reply = self.AM.sign_slr(template, account_id) except AttributeError as e: raise DetailedHTTPException( status=502, title= "It would seem initiating Account Manager Handler has failed.", detail="Account Manager might be down or unresponsive.", trace=traceback.format_exc(limit=100).splitlines()) debug_log.info(dumps(reply, indent=2)) # Parse JSON form Account Manager to format Service_Mgmnt understands. try: req = { "data": { "code": js["code"], }, "slr": reply["data"]["slr"]["attributes"]["slr"] } debug_log.info("SLR O: {}".format(dumps(req, indent=3))) except Exception as e: raise DetailedHTTPException( exception=e, detail= "Parsing JSON form Account Manager to format Service_Mgmnt understands has failed.", trace=traceback.format_exc(limit=100).splitlines()) try: sq.send_to( "Service_Components Mgmnt", "Send created and signed SLR to Service_Components Mgnt") endpoint = "/api/1.2/slr/slr" service_url = self.service_registry_handler.getService_url( self.payload["service_id"].encode()) debug_log.info("Service_ulr = {}, type: {}".format( service_url, type(service_url))) response = post("{}{}".format(service_url, endpoint), json=req, timeout=self.request_timeout) debug_log.info("Request sent.") if not response.ok: raise DetailedHTTPException( status=response.status_code, detail={ "Error from Service_Components Mgmnt": loads(response.text) }, title=response.reason) except DetailedHTTPException as e: raise e except Exception as e: raise DetailedHTTPException( exception=e, detail="Sending SLR to service has failed", trace=traceback.format_exc(limit=100).splitlines()) except DetailedHTTPException as e: raise e except Exception as e: raise DetailedHTTPException( title="Creation of SLR has failed.", exception=e, trace=traceback.format_exc(limit=100).splitlines())
def post(self): args = self.parser.parse_args() def get_api_key(account_url=self.account_url + "account/api/v1.3/", user=None, password=None, endpoint="external/auth/user/"): debug_log.info( "\nFetching Account Key for account '{}' from endpoint: {}". format(user + ":" + password, account_url + endpoint)) api_json = get(account_url + endpoint, auth=(user, password)) #debug_log.info("Received following key:\n {}".format(api_json)) if api_json.ok: return loads(api_json.text) else: raise DetailedHTTPException( title="Authentication to Account failed.", status=403) # Check Account is valid account, this is dummy UI, this is dumm test. account_info = get_api_key(user=args["username"], password=args["pword"]) account_id = account_info["account_id"] account_api_key = account_info["Api-Key-User"] # Initialize all common variables surrogate_id = args["surrogate_id"] service_id = args["service_id"] return_url = args["return_url"] # Generate Code for session code = str(guid()) debug_log.info( "Session information contains: code {}, account id {} and service_id {}" .format(code, account_id, service_id)) debug_log.info("Store session_information to database") session_information = { code: { "account_id": account_id, "service_id": service_id, "user_key": account_api_key } } self.store_session(session_information) try: # Make request to register surrogate_id data = { "code": code, "operator_id": self.operator_id, "return_url": return_url, "surrogate_id": surrogate_id, } # Fetch service information: service_json = self.service_registry_handler.getService(service_id) service_domain = service_json["serviceInstance"][0][ "domain"] # Domain to Login of Service service_access_uri = service_json["serviceInstance"][0][ "serviceAccessEndPoint"]["serviceAccessURI"] service_linking_uri = "/slr/linking" service_url = service_domain + service_access_uri + service_linking_uri # Initiate Service Link Process debug_log.info("Sending linking request to Service at: {}".format( service_url)) linking_result = post(service_url, json=data) debug_log.debug("Service Linking resulted in:\n {}\n {}".format( linking_result.status_code, linking_result.text)) # If SLR was created success fully load it as a dictionary, on errors we delete session. if linking_result.ok: reply_json = loads(linking_result.text) else: self.helper.delete_session(code) raise DetailedHTTPException( title=linking_result.reason, status=linking_result.status_code, detail={"msg": linking_result.text}) debug_log.info( "Encoding json as reply to ui: \n{}".format(reply_json)) if isinstance(reply_json, dict): reply_json = dumps(reply_json) self.helper.delete_session(code) return redirect("{}?results={}".format( decode64(args["return_url"]), encode64(reply_json)), code=302) except DetailedHTTPException as e: self.helper.delete_session(code) raise e except Exception as e: self.helper.delete_session(code) raise DetailedHTTPException( status=500, exception=e, title="Something went wrong during service linking, try again." )
def get(self, account_id, service_id): """ :param account_id: Account Manager user id :param service_id: Service id as in Service Registry """ debug_log.info("#### Request to start SLR flow with parameters: account_id ({}), service_id ({})" .format(account_id, service_id)) try: AM = get_am(current_app, request.headers) key_check = AM.verify_user_key(account_id) debug_log.info("Verifying User Key resulted: {}".format(key_check)) # Check Active SLR for this account/service pair doesn't exist AM.check_for_existing_slr(service_id, account_id) # We need to store some session information for later parts of flow. session_information = {} sq.task("Fetch service address from Service Registry") service_json = self.service_registry_handler.getService(service_id) service_domain = service_json["serviceInstance"][0]["loginDomain"] # Domain to Login of Service service_access_uri = service_json["serviceInstance"][0]["serviceAccessEndPoint"]["serviceAccessURI"] service_login_uri = service_json["serviceInstance"][0]["loginUri"] sq.task("Generate code for session") code = str(guid()) debug_log.info("Session information contains: code {}, account id {} and service_id {}" .format(code, account_id, service_id)) sq.task("Store session_information to database") session_information[code] = {"account_id": account_id, "service_id": service_id, "user_key": request.headers["Api-Key-User"]} self.store_session(session_information) service_endpoint = "{}{}{}".format(service_domain, service_access_uri, service_login_uri) service_query = "?code={}&operator_id={}&return_url={}&linkingFrom={}".format( # TODO: Get return url from somewhere code, self.uid, urlsafe_b64encode(self.return_url), "Operator") debug_log.info("Redirect url with parameters:\n{}{}\nCode contains: {}".format(service_endpoint, service_query, code)) sq.send_to("UI(Operator)", "Redirect user to Service Mockup login") response = make_response(redirect(service_endpoint+service_query)) return response except DetailedHTTPException as e: debug_log.exception(e) if "code" in locals(): self.helper.delete_session(code) raise DetailedHTTPException(exception=e, title="SLR registration failed.", status=500, detail="Something failed during creation of SLR.", trace=traceback.format_exc(limit=100).splitlines()) except Exception as e: debug_log.exception(e) if "code" in locals(): self.helper.delete_session(code) raise DetailedHTTPException(status=500, title="Something went really wrong during SLR registration.", detail="Error: {}".format(repr(e)), exception=e, trace=traceback.format_exc(limit=100).splitlines())
Operator_Components Mgmnt->Operator_Components Mgmnt: Load slr payload as object Operator_Components Mgmnt->Operator_Components Mgmnt: Decode payload and store it into object Operator_Components Mgmnt->Operator_Components Mgmnt: Fetch link_id from decoded payload Operator_Components Mgmnt->Operator_Components Mgmnt: Load account_id from database Operator_Components Mgmnt->Operator_Components Mgmnt: Load decoded payload as python dict Operator_Components Mgmnt->Operator_Components Mgmnt: Load slr and code from json payload Operator_Components Mgmnt->Account Manager: Verify SLR at Account Manager. Operator_Components Mgmnt-->Service_Components Mgmnt: 201, SLR VERIFIED ''' request_timeout = 20 SUPER_DEBUG = True account_id = "ACC-ID-RANDOM" user_account_id = account_id + "_" + str(guid()) ##### Here some functions to help with verifying SLR(JWS) def verifyJWS(json_JWS): def verify(jws, header): try: sign_key = jwk.JWK(**header["jwk"]) jws.verify(sign_key) return True except Exception as e: debug_log.info(repr(e)) try:
def on_post(self, req, resp): """ Handle a logon POST request. Arguments: req: the request resp: the response Returns: None The method expects its input as www-formencoded parameters in the request body. On success it will set the `Location` header to :attr:`APPLICATION` and return a session cookie. On failure it will set the `Location` header to :attr:`LOGINSCREEN`. It will always set the response status to :attr:`falcon.HTTP_303`. Other Parameters: email: the username of the user (a valid email address) password: the password login: the literal text `Login` Typically these parameters would correspond to input fields in an HTML form and a submit button with a `name=Login` attribute and send as input parameters in the body of the request. """ logger.info('LoginResource') global DBSession resp.status = falcon.HTTP_303 resp.location = f'{LOGINSCREEN}?failed' if not login_login_params.check(req.params): logger.info('unauthorized, params do not have a proper format') else: email = req.params['email'].lower() session = DBSession() user = session.query(User).filter(User.email == email).first() # make sure whichever path we take in the authentication # takes the same amount of time. This also functions as a # crude rate limiting algorithm because now logging takes # at least 1 second (although our WSGI app may have multiple # forked workers and/or threads and this limit is per thread) with timing_equalizer(1.0): if user: logger.info(f"valid user found {user.email}") if checkpassword(req.params['password'], user.password): for s in session.query(Session).filter(Session.userid == user.id): session.delete(s) now = datetime.now() softlimit = now + timedelta(minutes=SOFTTIMEOUT) hardlimit = now + timedelta(minutes=HARDTIMEOUT) ns = Session(userid=user.id, id=guid().hex, created=now, softlimit=softlimit, hardlimit=hardlimit) session.add(ns) session.commit() resp.set_cookie('session', ns.id, domain=DOMAIN, path='/', http_only=False) # falcon 3 supports samesite argument in set_cookie but falcon 2 doesn't resp._cookies['session']['samesite'] = 'Lax' logger.success(f'user succesfully authenticated {user.email}') resp.location = APPLICATION else: logger.info(f'user authentication failed for known user {user.email}') else: logger.info(f'user authentication failed for unknown user {email}')
def post(self): try: debug_log.info(request.json) user_id = request.json["user_id"] code = request.json["code"] sq.task("Generate surrogate_id.") surrogate_id = "{}_{}".format(str(guid()), code) sq.task("Link code to generated surrogate_id") self.helpers.add_surrogate_id_to_code(request.json["code"], surrogate_id) data = { "surrogate_id": surrogate_id, "code": request.json["code"], "token_key": loads(self.service_key.export_public()) } sq.send_to("Service_Components", "Send surrogate_id to Service_Components") endpoint = "/api/1.2/slr/link" content_json = {"code": code, "surrogate_id": surrogate_id} result_service = post("{}{}".format(self.service_url, endpoint), json=content_json) if not result_service.ok: raise DetailedHTTPException( status=result_service.status_code, detail={ "msg": "Something went wrong while posting to Service_Components for /link", "Error from Service_Components": loads(result_service.text) }, title=result_service.reason) sq.send_to("Operator_Components Mgmnt", "Send Operator_Components request to make SLR") endpoint = "/api/1.2/slr/link" result = post("{}{}".format(self.operator_url, endpoint), json=data) debug_log.info("####slr/link reply from operator: {}\n{}".format( result.status_code, result.text)) if not result.ok: raise DetailedHTTPException( status=result.status_code, detail={ "msg": "Something went wrong while posting to Operator_SLR for /link", "Error from Operator_SLR": loads(result.text) }, title=result.reason) except DetailedHTTPException as e: e.trace = traceback.format_exc(limit=100).splitlines() raise e except Exception as e: raise DetailedHTTPException( exception=e, detail= "Something failed in generating and delivering Surrogate_ID.", trace=traceback.format_exc(limit=100).splitlines())