Skip to content
Snippets Groups Projects
Select Git revision
  • master
1 result

example_rating_list.csv

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    SearchController.cs 13.90 KiB
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using Coscine.ApiCommons;
    using Microsoft.AspNetCore.Mvc;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using Microsoft.AspNetCore.Authorization;
    using Coscine.Database.Util;
    using Microsoft.Extensions.Logging;
    using Coscine.Database.Models;
    using Coscine.Logging;
    
    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>
            /// Searchs no filter
            /// </summary>
            /// <returns>Ok</returns>
            [HttpGet("[controller]/allNoFilter/")]
            public IActionResult SearchNoFilter()
            {
                var user = _authenticator.GetUser();
                return Ok(GetSearchResults(user.Id, "", ""));
            }
    
            /// <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 with no filter
            /// </summary>
            /// <param name="projectId">Id of the project</param>
            /// <returns>Ok</returns>
            [HttpGet("[controller]/projectNoFilter/{projectId}")]
            public IActionResult SearchProjectNoFilter(string projectId)
            {
                var user = _authenticator.GetUser();
                return Ok(GetSearchResults(user.Id, "", projectId));
            }
    
            /// <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);
                }
            }
        }
    }