def my_access(server_id): """ Get the api endpoints the logged in user is allowed to use on this server, and the latest datetime their token can expire. Parameters ---------- server_id: int Id of the server to check access on Notes ----- Produces a json object with "allowed_claims" and "latest_expiry" keys. "allowed_claims" will be an object with claim names as keys, and the available rights nested below. """ server = Server.query.filter(Server.id == server_id).first_or_404() allowed_claims = current_user.allowed_claims(server) return jsonify( { "allowed_claims": allowed_claims, "latest_expiry": current_user.latest_token_expiry(server), } )
def add_token(server): """ Generate a new token for a server. Parameters ---------- server: int ID of the server. Notes ----- Expects json with "name", "expiry" and "claims" keys, where "name" is a string, expiry is a datetime string of the form ""%Y-%m-%dT%H:%M:%S.%fZ" (e.g. 2018-01-01T00:00:00.0Z), and claims is a nested dict of the form {<claim_name>:{<right_name>:<bool>}}. Responds with a json object {"token":<token_string>, "id":<token_id>}. """ server = Server.query.filter(Server.id == server).first_or_404() json = request.get_json() current_app.logger.debug("New token request", request=json) if "name" not in json: raise InvalidUsage("No name.", payload={"bad_field": "name"}) expiry = datetime.datetime.strptime(json["expiry"], "%Y-%m-%dT%H:%M:%S.%fZ") lifetime = expiry - datetime.datetime.now() latest_lifetime = current_user.latest_token_expiry(server) if expiry > latest_lifetime: raise InvalidUsage("Token lifetime too long", payload={"bad_field": "expiry"}) allowed_claims = current_user.allowed_claims(server) current_app.logger.debug("New token request", allowed_claims=allowed_claims) for claim in json["claims"]: if claim not in allowed_claims: raise Unauthorized( f"You do not have access to {claim} on {server.name}") token_string = generate_token( username=current_user.username, flowapi_identifier=server.name, lifetime=lifetime, claims=json["claims"], private_key=current_app.config["PRIVATE_JWT_SIGNING_KEY"], ) token = Token( name=json["name"], token=token_string, expires=expiry, owner=current_user, server=server, ) db.session.add(token) db.session.commit() return jsonify({"token": token_string, "id": token.id})
def add_token(server): """ Generate a new token for a server. Parameters ---------- server: int ID of the server. Notes ----- Expects json with "name", "expiry" and "claims" keys, where "name" is a string, expiry is a datetime string of the form ""%Y-%m-%dT%H:%M:%S.%fZ" (e.g. 2018-01-01T00:00:00.0Z), and claims is a nested dict of the form {<claim_name>:{<right_name>:<bool>}}. Responds with a json object {"token":<token_string>, "id":<token_id>}. """ server = Server.query.filter(Server.id == server).first_or_404() json = request.get_json() print(json) if "name" not in json: raise InvalidUsage("No name.", payload={"bad_field": "name"}) expiry = datetime.datetime.strptime(json["expiry"], "%Y-%m-%dT%H:%M:%S.%fZ") lifetime = expiry - datetime.datetime.now() latest_lifetime = current_user.latest_token_expiry(server) if expiry > latest_lifetime: raise InvalidUsage("Token lifetime too long", payload={"bad_field": "expiry"}) allowed_claims = current_user.allowed_claims(server) print(allowed_claims) for claim, rights in json["claims"].items(): if claim not in allowed_claims: raise Unauthorized(f"You do not have access to {claim} on {server.name}") for right, setting in rights["permissions"].items(): if setting and not allowed_claims[claim]["permissions"][right]: raise Unauthorized( f"You do not have access to {claim}:{right} on {server.name}" ) for agg_unit in rights["spatial_aggregation"]: if agg_unit not in allowed_claims[claim]["spatial_aggregation"]: raise Unauthorized( f"You do not have access to {claim} at {agg_unit} on {server.name}" ) token_string = encode_access_token( identity=current_user.username, secret=server.secret_key, algorithm="HS256", expires_delta=lifetime, fresh=True, user_claims=json["claims"], csrf=False, identity_claim_key="identity", user_claims_key="user_claims", json_encoder=JSONEncoder, ) token = Token( name=json["name"], token=token_string, expires=expiry, owner=current_user, server=server, ) db.session.add(token) db.session.commit() return jsonify({"token": token_string, "id": token.id})