Aufgrund einer Konfigurationsänderung wird die GitLab Registry ab 10 Uhr nur Read Only zur Verfügung stehen. / Due to a configuration change, the GitLab Registry will be available for read-only access from 10am.

Commit de72866a authored by Benedikt Heinrichs's avatar Benedikt Heinrichs

Merge branch 'Topic/632-projectDeletion' into 'Product/593-projectDeletion'

New: Soft delete to search, test, controller and subprojects

See merge request !70
parents b398e03d 3b4d6548
stages:
- build
- test
- docs
- update-assembly-info
- build-release
- semantic-release
- release
- pre_release
- releasetrigger
build:
stage: build
script:
- PowerShell .\build.ps1 -Target Build -Configuration Debug
variables:
GIT_STRATEGY: clone
except:
variables:
- $GITLAB_USER_ID == $GIT_BOT_USER_ID
test:
cake:Test:
stage: test
script:
- PowerShell .\build.ps1 -Target LinterAndTest -Configuration Debug
- PowerShell .\build.ps1 -Target Test -Configuration Debug
variables:
GIT_STRATEGY: none
dependencies:
- build
GIT_STRATEGY: clone
artifacts:
reports:
junit: "./Artifacts/TestResults.xml"
paths:
- "./Artifacts/*"
except:
variables:
- $GITLAB_USER_ID == $GIT_BOT_USER_ID
update-assembly-info:
stage: update-assembly-info
script:
- PowerShell .\build.ps1 -Target UpdateAssemblyInfo
variables:
GIT_STRATEGY: none
dependencies:
- test
only:
- master
except:
variables:
- $GITLAB_USER_ID == $GIT_BOT_USER_ID
build-release:
stage: build-release
script:
- PowerShell .\build.ps1 -Target Build -Configuration Release
- PowerShell .\build.ps1 -Configuration Release -Target NugetPack
variables:
GIT_STRATEGY: none
dependencies:
- update-assembly-info
only:
- master
except:
variables:
- $GITLAB_USER_ID == $GIT_BOT_USER_ID
- tags
docs:
stage: docs
script:
- .\publishDocs.ps1 $GITLAB_TOKEN
variables:
GIT_STRATEGY: none
dependencies:
- test
only:
- master
except:
variables:
- $GITLAB_USER_ID == $GIT_BOT_USER_ID
semantic-release:
stage: semantic-release
script:
- PowerShell .\build.ps1 -Target SemanticRelease
variables:
GIT_STRATEGY: none
dependencies:
- test
GIT_STRATEGY: clone
only:
- master
except:
variables:
- $GITLAB_USER_ID == $GIT_BOT_USER_ID
- tags
release:
before_script:
cake:Release:
stage: release
script:
- PowerShell .\build.ps1 -Target Build -Configuration Release
- PowerShell .\build.ps1 -Configuration Release -Target NugetPack
- PowerShell .\build.ps1 -Configuration Release -Target NugetPush --nugetApiKey="$NUGET_API_KEY"
- PowerShell .\build.ps1 -Target Release -Configuration Release --nugetApiKey="${NUGET_API_KEY}"
variables:
GIT_STRATEGY: clone
dependencies:
- cake:Test
artifacts:
paths:
- "./Artifacts/*"
only:
- tags
pre_release:
stage: pre_release
cake:Prerelease:
stage: release
script:
- PowerShell .\build.ps1 -Target Build -Configuration Release
- PowerShell .\build.ps1 -Target Prerelease -Configuration Release
variables:
GIT_STRATEGY: clone
dependencies:
- cake:Test
artifacts:
paths:
- "./Artifacts/*"
when: manual
except:
- tags
- master
\ No newline at end of file
- master
cake:GitlabRelease:
stage: releasetrigger
script:
- PowerShell .\build.ps1 -Target GitlabRelease --GitlabProjectPath="${CI_PROJECT_PATH}" --gitlabProjectId="${CI_PROJECT_ID}" --gitlabToken="${GITLAB_TOKEN}"
only:
- master
\ No newline at end of file
{
"plugins": [
["@semantic-release/commit-analyzer", {
"preset": "eslint"
}],
["@semantic-release/release-notes-generator", {
"preset": "eslint",
}],
["@semantic-release/gitlab", {
"preset": "eslint",
"gitlabUrl": "https://git.rwth-aachen.de"
}],
["@semantic-release/exec", {
"prepareCmd" : "echo ${nextRelease.version}",
"publishCmd" : "echo test"
}],
["@semantic-release/git", {
"preset": "eslint",
"assets": "src/**/Properties/AssemblyInfo.cs",
"message": "Chore: ${nextRelease.version}\n\n${nextRelease.notes}"
}]
]
}
mode: ContinuousDeployment
next-version: 1.0.0
major-version-bump-message: 'Breaking:'
minor-version-bump-message: '(Update|New):'
patch-version-bump-message: 'Fix:'
no-bump-message: '.*'
commit-message-incrementing: Enabled
\ No newline at end of file
This diff is collapsed.
......@@ -293,7 +293,7 @@ namespace Coscine.Api.Project.Tests
ProjectController projectController = new ProjectController();
foreach (var project in Projects)
{
projectController.DeleteProject(project);
projectController.DeleteProject(project, true);
}
UserModel userModel = new UserModel();
foreach (var user in Users)
......
......@@ -59,14 +59,14 @@
<Reference Include="Coscine.Action, Version=1.8.0.0, Culture=neutral, processorArchitecture=AMD64">
<HintPath>..\packages\Coscine.Action.1.8.0\lib\net461\Coscine.Action.dll</HintPath>
</Reference>
<Reference Include="Coscine.ApiCommons, Version=1.4.0.0, Culture=neutral, PublicKeyToken=af4c1345df96546b, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.ApiCommons.1.4.0\lib\net461\Coscine.ApiCommons.dll</HintPath>
<Reference Include="Coscine.ApiCommons, Version=1.5.0.0, Culture=neutral, PublicKeyToken=af4c1345df96546b, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.ApiCommons.1.5.0-topic-632-projec0001\lib\net461\Coscine.ApiCommons.dll</HintPath>
</Reference>
<Reference Include="Coscine.Configuration, Version=1.4.0.0, Culture=neutral, PublicKeyToken=ce3d7a32d7dc1e5a, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.Configuration.1.4.0\lib\net461\Coscine.Configuration.dll</HintPath>
</Reference>
<Reference Include="Coscine.Database, Version=1.14.0.0, Culture=neutral, PublicKeyToken=767d77427707b70a, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.Database.1.14.0\lib\net461\Coscine.Database.dll</HintPath>
<Reference Include="Coscine.Database, Version=1.15.0.0, Culture=neutral, PublicKeyToken=767d77427707b70a, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.Database.1.15.0-topic-632-projec0005\lib\net461\Coscine.Database.dll</HintPath>
</Reference>
<Reference Include="Coscine.Logging, Version=1.0.1.0, Culture=neutral, PublicKeyToken=e1ed402bc3f6525e, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.Logging.1.0.1\lib\net461\Coscine.Logging.dll</HintPath>
......
......@@ -125,7 +125,7 @@ namespace Coscine.Api.Project.Tests
ProjectModel projectModel = new ProjectModel();
var project = projectModel.GetById(createdProjectObject.Id);
Controller.DeleteProject(project);
Controller.DeleteProject(project, true);
}
......@@ -248,7 +248,7 @@ namespace Coscine.Api.Project.Tests
ProjectModel projectModel = new ProjectModel();
var project = projectModel.GetById(createdProjectObject.Id);
Controller.DeleteProject(project);
Controller.DeleteProject(project, true);
}
[Test]
......
......@@ -88,7 +88,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Coscine.Database" publicKeyToken="767d77427707b70a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.14.0.0" newVersion="1.14.0.0" />
<bindingRedirect oldVersion="0.0.0.0-1.15.0.0" newVersion="1.15.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" />
......
......@@ -5,9 +5,9 @@
<package id="Castle.Core" version="4.4.0" targetFramework="net472" />
<package id="Consul" version="0.7.2.6" targetFramework="net472" />
<package id="Coscine.Action" version="1.8.0" targetFramework="net472" />
<package id="Coscine.ApiCommons" version="1.4.0" targetFramework="net472" />
<package id="Coscine.ApiCommons" version="1.5.0-topic-632-projec0001" targetFramework="net472" />
<package id="Coscine.Configuration" version="1.4.0" targetFramework="net472" />
<package id="Coscine.Database" version="1.14.0" targetFramework="net472" />
<package id="Coscine.Database" version="1.15.0-topic-632-projec0005" targetFramework="net472" />
<package id="Coscine.Logging" version="1.0.1" targetFramework="net472" />
<package id="Coscine.ProxyApi" version="1.2.1" targetFramework="net472" />
<package id="Coscine.SharePoint.Webparts.Vue" version="1.4.0" targetFramework="net472" />
......
......@@ -91,7 +91,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Coscine.Database" publicKeyToken="767d77427707b70a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.14.0.0" newVersion="1.14.0.0" />
<bindingRedirect oldVersion="0.0.0.0-1.15.0.0" newVersion="1.15.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" />
......
......@@ -49,7 +49,7 @@ namespace Coscine.Api.Project.Controllers
if (_projectModel.HasAccess(user, project, UserRoles.Member, UserRoles.Owner))
{
SubProjectModel subProjectModel = new SubProjectModel();
var subProjectRel = subProjectModel.GetAllWhere((subProject) => subProject.SubProjectId == project.Id);
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))
......@@ -121,52 +121,80 @@ namespace Coscine.Api.Project.Controllers
}
}
public void DeleteProject(Database.Model.Project project)
public void DeleteProject(Database.Model.Project project, bool isHard = false)
{
var subProjectModel = new SubProjectModel();
foreach(var subProject in subProjectModel.GetAllWhere((subProject) => subProject.ProjectId == project.Id))
foreach(var subProject in subProjectModel.GetAllWhere((subProject) => subProject.ProjectId == project.Id && project.Deleted == false))
{
subProjectModel.Delete(subProject);
DeleteProject(_projectModel.GetById(subProject.SubProjectId));
if (isHard)
{
subProjectModel.Delete(subProject);
}
DeleteProject(_projectModel.GetById(subProject.SubProjectId), isHard);
}
foreach (var subProject in subProjectModel.GetAllWhere((subProject) => subProject.SubProjectId == project.Id))
foreach (var subProject in subProjectModel.GetAllWhere((subProject) => subProject.SubProjectId == project.Id && project.Deleted == false))
{
subProjectModel.Delete(subProject);
if (isHard)
{
subProjectModel.Delete(subProject);
}
}
var projectResourceModel = new ProjectResourceModel();
ResourceModel resourceModel = new ResourceModel();
foreach (var projectResource in projectResourceModel.GetAllWhere((projectResource) => projectResource.ProjectId == project.Id))
foreach (var projectResource in projectResourceModel.GetAllWhere((projectResource) => projectResource.ProjectId == project.Id && project.Deleted == false))
{
projectResourceModel.Delete(projectResource);
resourceModel.Delete(resourceModel.GetById(projectResource.ResourceId));
if (isHard)
{
projectResourceModel.Delete(projectResource);
resourceModel.Delete(resourceModel.GetById(projectResource.ResourceId));
}
}
var projectRoleModel = new ProjectRoleModel();
foreach (var projectRole in projectRoleModel.GetAllWhere((projectRole) => projectRole.ProjectId == project.Id))
foreach (var projectRole in projectRoleModel.GetAllWhere((projectRole) => projectRole.ProjectId == project.Id && project.Deleted == false))
{
projectRoleModel.Delete(projectRole);
if (isHard)
{
projectRoleModel.Delete(projectRole);
}
}
var projectDisciplineModel = new ProjectDisciplineModel();
foreach (var projectDiscipline in projectDisciplineModel.GetAllWhere((projectDiscipline) => projectDiscipline.ProjectId == project.Id))
foreach (var projectDiscipline in projectDisciplineModel.GetAllWhere((projectDiscipline) => projectDiscipline.ProjectId == project.Id && project.Deleted == false))
{
projectDisciplineModel.Delete(projectDiscipline);
if (isHard)
{
projectDisciplineModel.Delete(projectDiscipline);
}
}
var projectInstituteModel = new ProjectInstituteModel();
foreach (var projectInstitute in projectInstituteModel.GetAllWhere((projectInstitute) => projectInstitute.ProjectId == project.Id))
foreach (var projectInstitute in projectInstituteModel.GetAllWhere((projectInstitute) => projectInstitute.ProjectId == project.Id && project.Deleted == false))
{
projectInstituteModel.Delete(projectInstitute);
if (isHard)
{
projectInstituteModel.Delete(projectInstitute);
}
}
_emitter.EmitProjectDelete(new ProjectEventArgs(_configuration)
if (isHard)
{
Project = project
});
_emitter.EmitProjectDelete(new ProjectEventArgs(_configuration)
{
Project = project
});
}
_projectModel.Delete(project);
if (isHard)
{
_projectModel.HardDelete(project);
} else
{
_projectModel.Delete(project);
}
}
[HttpPost("[controller]")]
......
......@@ -149,7 +149,8 @@ namespace Coscine.Api.Project.Controllers
join i in db.Institutes on jpi.InstituteId equals i.Id into joinedI
from ji in joinedI.DefaultIfEmpty()
where ((!showSubProjects && p.Id.NotIn(allSubProjectsList)) ||
where p.Deleted == false &&
((!showSubProjects && p.Id.NotIn(allSubProjectsList)) ||
(showSubProjects && p.Id.In(allSubProjectsList))) &&
(jpr.UserId.Equals(userId) || jv.DisplayName.Equals("Public")) &&
(projectId.Equals("") || p.Id.In(listOfSubprojects)) &&
......@@ -195,7 +196,8 @@ namespace Coscine.Api.Project.Controllers
join rt in db.ResourceTypes on r.TypeId equals rt.Id into joinedRt
from jrt in joinedRt.DefaultIfEmpty()
where (jpr.UserId.Equals(userId) || jv.DisplayName.Equals("Public")) &&
where jp.Deleted == false &&
(jpr.UserId.Equals(userId) || jv.DisplayName.Equals("Public")) &&
(projectId.Equals("") || jp.Id.In(listOfSubprojects)) &&
(searchQuery.Equals("") ||
r.ResourceName.Contains(searchQuery) ||
......
......@@ -30,10 +30,14 @@ namespace Coscine.Api.Project.Controllers
allowedRoles = allowedRoles.Select(x => x.ToLower().Trim()).ToArray();
if (projectModel.HasAccess(user, projectModel.GetById(parentGuid), allowedRoles))
{
var subProjects = _subProjectModel.GetAllWhere((subProjectM) => (subProjectM.ProjectId == parentGuid
var subProjects = _subProjectModel.GetAllWhere((subProjectM) => (subProjectM.ProjectId == parentGuid
// Corrosponing subproject must exist
&& subProjectM.Project.Deleted == false
// select only subprojects to which the user has access
&& (from projectRole in subProjectM.SubProject_FK.ProjectRolesProjectIdIds
where projectRole.User.Id == user.Id
where projectRole.User.Id == user.Id
&& allowedRoles.Contains(projectRole.Role.DisplayName.ToLower())
select projectRole).Any())
)
......
......@@ -5,6 +5,7 @@ using System.Linq.Expressions;
using Coscine.Api.Project.ReturnObjects;
using Coscine.ApiCommons.Models;
using Coscine.Database.Model;
using LinqKit;
using LinqToDB;
namespace Coscine.Api.Project.Models
......@@ -16,6 +17,97 @@ namespace Coscine.Api.Project.Models
{
}
public bool IsDeleted(Guid id)
{
return DatabaseConnection.ConnectToDatabase((db) =>
{
return
(from tableEntry in GetITableFromDatabase(db).AsExpandable()
where tableEntry.Id == id
&& tableEntry.Deleted == true
select tableEntry).Count() == 1;
});
}
public override Database.Model.Project GetById(Guid id)
{
var expression = GetIdFromObject();
return DatabaseConnection.ConnectToDatabase((db) =>
{
return
(from tableEntry in GetITableFromDatabase(db).AsExpandable()
where expression.Invoke(tableEntry) == id
&& tableEntry.Deleted == false
select tableEntry).First();
});
}
public override Database.Model.Project GetWhere(Expression<Func<Database.Model.Project, bool>> whereClause)
{
return DatabaseConnection.ConnectToDatabase((db) =>
{
return
(from tableEntry in GetITableFromDatabase(db).AsExpandable()
where whereClause.Invoke(tableEntry)
&& tableEntry.Deleted == false
select tableEntry).First();
});
}
public override IEnumerable<Database.Model.Project> GetAll()
{
return DatabaseConnection.ConnectToDatabase((db) =>
{
return
(from tableEntry in GetITableFromDatabase(db)
where tableEntry.Deleted == false
select tableEntry).ToList();
});
}
public override IEnumerable<Database.Model.Project> GetAllWhere(Expression<Func<Database.Model.Project, bool>> whereClause)
{
return DatabaseConnection.ConnectToDatabase((db) =>
{
return
(from tableEntry in GetITableFromDatabase(db).AsExpandable()
where whereClause.Invoke(tableEntry)
&& tableEntry.Deleted == false
select tableEntry).ToList();
});
}
public override int Update(Database.Model.Project databaseObject)
{
if (databaseObject.Deleted != false)
{
return DatabaseConnection.ConnectToDatabase((db) =>
{
return db.Update(databaseObject);
});
} else
{
return 0;
}
}
public override int Delete(Database.Model.Project databaseObject)
{
databaseObject.Deleted = true;
return DatabaseConnection.ConnectToDatabase((db) =>
{
return db.Update(databaseObject);
});
}
public int HardDelete(Database.Model.Project databaseObject)
{
return DatabaseConnection.ConnectToDatabase((db) =>
{
return db.Delete(databaseObject);
});
}
public Coscine.Database.Model.Project StoreFromObject(ProjectObject projectObject, User user)
{
if(projectObject.Disciplines.Count() == 0 || projectObject.Institutes.Count() == 0)
......@@ -45,7 +137,7 @@ namespace Coscine.Api.Project.Models
}
catch (Exception e)
{
Delete(project);
HardDelete(project);
throw e;
}
SetOwner(project, user);
......
......@@ -49,14 +49,14 @@
<Reference Include="Coscine.Action, Version=1.8.0.0, Culture=neutral, processorArchitecture=AMD64">
<HintPath>..\packages\Coscine.Action.1.8.0\lib\net461\Coscine.Action.dll</HintPath>
</Reference>
<Reference Include="Coscine.ApiCommons, Version=1.4.0.0, Culture=neutral, PublicKeyToken=af4c1345df96546b, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.ApiCommons.1.4.0\lib\net461\Coscine.ApiCommons.dll</HintPath>
<Reference Include="Coscine.ApiCommons, Version=1.5.0.0, Culture=neutral, PublicKeyToken=af4c1345df96546b, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.ApiCommons.1.5.0-topic-632-projec0001\lib\net461\Coscine.ApiCommons.dll</HintPath>
</Reference>
<Reference Include="Coscine.Configuration, Version=1.4.0.0, Culture=neutral, PublicKeyToken=ce3d7a32d7dc1e5a, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.Configuration.1.4.0\lib\net461\Coscine.Configuration.dll</HintPath>
</Reference>
<Reference Include="Coscine.Database, Version=1.14.0.0, Culture=neutral, PublicKeyToken=767d77427707b70a, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.Database.1.14.0\lib\net461\Coscine.Database.dll</HintPath>
<Reference Include="Coscine.Database, Version=1.15.0.0, Culture=neutral, PublicKeyToken=767d77427707b70a, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.Database.1.15.0-topic-632-projec0005\lib\net461\Coscine.Database.dll</HintPath>
</Reference>
<Reference Include="Coscine.Logging, Version=1.0.1.0, Culture=neutral, PublicKeyToken=e1ed402bc3f6525e, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.Logging.1.0.1\lib\net461\Coscine.Logging.dll</HintPath>
......
......@@ -4,9 +4,9 @@
<package id="AutoMapper.Extensions.Microsoft.DependencyInjection" version="6.0.0" targetFramework="net472" />
<package id="Consul" version="0.7.2.6" targetFramework="net472" />
<package id="Coscine.Action" version="1.8.0" targetFramework="net472" />
<package id="Coscine.ApiCommons" version="1.4.0" targetFramework="net472" />
<package id="Coscine.ApiCommons" version="1.5.0-topic-632-projec0001" targetFramework="net472" />
<package id="Coscine.Configuration" version="1.4.0" targetFramework="net472" />
<package id="Coscine.Database" version="1.14.0" targetFramework="net472" />
<package id="Coscine.Database" version="1.15.0-topic-632-projec0005" targetFramework="net472" />
<package id="Coscine.Logging" version="1.0.1" targetFramework="net472" />
<package id="Coscine.ProxyApi" version="1.2.1" targetFramework="net472" />
<package id="Coscine.SharePoint.Webparts.Vue" version="1.4.0" targetFramework="net472" />
......
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Cake" version="0.28.0" />
<package id="Cake" version="0.36.0" />
</packages>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment