//This search is a plain search, no permission limits or user lookups. public async Task <GenericSearchResult> SearchUnrestricted(SearchRequests requests) { return(await SearchBase(requests.Copy(), new Dictionary <string, object>(requests.values))); }
//A restricted search doesn't allow you to retrieve results that the given request user can't read public async Task <GenericSearchResult> Search(SearchRequests requests, long requestUserId = 0) { requests = requests.Copy(); var globalId = Guid.NewGuid(); UserView requester = new UserView() //This is a default user, make SURE all the relevant fields are set! { id = 0, super = false, groups = new List <long>() }; //Do a (hopefully) quick lookup for the request user! if (requestUserId > 0) { try { //This apparently throws an exception if it fails requester = await GetById <UserView>(RequestType.user, requestUserId); } catch (Exception ex) { logger.LogWarning($"Error while looking up requester: {ex}"); throw new ArgumentException($"Unknown request user {requestUserId}"); } } //Need to add requester key to parameter list! var globalPre = $"_sys{globalId.ToString().Replace("-", "")}"; var requesterKey = $"{globalPre}_requester"; var groupsKey = $"{globalPre}_groups"; var parameterValues = new Dictionary <string, object>(requests.values); parameterValues.Add(requesterKey, requestUserId); parameterValues.Add(groupsKey, permissionService.GetPermissionIdsForUser(requester)); //Modify the queries before giving them out to the query builder! We NEED them //to be absolutely restricted by permissions! foreach (var request in requests.requests) { //This USED to be part of the single search thing, but I want unrestricted search to be //truly unrestricted request.limit = Math.Min(request.limit > 0 ? request.limit : int.MaxValue, config.MaxIndividualResultSet); //This is VERY important: limit content searches based on permissions! if (request.type == RequestType.content.ToString()) //queryBuilder.ContentRequestTypes.Select(x => x.ToString()).Contains(request.type)) { request.query = queryBuilder.CombineQueryClause(request.query, $"!permissionlimit(@{groupsKey}, id, R)"); } if (request.type == RequestType.message.ToString() || request.type == RequestType.activity.ToString() || request.type == RequestType.watch.ToString() || request.type == RequestType.vote.ToString() || request.type == RequestType.message_aggregate.ToString() || request.type == RequestType.activity_aggregate.ToString()) { request.query = queryBuilder.CombineQueryClause(request.query, $"!permissionlimit(@{groupsKey}, contentId, R)"); } if (request.type == RequestType.message.ToString()) { request.query = queryBuilder.CombineQueryClause(request.query, $"!receiveuserlimit(@{requesterKey})"); } //Watches and variables and votes are per-user! if (request.type == RequestType.watch.ToString() || request.type == RequestType.uservariable.ToString() || request.type == RequestType.vote.ToString()) { request.query = queryBuilder.CombineQueryClause(request.query, $"userId = @{requesterKey}"); } if (request.type == RequestType.adminlog.ToString()) { if (!requester.super) { throw new ForbiddenException("You must be super to access the admin logs!"); } } } return(await SearchBase(requests, parameterValues)); }