def __init__(self): super(LinkingUi, self).__init__() self.helpers = Helpers(current_app.config) self.parser = reqparse.RequestParser() self.parser.add_argument('operator_id', type=str, help='Operator UUID.') self.parser.add_argument('Password', type=str, help="Password for user.") self.parser.add_argument('Email', type=str, help="Email/Username.")
def __init__(self): super(UserLogin, self).__init__() self.helpers = Helpers(current_app.config) self.parser = reqparse.RequestParser() self.parser.add_argument('code', type=str, help='session code') self.parser.add_argument('operator_id', type=str, help='Operator UUID.') self.parser.add_argument('return_url', type=str, help='Url safe Base64 coded return url.') self.parser.add_argument('Password', type=str, help="Password for user.") self.parser.add_argument('Email', type=str, help="Email/Username.") self.parser.add_argument( 'linkingFrom', type=str, help='Origin of the linking request(?)') # TODO: Clarify?
class StoreSSR(Resource): def __init__(self): super(StoreSSR, self).__init__() config = current_app.config self.helpers = Helpers(config) @timeme @error_handler @api_logging def post(self): # TODO: This is as naive as it gets, needs some verifications regarding ssr, # or are we leaving this to firewalls, eg. Only this host(operator) can use this endpoint. try: self.helpers.store_ssr_JSON(json=request.json["data"]) return {"id": request.json["data"]["id"]}, 201 except Exception as e: debug_log.exception(e) raise e
class StoreSlr(Resource): def __init__(self): super(StoreSlr, self).__init__() self.db_path = current_app.config["DATABASE_PATH"] self.helpers = Helpers(current_app.config) @timeme @error_handler @api_logging def post(self): def decode_payload(payload): #sq.task("Fix possible incorrect padding in payload") payload += '=' * (-len(payload) % 4 ) # Fix incorrect padding of base64 string. debug_log.info("After padding fix :{}".format(payload)) #sq.task("Decode SLR payload and store it into object") debug_log.info(payload.encode()) content = decode64(payload.encode()) #sq.task("Load decoded payload as python dict") payload = loads(content.decode("utf-8")) debug_log.info("Decoded SLR payload:") debug_log.info(type(payload)) debug_log.info(dumps(payload, indent=2)) return payload store = request.json payload = decode_payload(store["data"]["slr"]["attributes"]["payload"]) debug_log.info("Storing SLR into db") self.helpers.store_slr_JSON(json=request.json["data"]["slr"], slr_id=payload["link_id"], surrogate_id=payload["surrogate_id"]) debug_log.info("Storing SSR into db") self.helpers.store_ssr_JSON(json=request.json["data"]["ssr"]) return { "data": { "id": payload["link_id"], "type": "ServiceLinkRecord" } }, 201
class LinkingUi(Resource): def __init__(self): super(LinkingUi, self).__init__() self.helpers = Helpers(current_app.config) self.parser = reqparse.RequestParser() self.parser.add_argument('operator_id', type=str, help='Operator UUID.') self.parser.add_argument('Password', type=str, help="Password for user.") self.parser.add_argument('Email', type=str, help="Email/Username.") @error_handler @api_logging def get(self): args = self.parser.parse_args() # TODO: Use template file or get this from somewhere. args["provider"] = settings.NAME tmpl_str = ''' <html> <header> <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <!-- Optional theme --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous"> <!-- Latest compiled and minified JavaScript --> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> </header> <body> <div class="container"> <div class="row"> <div class="col-md-12"> <div class="col-md-4"><br/> </div> <div class="col-md-4"> <form class="form-horizontal" action="" method="POST"> <fieldset> <legend>Link {{provider}} with Operator({{ operator_id }})</legend> <div class="form-group"> <div class="col-lg-10 col-lg-offset-1"> Username:<input name="Email" id="username"></input><br> Password :<input name="Password" id="pword"></input> <div align=center> <button type="reset" class="btn btn-danger">Cancel</button> <button type="submit" class="btn btn-success">Submit</button> </div> </div> </div> </fieldset> <div {{ fromOperator }}> <p> By linking service to Operator, you agree to the <a href="#LinkToToS">Terms of Service</a></p> <hr><p> You will be redirected to your MyData Account for login. </div> <input type="hidden" name="operator_id" value="{{ operator_id }}"> </form> </div> </div> </div> </div> </body> </html> ''' # Render Login template response = make_response(render_template_string(tmpl_str, **args), 200) response.headers["Content-Type"] = "text/html" return response @error_handler @api_logging def post(self): args = self.parser.parse_args() operator_id = args["operator_id"] user_id = args["Email"] user_pw = args["Password"] if not valid_credentials(user_id, user_pw): raise DetailedHTTPException(status=401, detail={"msg": "Unauthorized, check your login credentials."} ) # Send Management the Operator id and get Surrogate_ID endpoint = "/api/1.3/slr/surrogate_id" # TODO: This needs to be fetched from somewhere. data = {"user_id": user_id, "operator_id": args["operator_id"]} result = post("{}{}".format(current_app.config["SERVICE_MGMNT_URL"], endpoint), json=data) if not result.ok: raise DetailedHTTPException(status=result.status_code, detail={ "msg": "Something went wrong while posting to Service_Components Mgmnt to inform login was successful " "and its alright to generate Surrogate_ID ", "Error from Service_Components Mgmnt": loads(result.text)}, title=result.reason) debug_log.info(result.text) surrogate_id = loads(result.text)["surrogate_id"] # Link surrogate_id to the user def link_surrogate_id(surrogate_id, user_id, operator_id): debug_log.info("We got surrogate_id {} for user_id {} on operator {}".format(surrogate_id, user_id, operator_id)) self.helpers.storeSurrogateJSON(user_id, surrogate_id, operator_id) link_surrogate_id(surrogate_id, user_id, operator_id) # Redirect user to Operator UI service_id = settings.SERVICE_ID return_url = "http://"+request.headers["HOST"]+"/" #TODO: less hardcoded stuff operator_login_url = self.helpers.get_operator_login_url(operator_id) operator_endpoint = "{}".format(operator_login_url) operator_query = "?surrogate_id={}&service_id={}&return_url={}&linkingFrom={}".format( # TODO: Get return url from somewhere surrogate_id, service_id, encode64(return_url), "Service") debug_log.info("Redirect url with parameters:\n{}{}\nSurrogate_id is: {}".format(operator_endpoint, operator_query, surrogate_id)) response = make_response(redirect(operator_endpoint + operator_query)) return response
def __init__(self): super(StoreSSR, self).__init__() config = current_app.config self.helpers = Helpers(config)
def __init__(self): super(StoreSlr, self).__init__() self.db_path = current_app.config["DATABASE_PATH"] self.helpers = Helpers(current_app.config)
class UserLogin(Resource): def __init__(self): super(UserLogin, self).__init__() self.helpers = Helpers(current_app.config) self.parser = reqparse.RequestParser() self.parser.add_argument('code', type=str, help='session code') self.parser.add_argument('operator_id', type=str, help='Operator UUID.') self.parser.add_argument('return_url', type=str, help='Url safe Base64 coded return url.') self.parser.add_argument('Password', type=str, help="Password for user.") self.parser.add_argument('Email', type=str, help="Email/Username.") self.parser.add_argument( 'linkingFrom', type=str, help='Origin of the linking request(?)') # TODO: Clarify? @error_handler @api_logging def get(self): args = self.parser.parse_args() # TODO: Use template file or get this from somewhere. if args["linkingFrom"] == "Operator": args["fromOperator"] = "" else: args["fromOperator"] = "hidden" tmpl_str = ''' <html> <header> <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <!-- Optional theme --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous"> <!-- Latest compiled and minified JavaScript --> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> </header> <body> <div class="container"> <div class="row"> <div class="col-md-12"> <div class="col-md-4"><br/> </div> <div class="col-md-4"> <form class="form-horizontal" action="" method="POST"> <fieldset> <legend>Link {{provider}} with Operator({{ operator_id }})</legend> <div class="form-group"> <div class="col-lg-10 col-lg-offset-1"> Username:<input name="Email" id="username"></input><br> Password :<input name="Password" id="pword"></input><br> <div align=center> <button type="reset" class="btn btn-danger">Cancel</button> <button type="submit" class="btn btn-success">Submit</button> </div> </div> </div> </fieldset> <div {{ fromOperator }}> <p> By linking service to Operator, you agree to the <a href="#LinkToToS">Terms of Service</a></p> </div> <input type="hidden" name="code" value="{{ code }}"> <input type="hidden" name="return_url" value="{{ return_url }}"> <input type="hidden" name="operator_id" value="{{ operator_id }}"> <input type="hidden" name="linkingFrom" value="{{ linkingFrom }}"> </form> </div> </div> </div> </div> </body> </html> ''' # Render Login template response = make_response(render_template_string(tmpl_str, **args), 200) response.headers["Content-Type"] = "text/html" return response # code = args["code"], # operator_id = args["operator_id"], # return_url = args["return_url"], # linkingFrom = args["linkingFrom"] @error_handler @api_logging def post(self): def link_surrogate_id(json_response, user_id, operator_id): response_user_id = self.helpers.get_user_id_with_code(args["code"]) if response_user_id == user_id: pass else: raise DetailedHTTPException( status=403, detail={ "msg": "Response was for different user_id than expected." }, title="User ID mismatch.") debug_log.info("We got surrogate_id {} for user_id {}".format( json_response["surrogate_id"], user_id)) debug_log.info(dumps(json_response, indent=2)) self.helpers.storeSurrogateJSON(user_id, json_response["surrogate_id"], operator_id) return json_response["surrogate_id"] args = self.parser.parse_args() debug_log.info("Args contain:\n {}".format(dumps(args, indent=2))) debug_log.info(dumps(request.json, indent=2)) user_id = args["Email"] user_pw = args["Password"] if not valid_credentials(user_id, user_pw): raise DetailedHTTPException( status=401, detail={"msg": "Unauthorized, check your login credentials."}) code = args["code"] self.helpers.store_code_user({code: user_id}) debug_log.info("User logged in with id ({})".format(format(user_id))) endpoint = "/api/1.3/slr/surrogate_id" # TODO: This needs to be fetched from somewhere. data = {"user_id": user_id, "operator_id": args["operator_id"]} result = post("{}{}".format(current_app.config["SERVICE_MGMNT_URL"], endpoint), json=data) if not result.ok: raise DetailedHTTPException( status=result.status_code, detail={ "msg": "Something went wrong while posting to Service_Components Mgmnt to inform login was successful " "and its alright to generate Surrogate_ID ", "Error from Service_Components Mgmnt": loads(result.text) }, title=result.reason) debug_log.info(result.text) try: operator_id = args["operator_id"] surrogate_id = link_surrogate_id( loads(result.text), user_id, operator_id) # Returns surrogate_id for convenience endpoint = "/api/1.3/slr/linking" # TODO: This needs to be fetched from somewhere. data = { "code": code, "operator_id": args["operator_id"], "return_url": args["return_url"], "surrogate_id": surrogate_id, "user_id": user_id } linking_result = post("{}{}".format( current_app.config["SERVICE_MGMNT_URL"], endpoint), json=data) debug_log.debug("Service Linking resulted in:\n {}\n {}".format( linking_result.status_code, linking_result.text)) except Exception as e: raise e reply_json = loads(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) return redirect("{}?results={}".format(decode64(args["return_url"]), encode64(reply_json)), code=302)