Skip to content
Snippets Groups Projects

Fix: Deleted Search Controller

Merged Petar Hristov requested to merge Issue/1861-searchMetadata into dev
2 files
+ 1
294
Compare changes
  • Side-by-side
  • Inline
Files
2
using Coscine.ApiCommons;
using Coscine.Database.Models;
using Coscine.Database.Util;
using Coscine.Logging;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Coscine.Api.Project.Controllers
{
/// <summary>
/// This controller represents the actions which can be taken with a search object
/// </summary>
[Authorize]
public class SearchController : Controller
{
private readonly Authenticator _authenticator;
private readonly ProjectRoleModel _projectRoleModel;
private readonly CoscineLogger _coscineLogger;
private readonly AnalyticsLogObject _analyticsLogObject;
/// <summary>
/// SearchController specifying a ProjectRoleModel and an AnalyticsObject
/// </summary>
/// <param name="logger">Logger</param>
public SearchController(ILogger<SearchController> logger)
{
_authenticator = new Authenticator(this, Program.Configuration);
_projectRoleModel = new ProjectRoleModel();
_coscineLogger = new CoscineLogger(logger);
_analyticsLogObject = new AnalyticsLogObject();
}
/// <summary>
/// Returns results for the search word
/// </summary>
/// <param name="encodedSearchWord">Encoded search word</param>
/// <returns>Ok</returns>
[HttpGet("[controller]/all/{encodedSearchWord}")]
public IActionResult Search(string encodedSearchWord)
{
var user = _authenticator.GetUser();
return Ok(GetSearchResults(user.Id, encodedSearchWord, ""));
}
/// <summary>
/// Returns searched projects
/// </summary>
/// <param name="projectId">Id of the project</param>
/// <param name="encodedSearchWord">Encoded search word</param>
/// <returns>Ok</returns>
[HttpGet("[controller]/project/{projectId}/{encodedSearchWord}")]
public IActionResult SearchProject(string projectId, string encodedSearchWord)
{
var user = _authenticator.GetUser();
return Ok(GetSearchResults(user.Id, encodedSearchWord, projectId));
}
/// <summary>
/// This method gets the search results
/// </summary>
/// <param name="userId">Id of the user</param>
/// <param name="encodedSearchWord">Encoded search word</param>
/// <param name="projectId">Id of the project</param>
/// <returns>Search results</returns>
private JToken GetSearchResults(Guid userId, string encodedSearchWord, string projectId)
{
string searchQuery;
if (!string.IsNullOrWhiteSpace(encodedSearchWord))
{
searchQuery = HttpUtility.UrlDecode(encodedSearchWord);
}
else
{
searchQuery = "";
}
List<Guid> list;
if (projectId.Equals(""))
{
list = new List<Guid>();
}
else
{
list = GetAllSubProjects(projectId);
}
// create return object
var json = new JObject();
// search and add results for resources
json["Resources"] = SearchForResources(userId, searchQuery, projectId, list);
// search and add results for projects
if (projectId.Equals(""))
{
json["Projects"] = SearchForProjects(userId, searchQuery, projectId, list, false);
}
else
{
json["Projects"] = new JArray();
}
// remove the id of the root project since it cann not be a subproject of it self
if (list.Count >= 1)
{
list.RemoveAt(0);
}
// search and ad results for sub-projects
json["SubProjects"] = SearchForProjects(userId, searchQuery, projectId, list, true);
LogAnalytics("View Search Results", userId, projectId, json);
return json;
}
/// <summary>
/// This method gets all sub projects
/// </summary>
/// <param name="projectId">Id of the project</param>
/// <returns>List of SubProjects</returns>
private List<Guid> GetAllSubProjects(string projectId)
{
var list = new List<Guid>();
if (!projectId.Equals(""))
{
list.Add(new Guid(projectId));
var counter = 0;
DatabaseConnection.ConnectToDatabase((db) =>
{
while (counter != list.Count)
{
var innerResults = (from sp in db.SubProjects
where sp.ProjectId.Equals(list[counter])
select sp.SubProjectId);
list.AddRange(innerResults.ToList());
counter++;
}
});
}
return list;
}
/// <summary>
/// This method searchs projects
/// </summary>
/// <param name="userId">Id of the user</param>
/// <param name="searchQuery">Search query</param>
/// <param name="projectId">Id of the project</param>
/// <param name="listOfSubprojects">List of subprojects</param>
/// <param name="showSubProjects">Shows subprojects</param>
/// <returns>Found projects</returns>
private JToken SearchForProjects(Guid userId, string searchQuery, string projectId, List<Guid> listOfSubprojects, bool showSubProjects)
{
return DatabaseConnection.ConnectToDatabase((db) =>
{
var allSubProjects = (from sp in db.SubProjects select sp.SubProjectId).ToList();
var allSubProjectsList = new List<Guid>();
allSubProjectsList.AddRange(allSubProjects);
var results =
(from p in db.Projects
join pr in db.ProjectRoles on p.Id equals pr.ProjectId into joinedPr
from jpr in joinedPr.DefaultIfEmpty()
join v in db.Visibilities on p.VisibilityId equals v.Id into joinedV
from jv in joinedV.DefaultIfEmpty()
join pd in db.ProjectDisciplines on p.Id equals pd.ProjectId into joinedPd
from jpd in joinedPd.DefaultIfEmpty()
join d in db.Disciplines on jpd.DisciplineId equals d.Id into joinedD
from jd in joinedD.DefaultIfEmpty()
join pi in db.ProjectInstitutes on p.Id equals pi.ProjectId into joinedPi
from jpi in joinedPi.DefaultIfEmpty()
where p.Deleted == false &&
((!showSubProjects && !allSubProjectsList.Contains(p.Id)) ||
(showSubProjects && allSubProjectsList.Contains(p.Id))) &&
(jpr.UserId == userId || jv.DisplayName == "Public") &&
(projectId == "" || listOfSubprojects.Contains(p.Id)) &&
(searchQuery == "" ||
p.ProjectName.Contains(searchQuery) ||
p.Description.Contains(searchQuery) ||
p.Keywords.Contains(searchQuery) ||
p.DisplayName.Contains(searchQuery) ||
p.PrincipleInvestigators.Contains(searchQuery) ||
p.GrantId.Contains(searchQuery) ||
jv.DisplayName.Contains(searchQuery) ||
jd.Url.Contains(searchQuery) ||
jd.DisplayNameDe.Contains(searchQuery) ||
jd.DisplayNameEn.Contains(searchQuery))
select new { p.Id, p.DisplayName, p.Slug }).OrderBy(element => element.DisplayName).Distinct();
return JToken.Parse(JsonConvert.SerializeObject(results));
});
}
/// <summary>
/// This method searchs for resources
/// </summary>
/// <param name="userId">Id of the user</param>
/// <param name="searchQuery">Search Query</param>
/// <param name="projectId">Id of the project</param>
/// <param name="listOfSubprojects">List of subprojects</param>
/// <returns>Found resources by a searchQuery</returns>
private JToken SearchForResources(Guid userId, string searchQuery, string projectId, List<Guid> listOfSubprojects)
{
return DatabaseConnection.ConnectToDatabase((db) =>
{
var results = (from r in db.Resources
join pres in db.ProjectResources on r.Id equals pres.ResourceId into joinedPres
from jpres in joinedPres.DefaultIfEmpty()
join p in db.Projects on jpres.ProjectId equals p.Id into joinedP
from jp in joinedP.DefaultIfEmpty()
join pr in db.ProjectRoles on jp.Id equals pr.ProjectId into joinedPr
from jpr in joinedPr.DefaultIfEmpty()
join v in db.Visibilities on r.VisibilityId equals v.Id into joinedV
from jv in joinedV.DefaultIfEmpty()
join rd in db.ResourceDisciplines on r.Id equals rd.ResourceId into joinedRd
from jrd in joinedRd.DefaultIfEmpty()
join d in db.Disciplines on jrd.DisciplineId equals d.Id into joinedD
from jd in joinedD.DefaultIfEmpty()
join l in db.Licenses on r.LicenseId equals l.Id into joinedL
from jl in joinedL.DefaultIfEmpty()
join rt in db.ResourceTypes on r.TypeId equals rt.Id into joinedRt
from jrt in joinedRt.DefaultIfEmpty()
where jp.Deleted == false &&
(jpr.UserId == userId || jv.DisplayName == "Public") &&
(projectId == "" || listOfSubprojects.Contains(jd.Id)) &&
(searchQuery == "" ||
r.ResourceName.Contains(searchQuery) ||
r.DisplayName.Contains(searchQuery) ||
r.ResourceName.Contains(searchQuery) ||
r.Keywords.Contains(searchQuery) ||
r.UsageRights.Contains(searchQuery) ||
r.Description.Contains(searchQuery) ||
r.ApplicationProfile.Contains(searchQuery) ||
jrt.DisplayName.Contains(searchQuery) ||
jl.DisplayName.Contains(searchQuery) ||
jd.DisplayNameDe.Contains(searchQuery) ||
jd.DisplayNameEn.Contains(searchQuery))
select new { r.Id, r.DisplayName, jpr.ProjectId, jp.Slug }).OrderBy(element => element.DisplayName).Distinct();
return JToken.Parse(JsonConvert.SerializeObject(results));
});
}
/// <summary>
/// Log Analytics
/// </summary>
/// <param name="operation">Operation</param>
/// <param name="userId">Id of the user</param>
/// <param name="projectId">Id of the project</param>
/// <param name="json">AnalyticsLogObject</param>
private void LogAnalytics(string operation, Guid userId, string projectId, JObject json)
{
if (CoscineLoggerConfiguration.IsLogLevelActivated(LogType.Analytics))
{
List<string> projects = new List<string>();
foreach (var entry in json["Projects"])
{
projects.Add(entry["Id"].ToString());
}
foreach (var entry in json["SubProjects"])
{
projects.Add(entry["Id"].ToString());
}
List<string> resources = new List<string>();
foreach (var entry in json["Resources"])
{
resources.Add(entry["Id"].ToString());
}
_analyticsLogObject.Type = "Action";
_analyticsLogObject.Operation = operation;
if (!projectId.Equals(""))
{
_analyticsLogObject.ProjectId = projectId;
_analyticsLogObject.RoleId = _projectRoleModel.GetGetUserRoleForProject(new Guid(_analyticsLogObject.ProjectId), userId).ToString();
}
_analyticsLogObject.ProjectList = projects;
_analyticsLogObject.ResourceList = resources;
_coscineLogger.AnalyticsLog(_analyticsLogObject);
}
}
}
}
\ No newline at end of file
Loading