"""Endpoints for internal users.""" import re from connector_neo4j import Neo4jSession from flask import request from owsresponse import response from owsresponse.adaptors.flask import flaskify from users import constants from users.app import app from users.models import identities as identity_model from users.utils import authorization from users.utils.api_utils import jwt_check, validate_request_data from users.validation.schemas.internal_user_email import InternalUserEmailSchema @app.route('/internal/users', methods=['GET']) @Neo4jSession(use_v2=True, database=constants.NEO4J_DATABASE_NAME) @jwt_check def get_internal_users(): """Get a list of employees by search term. This endpoint requires a query param 'term' to search for employees. """ authorized = authorization.pdp_authorize_list_employees() if not authorized: return flaskify(response.Response(message='Forbidden', status=403)) search_term = request.args.get('term', '').strip() # Remove non-alphanumeric, non-space, non-hyphen/underscore/period/at sign search_term = re.sub(r'[^\w\sÀ-ÿ\-\_\.@\+]', '', search_term) if not search_term: return flaskify(response.Response(message='Search term is required', status=400)) search_results = identity_model.get_employees_by_search_term(search_term) return flaskify(response.Response({'users': search_results})) @app.route('/internal/user/get_by_email', methods=['POST']) @Neo4jSession(use_v2=True, database=constants.NEO4J_DATABASE_NAME) @jwt_check @validate_request_data(InternalUserEmailSchema()) def get_internal_user_by_email(): """Get an employee identity by email address. This endpoint uses POST instead of GET to protect PII. Email addresses in URL paths can be exposed in logs. Request Body: email (str): Required. Email address to search for. """ authorized = authorization.pdp_authorize_list_employees() if not authorized: return flaskify(response.Response(message='Forbidden', status=403)) email = request.validated_json['email'] identity_id = identity_model.get_identity_id_by_email(email) if not identity_id: return flaskify(response.create_not_found_response(message='Identity not found')) return flaskify(response.Response({'id': identity_id}))