Skip to content
Snippets Groups Projects
Select Git revision
  • master
  • developement_1 protected
  • Version_1.2.4
  • Version_1.2.3
  • Version_1.2.2
  • Version_1.2.1
  • Version_1.2.0
  • Version_1.0.1
  • Version_1.0.0
  • Version_0.1.0
  • Version_0.0.6
  • Version_0.0.5
  • Version_0.0.4
  • Version_0.0.3
  • Version_0.0.2
  • Version_0.0.1
16 results

OpenGlController.cpp

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    ProjectController.cs 16.92 KiB
    using Coscine.Action;
    using Coscine.Action.EventArgs;
    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 System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace Coscine.Api.Project.Controllers
    {
        [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 CoscineLogger _coscineLogger;
            private readonly AnalyticsLogObject _analyticsLogObject;
    
            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();
                _coscineLogger = new CoscineLogger(logger);
                _analyticsLogObject = new AnalyticsLogObject();
            }
            
            [Route("[controller]")]
            public IActionResult Index()
            {
                var user = _authenticator.GetUser();
                var result = _projectModel.GetWithAccess(user, UserRoles.Member, UserRoles.Owner).ToList()
                    .Select((project) => _projectModel.CreateReturnObjectFromDatabaseObject(project))
                    .OrderBy(element => element.DisplayName);
    
                if (Request.Query != null && Request.Query["noanalyticslog"] != "true")
                {
                    LogAnalytics("List Projects", result);
                }
    
                return Ok(result);
            }
    
            [Route("[controller]/-/topLevel")]
            public IActionResult GetTopLevelProjects()
            {
                var user = _authenticator.GetUser();
                var result = _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")
                {
                    LogAnalytics("View Home", result);
                }
    
                return Ok(result);
            }
    
            [HttpGet("[controller]/{id}")]
            public IActionResult 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}");
                }
            }
    
            [HttpGet("[controller]/{id}/resources")]
            public IActionResult 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.ProjectResourceResourceIdIds
                             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")
                    {
                        LogAnalytics("View Project", null, resources, id, user); // intentionally log as view project to help identify the related user action
                    }
                    return Json(resources);
                }
                else
                {
                    return Unauthorized($"User is not allowed to see given the project {id}");
                }
            }
    
            [HttpGet("[controller]/{id}/quotas")]
            public IActionResult Quotas(string id)
            {
                var user = _authenticator.GetUser();
                var projectObject = ObjectFactory<ProjectObject>.DeserializeFromStream(Request.Body);
                var guidId = Guid.Parse(id);
                var project = _projectModel.GetById(guidId);
                if (_projectModel.HasAccess(user, project, UserRoles.Owner))
                {
                    ProjectQuotaModel projectQuotaModel = new ProjectQuotaModel();
                    var projectQuotas =
                        projectQuotaModel.GetAllWhere((projectQuota) =>
                            projectQuota.ProjectId == guidId
                            && projectQuota.ResourceType.Enabled == true)
                        .Select((projectQuota) => projectQuotaModel.CreateReturnObjectFromDatabaseObject(projectQuota));
    
    
                    ResourceModel resourceModel = new ResourceModel();
                    RDSResourceTypeModel rdsResourceTypeModel = new RDSResourceTypeModel();
                    var returnList = new List<dynamic>();
                    foreach (var projectQuota in projectQuotas)
                    {
                        // TODO: Cleanup quota and give it to every resource, this hard coded solution seems not scalable
                        if (projectQuota.ResourceType.DisplayName == "rds") 
                        {
                            var resources = resourceModel.GetAllWhere((resource) =>
                                                resource.TypeId == projectQuota.ResourceType.Id
                                                && (from connection in resource.ProjectResourceResourceIdIds
                                                    where connection.ProjectId == guidId
                                                    select connection).Any());
                            
                            var size = resources.Sum((resource) => 
                                    rdsResourceTypeModel.GetById(resource.ResourceTypeOptionId.Value).Size);
                            returnList.Add(new { 
                                type = projectQuota.ResourceType.DisplayName, 
                                available = projectQuota.Quotas,
                                allocated = size
                            });
                        }
                    }
                    return Json(returnList);
                }
                else
                {
                    return Unauthorized("The user is not authorized to perform a get on the selected project!");
                }
            }
    
            [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))
                {
                    LogAnalytics("Edit Project", null, null, id, user);
                    return Ok(_projectModel.UpdateByObject(project, projectObject));
                }
                else
                {
                    return Unauthorized("The user is not authorized to perform an update on the selected project!");
                }
            }
    
            [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))
                {
                    LogAnalytics("Delete Project", null, null, id, user);
                    DeleteProject(project);
                    return Json(_projectModel.CreateReturnObjectFromDatabaseObject(project));
                }
                else
                {
                    return Unauthorized("The user is not authorized to perform an update on the selected project!");
                }
            }
    
            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.SubProject_FK.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);
                    }
    
                    var projectQuotaModel = new ProjectQuotaModel();
                    foreach (var projectQuota in projectQuotaModel.GetAllWhere((Quota) => Quota.ProjectId == project.Id))
                    {
                        projectQuotaModel.Delete(projectQuota);
                    }
    
                    _activatedFeaturesModel.DeactivateAllFeatures(project);
    
                    if (propegateAction)
                    {
                        _emitter.EmitProjectDelete(new ProjectEventArgs(_configuration)
                        {
                            Project = project
                        });
                    }
    
                    _projectModel.HardDelete(project);
                }
                else
                {
                    _projectModel.Delete(project);
                }
            }
    
            [HttpPost("[controller]")]
            public IActionResult Store()
            {
                var user = _authenticator.GetUser();
                var isRWTHMember = IsRWTHMember(user);
                var projectObject = ObjectFactory<ProjectObject>.DeserializeFromStream(Request.Body);
    
                if (projectObject.ParentId != null
                    && 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, isRWTHMember);
    
                if (projectObject.ParentId != null
                    && 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
                });
    
                LogAnalytics("Add Project", null, null, project.Id.ToString(), user);
    
                return Json(_projectModel.CreateReturnObjectFromDatabaseObject(project));
            }
    
            private bool IsRWTHMember(User user)
            {
                var externalIds = new ExternalIdModel().GetAllWhere((externalId) => externalId.UserId == user.Id);
                if(externalIds.Count() == 0)
                {
                    return false;
                }
                var externalIdList = new List<string>();
                
                foreach (var externalId in externalIds)
                {
                    externalIdList.Add(externalId.ExternalIdColumn);
                }
                return new RdfStoreConnector(Program.Configuration.GetStringAndWait("coscine/local/virtuoso/additional/url")).GetTriples(new Uri("https://ror.org/04xfq0f34"), null, null, 1, externalIdList).Count() != 0;
            }
    
            private void LogAnalytics(string operation,
                IEnumerable<ProjectObject> projects = null,
                IEnumerable<ResourceObject> resources = null,
                string projectId = null,
                User user = null
            )
            {
                if (CoscineLoggerConfiguration.IsLogLevelActivated(LogType.Analytics))
                {
                    _analyticsLogObject.Type = "Action";
                    _analyticsLogObject.Operation = operation;
    
                    if (projects != null)
                    {
                        List<string> projectList = new List<string>();
                        foreach (var entry in projects)
                        {
                            projectList.Add(entry.Id.ToString());
                        }
                        _analyticsLogObject.ProjectList = projectList;
                    }
                    if (resources != null)
                    {
                        List<string> shownResources = new List<string>();
                        foreach (var entry in resources)
                        {
                            shownResources.Add(entry.Id.ToString());
                        }
                        _analyticsLogObject.ResourceList = shownResources;
                    }
                    if (projectId != null)
                    {
                        _analyticsLogObject.ProjectId = projectId;
                        if (user != null)
                        {
                            _analyticsLogObject.RoleId = _projectRoleModel.GetGetUserRoleForProject(new Guid(_analyticsLogObject.ProjectId), user.Id).ToString();
                        }
                    }
                    _coscineLogger.AnalyticsLog(_analyticsLogObject);
                }
            }
        }
    }