using Coscine.Action; using Coscine.Action.EventArgs; using Coscine.Action.Utils; using Coscine.Api.Project.ParameterObjects; using Coscine.Api.Project.ReturnObjects; using Coscine.ApiCommons; using Coscine.ApiCommons.Factories; using Coscine.Configuration; using Coscine.Database.DataModel; using Coscine.Database.Models; using Coscine.Database.ReturnObjects; using Coscine.Database.Util; using Coscine.Logging; using Coscine.Metadata; using Coscine.ResourceLoader; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; namespace Coscine.Api.Project.Controllers { /// <summary> /// /// This controller represents the actions which can be taken with a project object. /// </summary> [Authorize] public class ProjectController : Controller { private readonly Authenticator _authenticator; private readonly ProjectModel _projectModel; private readonly IConfiguration _configuration; private readonly Emitter _emitter; private readonly ActivatedFeaturesModel _activatedFeaturesModel; private readonly ProjectRoleModel _projectRoleModel; private readonly ProjectQuotaModel _projectQuotaModel; private readonly ResourceTypeModel _resourceTypeModel; private readonly ResourceModel _resourceModel; private readonly CoscineLogger _coscineLogger; private readonly VisibilityModel _visibilityModel; private readonly InvitationModel _invitationModel; private readonly RoleModel _roleModel; private readonly UserModel _userModel; private readonly int _maxAvailable = 100; private readonly string _userUrlPrefix = "https://purl.org/coscine/users"; private readonly Uri _orgPrefixUrl = new Uri("http://www.w3.org/ns/org#"); private readonly RdfStoreConnector _rdfStoreConnector; /// <summary> /// ProjectController constructor /// </summary> /// <param name="logger">Logger</param> public ProjectController(ILogger<ProjectController> logger) { _authenticator = new Authenticator(this, Program.Configuration); _configuration = Program.Configuration; _projectModel = new ProjectModel(); _emitter = new Emitter(_configuration); _activatedFeaturesModel = new ActivatedFeaturesModel(); _projectRoleModel = new ProjectRoleModel(); _resourceTypeModel = new ResourceTypeModel(); _resourceModel = new ResourceModel(); _projectQuotaModel = new ProjectQuotaModel(); _coscineLogger = new CoscineLogger(logger); _visibilityModel = new VisibilityModel(); _rdfStoreConnector = new RdfStoreConnector(Program.Configuration.GetString("coscine/local/virtuoso/additional/url")); _invitationModel = new InvitationModel(); _roleModel = new RoleModel(); _userModel = new UserModel(); } /// <summary> /// Returns all available projects (including sub projects) /// </summary> /// <returns>Ok</returns> [Route("[controller]")] public ActionResult<IEnumerable<ProjectObject>> Index() { var user = _authenticator.GetUser(); var result = _projectModel.GetWithAccess(user, UserRoles.Member, UserRoles.Owner).ToList() .Select((project) => _projectModel.CreateReturnObjectFromDatabaseObject(project)) .OrderBy(element => element.DisplayName); return Ok(result); } /// <summary> /// Retrieves all top level projects /// </summary> /// <returns>Ok</returns> [Route("[controller]/-/topLevel")] public ActionResult<IEnumerable<ProjectObject>> GetTopLevelProjects() { var user = _authenticator.GetUser(); var projects = _projectModel.GetTopLevelWithAccess(user, UserRoles.Member, UserRoles.Owner).ToList() .Select((project) => _projectModel.CreateReturnObjectFromDatabaseObject(project)) .OrderBy(element => element.DisplayName); if (Request.Query != null && Request.Query["noanalyticslog"] != "true") { LogAnalyticsViewHome(projects.Select(x => x.Id.ToString()).ToList()); } return Ok(projects); } /// <summary> /// This returns the the project if the user has access to it /// </summary> /// <param name="id">Id of the resource</param> /// <returns>Ok or Statuscode 401</returns> [HttpGet("[controller]/{id}")] public ActionResult<ProjectObject> Get(string id) { var user = _authenticator.GetUser(); var project = _projectModel.GetById(Guid.Parse(id)); if (_projectModel.HasAccess(user, project, UserRoles.Member, UserRoles.Owner)) { SubProjectModel subProjectModel = new SubProjectModel(); var subProjectRel = subProjectModel.GetAllWhere((subProject) => subProject.SubProjectId == project.Id && project.Deleted == false); var parentProjectRelation = subProjectRel.FirstOrDefault(); if (parentProjectRelation != null && _projectModel.HasAccess(user, parentProjectRelation.ProjectId, UserRoles.Member, UserRoles.Owner)) { return Ok(_projectModel.CreateReturnObjectFromDatabaseObject(project, parentProjectRelation.ProjectId)); } return Ok(_projectModel.CreateReturnObjectFromDatabaseObject(project)); } else { return Unauthorized($"User is not allowed to see given the project {id}"); } } /// <summary> /// Gets the resources /// </summary> /// <param name="id">Id of the resource</param> /// <returns>Json object or Statuscode 401</returns> [HttpGet("[controller]/{id}/resources")] public ActionResult<IEnumerable<ResourceObject>> GetResources(string id) { var project = _projectModel.GetById(Guid.Parse(id)); var user = _authenticator.GetUser(); var resourceModel = new ResourceModel(); var resourceTypeModel = new ResourceTypeModel(); if (_projectModel.HasAccess(user, project, UserRoles.Member, UserRoles.Owner)) { var resources = resourceModel.GetAllWhere((resource) => (from projectResource in resource.ProjectResources where projectResource.ProjectId == project.Id select projectResource).Any()) .Select((resource) => { return resourceModel.CreateReturnObjectFromDatabaseObject(resource); }).OrderBy(element => element.DisplayName); if (Request.Query != null && Request.Query["noanalyticslog"] != "true") { var projectObject = _projectModel.CreateReturnObjectFromDatabaseObject(_projectModel.GetById(project.Id)); LogAnalyticsViewProject(project, resources.ToList(), projectObject.Disciplines, projectObject.Organizations, user); } return Json(resources); } else { return Unauthorized($"User is not allowed to see given the project {id}"); } } /// <summary> /// Retrieves the quota for the selected project. /// </summary> /// <param name="projectId">Id of the project.</param> /// <returns>List of project quotas</returns> [HttpGet("[controller]/{projectId}/quota/-/all")] public ActionResult<IEnumerable<ProjectQuota>> Quotas(string projectId) { var user = _authenticator.GetUser(); if (!Guid.TryParse(projectId, out Guid projectGuid)) { return BadRequest($"{projectId} is not a guid."); } var project = _projectModel.GetById(projectGuid); if (project == null) { return NotFound($"Could not find project with id: {projectId}"); } if (!_projectModel.HasAccess(user, project, UserRoles.Owner)) { return Unauthorized("The user is not authorized to perform a get on the selected project!"); } var resourceTypes = _resourceTypeModel.GetAllWhere(x => x.Enabled.HasValue && x.Enabled.Value); return Json(resourceTypes.Select(x => CreateProjectQuotaReturnObject(x, projectGuid))); } private ProjectQuotaReturnObject CreateProjectQuotaReturnObject(ResourceType x, Guid projectGuid) { var projectQuota = _projectQuotaModel.GetWhere((y) => y.ProjectId == projectGuid && y.ResourceTypeId == x.Id); return new ProjectQuotaReturnObject { Id = x.Id, Name = x.DisplayName, Used = CalculateUsed(x, projectGuid), Allocated = projectQuota == null ? 0 : projectQuota.Quota }; } private int CalculateUsed(ResourceType resourceType, Guid projectId) { var resourceTypeDefinition = ResourceTypeFactory.CreateResourceTypeObject(resourceType.DisplayName, _configuration); var resources = _resourceModel.GetAllWhere((resource) => (from projectResource in resource.ProjectResources where projectResource.ProjectId == projectId select projectResource).Any() && resource.TypeId == resourceType.Id); var used = resources.Sum(y => resourceTypeDefinition.GetResourceQuotaAvailable(y.Id.ToString(), _resourceModel.GetResourceTypeOptions(y.Id)).Result); return (int)used; } /// <summary> /// Retrieves the quota for the selected project and resource Type. /// </summary> /// <param name="projectId">Id of the project</param> /// <param name="resourceTypeId">Id of the resource type</param> /// <returns>The project quota for the resource type.</returns> [HttpGet("[controller]/{projectId}/quota/{resourceTypeId}")] public ActionResult<ProjectQuotaReturnObject> Quota(string projectId, string resourceTypeId) { var user = _authenticator.GetUser(); if (!Guid.TryParse(projectId, out Guid projectGuid)) { return BadRequest($"{projectId} is not a guid."); } var project = _projectModel.GetById(projectGuid); if (project == null) { return NotFound($"Could not find project with id: {projectId}"); } if (!_projectModel.HasAccess(user, project, UserRoles.Owner)) { return Unauthorized("The user is not authorized to perform a get on the selected project!"); } if (!Guid.TryParse(resourceTypeId, out Guid resourceTypeGuid)) { return BadRequest($"{resourceTypeId} is not a guid."); } var resourceType = _resourceTypeModel.GetById(resourceTypeGuid); if (resourceType == null || !resourceType.Enabled.HasValue || !resourceType.Enabled.Value) { return NotFound($"Could not find resourceType with id: {resourceTypeId}"); } var projectQuota = _projectQuotaModel.GetWhere((x) => x.ProjectId == projectGuid && x.ResourceTypeId == resourceTypeGuid); var projectQuotaReturnObject = new ProjectQuotaReturnObject { Id = resourceTypeGuid, Name = resourceType.DisplayName, Used = CalculateUsed(resourceType, projectGuid), Allocated = projectQuota.Quota }; return Json(projectQuotaReturnObject); } /// <summary> /// Get the max quota for a resource type. /// </summary> /// <param name="projectId">Id of the project.</param> /// <param name="resourceTypeId">Id of the resource</param> /// <returns>The maximum value for the quota.</returns> [HttpGet("[controller]/{projectId}/quota/{resourceTypeId}/max")] public ActionResult<MaxProjectQuota> GetQuotaMax(string projectId, string resourceTypeId) { var user = _authenticator.GetUser(); if (!Guid.TryParse(projectId, out Guid projectGuid)) { return BadRequest($"{projectId} is not a guid."); } var project = _projectModel.GetById(projectGuid); if (project == null) { return NotFound($"Could not find project with id: {projectId}"); } if (!_projectModel.HasAccess(user, project, UserRoles.Owner)) { return Unauthorized("The user is not authorized to perform a get on the selected project!"); } if (!Guid.TryParse(resourceTypeId, out Guid resourceTypeGuid)) { return BadRequest($"{resourceTypeId} is not a guid."); } var resourceType = _resourceTypeModel.GetById(resourceTypeGuid); if (resourceType == null || !resourceType.Enabled.HasValue || !resourceType.Enabled.Value) { return NotFound($"Could not find resourceType with id: {resourceTypeId}"); } return Json(new MaxProjectQuota { Id = resourceTypeGuid, Available = _maxAvailable }); } /// <summary> /// Update the project quota. /// </summary> /// <param name="projectId">Id of the project.</param> /// <param name="resourceTypeId">Id of the resource.</param> /// <param name="updateProjectQuotaObject">Object containing the update values.</param> /// <returns>NoContent (204).</returns> [HttpPost("[controller]/{projectId}/quota/{resourceTypeId}")] public IActionResult UpdateQuota(string projectId, string resourceTypeId, [FromBody] UpdateProjectQuotaObject updateProjectQuotaObject) { var user = _authenticator.GetUser(); if (!Guid.TryParse(projectId, out Guid projectGuid)) { return BadRequest($"{projectId} is not a guid."); } var project = _projectModel.GetById(projectGuid); if (project == null) { return NotFound($"Could not find project with id: {projectId}"); } if (!_projectModel.HasAccess(user, project, UserRoles.Owner)) { return Unauthorized("The user is not authorized to perform a get on the selected project!"); } if (!Guid.TryParse(resourceTypeId, out Guid resourceTypeGuid)) { return BadRequest($"{resourceTypeId} is not a guid."); } var resourceType = _resourceTypeModel.GetById(resourceTypeGuid); if (resourceType == null || !resourceType.Enabled.HasValue || !resourceType.Enabled.Value) { return NotFound($"Could not find resourceType with id: {resourceTypeId}"); } if (resourceType.DisplayName.Equals("rdss3")) { return BadRequest($"Cannot adjust quota for rdss3."); } if (updateProjectQuotaObject.Allocated < 0) { return BadRequest($"Allocated {updateProjectQuotaObject.Allocated}. Cannot be less than 0."); } var projectQuotaForCurrent = _projectQuotaModel.GetWhere(x => x.ProjectId == projectGuid && x.ResourceTypeId == resourceTypeGuid); var used = CalculateUsed(resourceType, projectGuid); if (used > updateProjectQuotaObject.Allocated) { return BadRequest($"Cannot set quota ({updateProjectQuotaObject.Allocated}) below the used value ({used})."); } if (updateProjectQuotaObject.Allocated > _maxAvailable) { return BadRequest($"Cannot set quota to {updateProjectQuotaObject.Allocated}. It would exceed the limit of {_maxAvailable}"); } projectQuotaForCurrent.Quota = updateProjectQuotaObject.Allocated; _projectQuotaModel.Update(projectQuotaForCurrent); return NoContent(); } /// <summary> /// Updates the selected project /// </summary> /// <param name="id">Id of the resource</param> /// <returns>Ok or Statuscode 401</returns> [HttpPost("[controller]/{id}")] public IActionResult Update(string id) { var user = _authenticator.GetUser(); var projectObject = ObjectFactory<ProjectObject>.DeserializeFromStream(Request.Body); var project = _projectModel.GetById(Guid.Parse(id)); if (_projectModel.HasAccess(user, project, UserRoles.Owner)) { LogAnalyticsEditProject(project, _projectModel.GetMetadataCompleteness(projectObject), projectObject.Disciplines, projectObject.Organizations, user); return Ok(_projectModel.UpdateByObject(project, projectObject)); } else { return Unauthorized("The user is not authorized to perform an update on the selected project!"); } } /// <summary> /// Deletes the selected project /// </summary> /// <param name="id">Id of the resource</param> /// <returns>Json object or Statuscode 401</returns> [HttpDelete("[controller]/{id}")] public IActionResult Delete(string id) { var user = _authenticator.GetUser(); var project = _projectModel.GetById(Guid.Parse(id)); if (_projectModel.HasAccess(user, project, UserRoles.Owner)) { var projectObject = _projectModel.CreateReturnObjectFromDatabaseObject(_projectModel.GetById(project.Id)); LogAnalyticsDeleteProject(project, projectObject.Disciplines, projectObject.Organizations, user); DeleteProject(project); return Json(_projectModel.CreateReturnObjectFromDatabaseObject(project)); } else { return Unauthorized("The user is not authorized to perform an update on the selected project!"); } } /// <summary> /// Deletes the project /// </summary> /// <param name="project">Project</param> /// <param name="isHard">isHard</param> /// <param name="propegateAction">propegate Action</param> public void DeleteProject(Database.DataModel.Project project, bool isHard = false, bool propegateAction = true) { var subProjectModel = new SubProjectModel(); foreach (var subProject in subProjectModel.GetAllWhere( (subProject) => subProject.ProjectId == project.Id && (subProject.SubProjectNavigation.Deleted == false || isHard) )) { Database.DataModel.Project subProjectObject; if (isHard) { subProjectObject = _projectModel.GetByIdIncludingDeleted(subProject.SubProjectId); subProjectModel.Delete(subProject); } else { subProjectObject = _projectModel.GetById(subProject.SubProjectId); } DeleteProject(subProjectObject, isHard, propegateAction); } foreach (var subProject in subProjectModel.GetAllWhere((subProject) => subProject.SubProjectId == project.Id)) { if (isHard) { subProjectModel.Delete(subProject); } } if (isHard) { var projectResourceModel = new ProjectResourceModel(); var resourceModel = new ResourceModel(); var resourceTypeModel = new ResourceTypeModel(); foreach (var projectResource in projectResourceModel.GetAllWhere((projectResource) => projectResource.ProjectId == project.Id)) { var resource = resourceModel.GetById(projectResource.ResourceId); var resourceTypeOptions = resourceModel.GetResourceTypeOptions(projectResource.ResourceId); var resourceTypeDefinition = ResourceTypeFactory.CreateResourceTypeObject(resourceTypeModel.GetById(resource.TypeId).DisplayName, _configuration); resourceTypeDefinition.DeleteResource(projectResource.ResourceId.ToString(), resourceTypeOptions); projectResourceModel.Delete(projectResource); resourceModel.Delete(resource); } var projectRoleModel = new ProjectRoleModel(); foreach (var projectRole in projectRoleModel.GetAllWhere((projectRole) => projectRole.ProjectId == project.Id)) { projectRoleModel.Delete(projectRole); } var projectDisciplineModel = new ProjectDisciplineModel(); foreach (var projectDiscipline in projectDisciplineModel.GetAllWhere((projectDiscipline) => projectDiscipline.ProjectId == project.Id)) { projectDisciplineModel.Delete(projectDiscipline); } var projectInstituteModel = new ProjectInstituteModel(); foreach (var projectInstitute in projectInstituteModel.GetAllWhere((projectInstitute) => projectInstitute.ProjectId == project.Id)) { projectInstituteModel.Delete(projectInstitute); } foreach (var projectQuota in _projectQuotaModel.GetAllWhere((Quota) => Quota.ProjectId == project.Id)) { _projectQuotaModel.Delete(projectQuota); } foreach (var invitation in _invitationModel.GetAllWhere((x) => x.Project == project.Id)) { _invitationModel.Delete(invitation); } _activatedFeaturesModel.DeactivateAllFeatures(project); if (propegateAction) { _emitter.EmitProjectDelete(new ProjectEventArgs(_configuration) { Project = project }); } _projectModel.HardDelete(project); } else { _projectModel.Delete(project); } } /// <summary> /// Creates a project /// </summary> /// <returns>Json object or Statuscode 401</returns> [HttpPost("[controller]")] public IActionResult Store() { var user = _authenticator.GetUser(); var projectObject = ObjectFactory<ProjectObject>.DeserializeFromStream(Request.Body); if (projectObject?.ParentId != new Guid() && !_projectModel.HasAccess(user, _projectModel.GetById(projectObject.ParentId), UserRoles.Owner)) { return Unauthorized("User is not allowed to create SubProjects."); } var project = _projectModel.StoreFromObject(projectObject, user, _rdfStoreConnector.GetQuotaDefault(user.Id.ToString())); if (projectObject.ParentId != new Guid() // for now, only an owner can add subprojects to projects && _projectModel.HasAccess(user, _projectModel.GetById(projectObject.ParentId), UserRoles.Owner)) { var subProjectModel = new SubProjectModel(); subProjectModel.LinkSubProject(projectObject.ParentId, project.Id); } _emitter.EmitProjectCreate(new ProjectEventArgs(_configuration) { Project = project, ProjectOwner = user }); LogAnalyticsAddProject(project, _projectModel.GetMetadataCompleteness(projectObject), projectObject.Disciplines, projectObject.Organizations, user); return Json(_projectModel.CreateReturnObjectFromDatabaseObject(project)); } /// <summary> /// List all invitations of a project. /// </summary> /// <param name="projectId">Project id of the project</param> /// <returns>List of invitations</returns> [HttpGet("[controller]/invitation/list/{projectId}")] public ActionResult<IEnumerable<InvitationReturnObject>> ListInvitations(Guid projectId) { var project = _projectModel.GetById(projectId); if (project == null) { return NotFound($@"The project ""{projectId}"" was not found."); } var user = _authenticator.GetUser(); if (!_projectModel.HasAccess(user, project, UserRoles.Owner)) { return Unauthorized($"You are not an owner of the project."); } var invitations = _invitationModel.GetAllWhere(x => x.Project == projectId) .Select(x => new InvitationReturnObject { Id = x.Id, Expiration = x.Expiration, Issuer = x.Issuer, ProjectId = x.Project, RoleId = x.Role, UserMail = x.InviteeEmail }); return new ActionResult<IEnumerable<InvitationReturnObject>>(invitations); } /// <summary> /// Create and send an invitation to specified mail. /// </summary> /// <param name="sendInvitationObject">Informations for sending an invitation</param> /// <returns>NoContent</returns> [HttpPost("[controller]/invitation")] public IActionResult SendInvitation([FromBody] SendInvitationObject sendInvitationObject) { var user = _authenticator.GetUser(); if (!IsValidEmail(sendInvitationObject.Email)) { return BadRequest($@"The email ""{sendInvitationObject.Email}"" is invalid."); } var project = _projectModel.GetById(sendInvitationObject.Project); if (project == null) { return NotFound($@"The project ""{sendInvitationObject.Project}"" was not found."); } if (_roleModel.GetById(sendInvitationObject.Role) == null) { return NotFound($@"The role ""{sendInvitationObject.Role}"" was not found."); } if (!_projectModel.HasAccess(user, project, UserRoles.Owner)) { return Unauthorized($"You are not an owner of the project."); } var invitations = _invitationModel.GetAllWhere( x => x.Project == sendInvitationObject.Project && x.InviteeEmail == sendInvitationObject.Email && x.Expiration > DateTime.UtcNow ); if (invitations.Any()) { return BadRequest("This invitee already has a valid invitation to this project."); } var expiredInvitations = _invitationModel.GetAllWhere( x => x.Project == sendInvitationObject.Project && x.InviteeEmail == sendInvitationObject.Email && x.Expiration <= DateTime.UtcNow ); foreach (var expiredInvitation in expiredInvitations) { _invitationModel.Delete(expiredInvitation); } var token = _invitationModel.CreateInvitation(sendInvitationObject.Project, user.Id, sendInvitationObject.Role, sendInvitationObject.Email); var body = new JObject { ["Args"] = new JObject() { ["placeholder"] = new JObject() { ["confirmation_link"] = $@"{_configuration.GetString("coscine/local/api/additional/url")}/SitePages/Home.aspx?token={token}" } } }; NotificationBusUtil.Send(Program.Configuration, "user_invitation", NotificationBusUtil.GetUserList(new User { EmailAddress = sendInvitationObject.Email }), sendInvitationObject.Project.ToString(), body); return NoContent(); } /// <summary> /// Deletes an invitation. /// </summary> /// <param name="invitationId">Id of a invitation</param> /// <returns>NoContent</returns> [HttpDelete("[controller]/invitation/{invitationId}")] public IActionResult DeleteInvitation(Guid invitationId) { var invitation = _invitationModel.GetById(invitationId); if(invitation == null) { return NotFound("Invitation was not found."); } var user = _authenticator.GetUser(); if (!_projectModel.HasAccess(user, _projectModel.GetById(invitation.Project), UserRoles.Owner)) { return Unauthorized($"You are not an owner of this project."); } _invitationModel.Delete(invitation); return NoContent(); } /// <summary> /// Resolve an invitation for the current user. /// </summary> /// <param name="token">Token of a invitation</param> /// <returns>NoContent</returns> [HttpGet("[controller]/invitation/resolve/{token}")] public IActionResult ResolveInvitation(Guid token) { var user = _authenticator.GetUser(); var invitation = _invitationModel.GetByToken(token); if(invitation == null) { return NotFound("Invitation was not found."); } if (invitation.Expiration < DateTime.UtcNow) { return BadRequest("The invitation has expired"); } var project = _projectModel.GetById(invitation.Project); if (!_projectModel.HasAccess(_userModel.GetById(invitation.Issuer), project, UserRoles.Owner)) { return Unauthorized($"The issuer is not an owner of the project."); } if (_projectRoleModel.GetAllWhere(x => x.ProjectId == invitation.Project && x.UserId == user.Id).Any()) { return BadRequest($"The invitee is already part of the project."); } var role = _roleModel.GetById(invitation.Role); _emitter.EmitUserAdd(new UserEventArgs(_configuration) { Project = project, Role = role, User = user, }); var projectRole = new ProjectRole() { RelationId = Guid.NewGuid(), ProjectId = invitation.Project, UserId = user.Id, RoleId = invitation.Role }; _projectRoleModel.Insert(projectRole); _invitationModel.Delete(invitation); return NoContent(); } private static bool IsValidEmail(string email) { try { return new System.Net.Mail.MailAddress(email).Address == email; } catch { return false; } } private void LogAnalyticsViewHome(List<string> projectIds) { _coscineLogger.AnalyticsLog( new AnalyticsLogObject { Type = "Action", Operation = "View Home", ProjectList = projectIds }); } private void LogAnalyticsViewProject(Database.DataModel.Project project, List<ResourceObject> resources, IEnumerable<DisciplineObject> disciplines, IEnumerable<OrganizationObject> organizations, User user) { var resourceTypes = _resourceTypeModel.GetAllWhere(x => x.Enabled.HasValue && x.Enabled.Value); var objects = resourceTypes.Select(x => CreateProjectQuotaReturnObject(x, project.Id)); _coscineLogger.AnalyticsLog( new AnalyticsLogObject { Type = "Action", Operation = "View Project", RoleId = _projectRoleModel.GetGetUserRoleForProject(project.Id, user.Id).ToString(), ProjectId = project.Id.ToString(), QuotaSize = objects.Select(x => $"{x.Name}: {x.Used}/{x.Allocated}").ToList(), Disciplines = disciplines.Select(x => x.DisplayNameEn).ToList(), Organizations = organizations.Select(x => x.DisplayName).ToList(), Visibility = project.VisibilityId.HasValue ? _visibilityModel.GetById(project.VisibilityId.Value)?.DisplayName : null, ResourceList = resources.Select(x => x.Id.ToString()).ToList(), }); } private void LogAnalyticsEditProject(Database.DataModel.Project project, string metadataCompletness, IEnumerable<DisciplineObject> disciplines, IEnumerable<OrganizationObject> organizations, User user) { var resourceTypes = _resourceTypeModel.GetAllWhere(x => x.Enabled.HasValue && x.Enabled.Value); var objects = resourceTypes.Select(x => CreateProjectQuotaReturnObject(x, project.Id)); _coscineLogger.AnalyticsLog( new AnalyticsLogObject { Type = "Action", Operation = "Edit Project", RoleId = _projectRoleModel.GetGetUserRoleForProject(project.Id, user.Id).ToString(), ProjectId = project.Id.ToString(), QuotaSize = objects.Select(x => $"{x.Name}: {x.Used}/{x.Allocated}").ToList(), MetadataCompleteness = metadataCompletness, Disciplines = disciplines.Select(x => x.DisplayNameEn).ToList(), Organizations = organizations.Select(x => x.DisplayName).ToList(), Visibility = project.VisibilityId.HasValue ? _visibilityModel.GetById(project.VisibilityId.Value)?.DisplayName : null, }); } private void LogAnalyticsAddProject(Database.DataModel.Project project, string metadataCompletness, IEnumerable<DisciplineObject> disciplines, IEnumerable<OrganizationObject> organizations, User user) { var resourceTypes = _resourceTypeModel.GetAllWhere(x => x.Enabled.HasValue && x.Enabled.Value); var objects = resourceTypes.Select(x => CreateProjectQuotaReturnObject(x, project.Id)); _coscineLogger.AnalyticsLog( new AnalyticsLogObject { Type = "Action", Operation = "Add Project", RoleId = _projectRoleModel.GetGetUserRoleForProject(project.Id, user.Id).ToString(), ProjectId = project.Id.ToString(), QuotaSize = objects.Select(x => $"{x.Name}: {x.Used}/{x.Allocated}").ToList(), MetadataCompleteness = metadataCompletness, Disciplines = disciplines.Select(x => x.DisplayNameEn).ToList(), Organizations = organizations.Select(x => x.DisplayName).ToList(), Visibility = project.VisibilityId.HasValue ? _visibilityModel.GetById(project.VisibilityId.Value)?.DisplayName : null, }); } private void LogAnalyticsDeleteProject(Database.DataModel.Project project, IEnumerable<DisciplineObject> disciplines, IEnumerable<OrganizationObject> organizations, User user) { var resourceTypes = _resourceTypeModel.GetAllWhere(x => x.Enabled.HasValue && x.Enabled.Value); var objects = resourceTypes.Select(x => CreateProjectQuotaReturnObject(x, project.Id)); _coscineLogger.AnalyticsLog( new AnalyticsLogObject { Type = "Action", Operation = "Delete Project", RoleId = _projectRoleModel.GetGetUserRoleForProject(project.Id, user.Id).ToString(), ProjectId = project.Id.ToString(), QuotaSize = objects.Select(x => $"{x.Name}: {x.Used}/{x.Allocated}").ToList(), Disciplines = disciplines.Select(x => x.DisplayNameEn).ToList(), Organizations = organizations.Select(x => x.DisplayName).ToList(), Visibility = project.VisibilityId.HasValue ? _visibilityModel.GetById(project.VisibilityId.Value)?.DisplayName : null, }); } } }