Source code for fasjson.web.resources.search

from flask_restx import Resource
from flask_restx.inputs import datetime_from_iso8601

from fasjson.lib.ldap.models import UserModel as LDAPUserModel
from fasjson.web.utils import maybe_anonymize
from fasjson.web.utils.ipa import get_attrs_from_mask, ldap_client
from fasjson.web.utils.pagination import page_request_parser
from fasjson.web.utils.request_parsing import add_exact_arguments

from .base import Namespace
from .users import UserModel


search_request_parser = page_request_parser.copy()
search_request_parser.add_argument("email", help="The email to search for")
search_request_parser.add_argument("email__exact", help="DEPRECATED: use email")
search_request_parser.add_argument("username", help="The username to search for")
search_request_parser.add_argument("ircnick", help="The ircnick to search for")
search_request_parser.add_argument("givenname", help="The first name to search for")
search_request_parser.add_argument("surname", help="The surname to search for")
search_request_parser.add_argument("human_name", help="The full human name to search for")
search_request_parser.add_argument("github_username", help="The username in GitHub.com")
search_request_parser.add_argument("gitlab_username", help="The username in GitLab.com")
search_request_parser.add_argument(
    "creation__before",
    help="Search for users created before this date",
    type=datetime_from_iso8601,
)
search_request_parser.add_argument("rhbzemail", help="The bugzilla email to search for")
search_request_parser.add_argument(
    "group", action="append", help="Users must be a member of this group"
)
add_exact_arguments(search_request_parser, LDAPUserModel)


api_v1 = Namespace("search", description="Search related operations")


[docs] @api_v1.route("/users/") class SearchUsers(Resource):
[docs] @api_v1.doc("search") @api_v1.expect(search_request_parser) @api_v1.response(400, "Validation Error") @api_v1.paged_marshal_with(UserModel) def get(self): """Fetch users given a search term""" search_args = search_request_parser.parse_args() page_number, page_size = self._parse_page_args(search_args) self._validate_search_args(search_args) client = ldap_client() result = client.search_users( attrs=get_attrs_from_mask(UserModel), page_size=page_size, page_number=page_number, **search_args ) result.items = [maybe_anonymize(user) for user in result.items] return result
def _parse_page_args(self, search_args): """ A simple function to remove and return the page size and number from the search args. Page size: - is between 1 and 40 - is a number - defaults to 40 if not provided """ page_number = search_args.pop("page_number") page_size = search_args.pop("page_size") page_size = 40 if page_size is None else page_size if page_size > 40 or page_size == 0: api_v1.abort( 400, "Page size must be between 1 and 40 when searching.", page_size=page_size, ) return page_number, page_size def _validate_search_args(self, search_args): """ A simple function to validate the provided arguments. Checks: - At least one search term must be provided - All provided search terms must be greater than 3 characters in length """ if not any(search_args.values()): api_v1.abort(400, "At least one search term must be provided.") for search_term, search_value in search_args.items(): if search_term == "creation__before": continue # It's a datetime already if search_term == "group": continue # These may be smaller than 3 chars, and will be matched exactly anyway. if search_value and len(search_value) < 3: api_v1.abort( 400, "Search term must be at least 3 characters long.", search_term=search_term, search_value=search_value, )