diff --git a/src/.tools/linq2db.t4models/FirebirdSql.Data.FirebirdClient.dll b/src/.tools/linq2db.t4models/FirebirdSql.Data.FirebirdClient.dll
new file mode 100644
index 0000000000000000000000000000000000000000..dd8e0105289d37e4be97c1419fd12a2cbc6e00c4
Binary files /dev/null and b/src/.tools/linq2db.t4models/FirebirdSql.Data.FirebirdClient.dll differ
diff --git a/src/.tools/linq2db.t4models/Init.ps1 b/src/.tools/linq2db.t4models/Init.ps1
new file mode 100644
index 0000000000000000000000000000000000000000..d7e710d55907097cf93d3d3e546801028e12d906
--- /dev/null
+++ b/src/.tools/linq2db.t4models/Init.ps1
@@ -0,0 +1,9 @@
+param($installPath, $toolsPath, $package, $project)
+
+# get the active solution
+$solution           = Get-Interface $dte.Solution ([EnvDTE80.Solution2])
+$solutionPath       = [System.IO.Path]::GetDirectoryName($solution.FullName)
+$linq2dbToolsPath   = [System.IO.Path]::Combine($solutionPath, ".tools", "linq2db.t4models")
+
+# tools copy
+xcopy $("$toolsPath\*.*") $("$linq2dbToolsPath\") /y /e
diff --git a/src/.tools/linq2db.t4models/Microsoft.SqlServer.Types.dll b/src/.tools/linq2db.t4models/Microsoft.SqlServer.Types.dll
new file mode 100644
index 0000000000000000000000000000000000000000..d4dd789939d82c83eb2720bf5868234ffafca86d
Binary files /dev/null and b/src/.tools/linq2db.t4models/Microsoft.SqlServer.Types.dll differ
diff --git a/src/.tools/linq2db.t4models/MySql.Data.dll b/src/.tools/linq2db.t4models/MySql.Data.dll
new file mode 100644
index 0000000000000000000000000000000000000000..d97ad46b903f211ecb4e3e09bc44e7128ec887e2
Binary files /dev/null and b/src/.tools/linq2db.t4models/MySql.Data.dll differ
diff --git a/src/.tools/linq2db.t4models/Npgsql.dll b/src/.tools/linq2db.t4models/Npgsql.dll
new file mode 100644
index 0000000000000000000000000000000000000000..c814b2681c107eac00cbb32812954bc9d163ba73
Binary files /dev/null and b/src/.tools/linq2db.t4models/Npgsql.dll differ
diff --git a/src/.tools/linq2db.t4models/Oracle.ManagedDataAccess.dll b/src/.tools/linq2db.t4models/Oracle.ManagedDataAccess.dll
new file mode 100644
index 0000000000000000000000000000000000000000..c228b7093fb73194e9bf9689d99b1154a963cf15
Binary files /dev/null and b/src/.tools/linq2db.t4models/Oracle.ManagedDataAccess.dll differ
diff --git a/src/.tools/linq2db.t4models/SQLite.Interop.dll b/src/.tools/linq2db.t4models/SQLite.Interop.dll
new file mode 100644
index 0000000000000000000000000000000000000000..5b872055f5a4b1b759bfa0811901675d4c01346b
Binary files /dev/null and b/src/.tools/linq2db.t4models/SQLite.Interop.dll differ
diff --git a/src/.tools/linq2db.t4models/System.Data.SQLite.dll b/src/.tools/linq2db.t4models/System.Data.SQLite.dll
new file mode 100644
index 0000000000000000000000000000000000000000..59f3dcc375988dbd291f100bd06f259b88a887e0
Binary files /dev/null and b/src/.tools/linq2db.t4models/System.Data.SQLite.dll differ
diff --git a/src/.tools/linq2db.t4models/System.Threading.Tasks.Extensions.dll b/src/.tools/linq2db.t4models/System.Threading.Tasks.Extensions.dll
new file mode 100644
index 0000000000000000000000000000000000000000..6807cbd9ba040b9f721a03d7fbe6bc0ec088d50b
Binary files /dev/null and b/src/.tools/linq2db.t4models/System.Threading.Tasks.Extensions.dll differ
diff --git a/src/.tools/linq2db.t4models/linq2db.dll b/src/.tools/linq2db.t4models/linq2db.dll
new file mode 100644
index 0000000000000000000000000000000000000000..bcbdac1d0742aad9fe3866797e3036961812b53d
Binary files /dev/null and b/src/.tools/linq2db.t4models/linq2db.dll differ
diff --git a/src/Project.Tests/DefaultControllerTests.cs b/src/Project.Tests/DefaultControllerTests.cs
index 23a03e8ecc96c23982af9dd2852cde5520bc1ff9..2869e18f722ed2f5c0c0c1fe0bca75ddf8d63f6a 100644
--- a/src/Project.Tests/DefaultControllerTests.cs
+++ b/src/Project.Tests/DefaultControllerTests.cs
@@ -13,6 +13,7 @@ using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using System.Management;
+using System.Security.Claims;
 
 namespace Coscine.Api.Project.Tests
 {
@@ -144,9 +145,8 @@ namespace Coscine.Api.Project.Tests
             RDSResourceTypeModel rdsResourceTypeModel = new RDSResourceTypeModel();
             RdsResourceType = new RDSResourceType()
             {
-                AccessKey = "a",
-                SecretKey = "b",
                 BucketName = "c",
+                Size = 25,
             };
             rdsResourceTypeModel.Insert(RdsResourceType);
 
@@ -258,6 +258,11 @@ namespace Coscine.Api.Project.Tests
             var context = new Mock<HttpContext>();
             context.SetupGet(x => x.Request).Returns(request.Object);
 
+            var claimsPrincipal = new Mock<ClaimsPrincipal>();
+            Claim claim = new Claim("UserID", user.Id.ToString());
+            context.SetupGet(x => x.User).Returns(claimsPrincipal.Object);
+            context.Setup(x => x.User.FindFirst("UserID")).Returns(claim);
+
             if (stream != null)
             {
                 context.SetupGet(x => x.Request.Method).Returns("POST");
diff --git a/src/Project.Tests/Project.Tests.csproj b/src/Project.Tests/Project.Tests.csproj
index 22e8f5d86f93079333bf6d522476ef3cd399e6e5..4faef05e407b110d2175658f1349305a38acaef1 100644
--- a/src/Project.Tests/Project.Tests.csproj
+++ b/src/Project.Tests/Project.Tests.csproj
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\packages\NUnit.3.12.0\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" />
   <Import Project="..\packages\Microsoft.AspNetCore.Mvc.Razor.Extensions.2.2.0\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.props" Condition="Exists('..\packages\Microsoft.AspNetCore.Mvc.Razor.Extensions.2.2.0\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.props')" />
   <Import Project="..\packages\Microsoft.Extensions.Configuration.UserSecrets.2.2.0\build\netstandard2.0\Microsoft.Extensions.Configuration.UserSecrets.props" Condition="Exists('..\packages\Microsoft.Extensions.Configuration.UserSecrets.2.2.0\build\netstandard2.0\Microsoft.Extensions.Configuration.UserSecrets.props')" />
   <Import Project="..\packages\Microsoft.DiaSymReader.Native.1.7.0\build\Microsoft.DiaSymReader.Native.props" Condition="Exists('..\packages\Microsoft.DiaSymReader.Native.1.7.0\build\Microsoft.DiaSymReader.Native.props')" />
@@ -8,7 +9,6 @@
   <Import Project="..\packages\linq2db.t4models.2.6.4\build\linq2db.t4models.props" Condition="Exists('..\packages\linq2db.t4models.2.6.4\build\linq2db.t4models.props')" />
   <Import Project="..\packages\linq2db.SqlServer.2.6.4\build\linq2db.SqlServer.props" Condition="Exists('..\packages\linq2db.SqlServer.2.6.4\build\linq2db.SqlServer.props')" />
   <Import Project="..\packages\NUnit3TestAdapter.3.13.0\build\net35\NUnit3TestAdapter.props" Condition="Exists('..\packages\NUnit3TestAdapter.3.13.0\build\net35\NUnit3TestAdapter.props')" />
-  <Import Project="..\packages\NUnit.3.11.0\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.11.0\build\NUnit.props')" />
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -59,14 +59,17 @@
     <Reference Include="Coscine.Action, Version=1.7.0.0, Culture=neutral, processorArchitecture=AMD64">
       <HintPath>..\packages\Coscine.Action.1.7.0\lib\net461\Coscine.Action.dll</HintPath>
     </Reference>
-    <Reference Include="Coscine.ApiCommons, Version=1.2.2.0, Culture=neutral, PublicKeyToken=af4c1345df96546b, processorArchitecture=MSIL">
-      <HintPath>..\packages\Coscine.ApiCommons.1.2.2\lib\net461\Coscine.ApiCommons.dll</HintPath>
+    <Reference Include="Coscine.ApiCommons, Version=1.2.2.3, Culture=neutral, PublicKeyToken=af4c1345df96546b, processorArchitecture=MSIL">
+      <HintPath>..\packages\Coscine.ApiCommons.1.2.2.3\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.10.0.0, Culture=neutral, PublicKeyToken=767d77427707b70a, processorArchitecture=MSIL">
-      <HintPath>..\packages\Coscine.Database.1.10.0\lib\net461\Coscine.Database.dll</HintPath>
+    <Reference Include="Coscine.Database, Version=1.11.0.0, Culture=neutral, PublicKeyToken=767d77427707b70a, processorArchitecture=MSIL">
+      <HintPath>..\packages\Coscine.Database.1.11.0\lib\net461\Coscine.Database.dll</HintPath>
+    </Reference>
+    <Reference Include="Coscine.Logging, Version=0.0.1.0, Culture=neutral, PublicKeyToken=e1ed402bc3f6525e, processorArchitecture=MSIL">
+      <HintPath>..\packages\Coscine.Logging.0.0.1\lib\net461\Coscine.Logging.dll</HintPath>
     </Reference>
     <Reference Include="Coscine.ProxyApi, Version=1.2.0.0, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\packages\Coscine.ProxyApi.1.2.0\lib\net461\Coscine.ProxyApi.dll</HintPath>
@@ -104,12 +107,18 @@
     <Reference Include="Microsoft.AspNetCore.Antiforgery, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
       <HintPath>..\packages\Microsoft.AspNetCore.Antiforgery.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Antiforgery.dll</HintPath>
     </Reference>
+    <Reference Include="Microsoft.AspNetCore.Authentication, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.AspNetCore.Authentication.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Authentication.dll</HintPath>
+    </Reference>
     <Reference Include="Microsoft.AspNetCore.Authentication.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
       <HintPath>..\packages\Microsoft.AspNetCore.Authentication.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Authentication.Abstractions.dll</HintPath>
     </Reference>
     <Reference Include="Microsoft.AspNetCore.Authentication.Core, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
       <HintPath>..\packages\Microsoft.AspNetCore.Authentication.Core.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Authentication.Core.dll</HintPath>
     </Reference>
+    <Reference Include="Microsoft.AspNetCore.Authentication.JwtBearer, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.AspNetCore.Authentication.JwtBearer.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Authentication.JwtBearer.dll</HintPath>
+    </Reference>
     <Reference Include="Microsoft.AspNetCore.Authorization, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
       <HintPath>..\packages\Microsoft.AspNetCore.Authorization.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Authorization.dll</HintPath>
     </Reference>
@@ -368,6 +377,12 @@
     <Reference Include="Microsoft.IdentityModel.Logging, Version=5.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
       <HintPath>..\packages\Microsoft.IdentityModel.Logging.5.6.0\lib\net461\Microsoft.IdentityModel.Logging.dll</HintPath>
     </Reference>
+    <Reference Include="Microsoft.IdentityModel.Protocols, Version=5.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.IdentityModel.Protocols.5.3.0\lib\net461\Microsoft.IdentityModel.Protocols.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect, Version=5.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.IdentityModel.Protocols.OpenIdConnect.5.3.0\lib\net461\Microsoft.IdentityModel.Protocols.OpenIdConnect.dll</HintPath>
+    </Reference>
     <Reference Include="Microsoft.IdentityModel.Tokens, Version=5.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
       <HintPath>..\packages\Microsoft.IdentityModel.Tokens.5.6.0\lib\net461\Microsoft.IdentityModel.Tokens.dll</HintPath>
     </Reference>
@@ -386,8 +401,17 @@
     <Reference Include="Newtonsoft.Json.Bson, Version=1.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
       <HintPath>..\packages\Newtonsoft.Json.Bson.1.0.2\lib\net45\Newtonsoft.Json.Bson.dll</HintPath>
     </Reference>
-    <Reference Include="nunit.framework, Version=3.11.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
-      <HintPath>..\packages\NUnit.3.11.0\lib\net45\nunit.framework.dll</HintPath>
+    <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
+      <HintPath>..\packages\NLog.4.6.8\lib\net45\NLog.dll</HintPath>
+    </Reference>
+    <Reference Include="NLog.Extensions.Logging, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
+      <HintPath>..\packages\NLog.Extensions.Logging.1.6.1\lib\net461\NLog.Extensions.Logging.dll</HintPath>
+    </Reference>
+    <Reference Include="NLog.Web.AspNetCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
+      <HintPath>..\packages\NLog.Web.AspNetCore.4.9.0\lib\net461\NLog.Web.AspNetCore.dll</HintPath>
+    </Reference>
+    <Reference Include="nunit.framework, Version=3.12.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
+      <HintPath>..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.AppContext, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
@@ -495,6 +519,7 @@
       <Private>True</Private>
       <Private>True</Private>
     </Reference>
+    <Reference Include="System.Runtime.Serialization" />
     <Reference Include="System.Security" />
     <Reference Include="System.Security.AccessControl, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
       <HintPath>..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll</HintPath>
@@ -531,6 +556,7 @@
     <Reference Include="System.Security.Principal.Windows, Version=4.1.1.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
       <HintPath>..\packages\System.Security.Principal.Windows.4.5.1\lib\net461\System.Security.Principal.Windows.dll</HintPath>
     </Reference>
+    <Reference Include="System.ServiceModel" />
     <Reference Include="System.ServiceProcess" />
     <Reference Include="System.Text.Encoding.CodePages, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
       <HintPath>..\packages\System.Text.Encoding.CodePages.4.5.1\lib\net461\System.Text.Encoding.CodePages.dll</HintPath>
@@ -562,6 +588,11 @@
       <Private>True</Private>
       <Private>True</Private>
     </Reference>
+    <Reference Include="System.Xml.XmlDocument, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Xml.XmlDocument.4.3.0\lib\net46\System.Xml.XmlDocument.dll</HintPath>
+      <Private>True</Private>
+      <Private>True</Private>
+    </Reference>
     <Reference Include="System.Xml.XPath, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
       <HintPath>..\packages\System.Xml.XPath.4.3.0\lib\net46\System.Xml.XPath.dll</HintPath>
       <Private>True</Private>
@@ -608,7 +639,6 @@
     <PropertyGroup>
       <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
     </PropertyGroup>
-    <Error Condition="!Exists('..\packages\NUnit.3.11.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit.3.11.0\build\NUnit.props'))" />
     <Error Condition="!Exists('..\packages\NUnit3TestAdapter.3.13.0\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit3TestAdapter.3.13.0\build\net35\NUnit3TestAdapter.props'))" />
     <Error Condition="!Exists('..\packages\linq2db.SqlServer.2.6.4\build\linq2db.SqlServer.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\linq2db.SqlServer.2.6.4\build\linq2db.SqlServer.props'))" />
     <Error Condition="!Exists('..\packages\linq2db.t4models.2.6.4\build\linq2db.t4models.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\linq2db.t4models.2.6.4\build\linq2db.t4models.props'))" />
@@ -621,6 +651,7 @@
     <Error Condition="!Exists('..\packages\Microsoft.AspNetCore.Mvc.Razor.Extensions.2.2.0\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.AspNetCore.Mvc.Razor.Extensions.2.2.0\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.targets'))" />
     <Error Condition="!Exists('..\packages\Microsoft.AspNetCore.Server.IIS.2.2.2\build\netstandard2.0\Microsoft.AspNetCore.Server.IIS.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.AspNetCore.Server.IIS.2.2.2\build\netstandard2.0\Microsoft.AspNetCore.Server.IIS.targets'))" />
     <Error Condition="!Exists('..\packages\Microsoft.AspNetCore.Server.IISIntegration.2.2.1\build\netstandard2.0\Microsoft.AspNetCore.Server.IISIntegration.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.AspNetCore.Server.IISIntegration.2.2.1\build\netstandard2.0\Microsoft.AspNetCore.Server.IISIntegration.targets'))" />
+    <Error Condition="!Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit.3.12.0\build\NUnit.props'))" />
   </Target>
   <Import Project="..\packages\Microsoft.Extensions.Configuration.UserSecrets.2.2.0\build\netstandard2.0\Microsoft.Extensions.Configuration.UserSecrets.targets" Condition="Exists('..\packages\Microsoft.Extensions.Configuration.UserSecrets.2.2.0\build\netstandard2.0\Microsoft.Extensions.Configuration.UserSecrets.targets')" />
   <Import Project="..\packages\Microsoft.AspNetCore.Mvc.Razor.Extensions.2.2.0\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.targets" Condition="Exists('..\packages\Microsoft.AspNetCore.Mvc.Razor.Extensions.2.2.0\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.targets')" />
diff --git a/src/Project.Tests/ProjectControllerTests.cs b/src/Project.Tests/ProjectControllerTests.cs
index d7792930d0b013539f663ba38f92307e765851e7..968f1e69214f39a177317c21f4ead65bc0fe8e3c 100644
--- a/src/Project.Tests/ProjectControllerTests.cs
+++ b/src/Project.Tests/ProjectControllerTests.cs
@@ -25,8 +25,8 @@ namespace Coscine.Api.Project.Tests
         public void OwnsTest()
         {
             ProjectModel projectModel = new ProjectModel();
-            Assert.IsTrue(projectModel.OwnsProject(Users[0], Projects[0]));
-            Assert.IsFalse(projectModel.OwnsProject(Users[0], Projects[1]));
+            Assert.IsTrue(projectModel.HasAccess(Users[0], Projects[0], UserRoles.Owner));
+            Assert.IsFalse(projectModel.HasAccess(Users[0], Projects[1], UserRoles.Owner));
 
             var all = projectModel.GetAllWhere((project) =>
                 (from projectRole in project.ProjectRolesProjectIdIds
@@ -87,15 +87,8 @@ namespace Coscine.Api.Project.Tests
 
             FakeControllerContext(Users[0], stream);
 
-            try
-            {
-                Controller.Update(Projects[1].Id.ToString());
-                Assert.Fail();
-            }
-            catch (Exception e)
-            {
-                Assert.IsTrue(e.GetType() == typeof(NotAuthorizedException));
-            }
+            actionResult = Controller.Update(Projects[1].Id.ToString());
+            Assert.IsTrue(actionResult.GetType() == typeof(UnauthorizedObjectResult));
 
             // Cleanup
             stream.Close();
@@ -114,12 +107,12 @@ namespace Coscine.Api.Project.Tests
             FakeControllerContext(Users[0], stream);
 
             var actionResult = Controller.Store();
-            Assert.IsTrue(actionResult.GetType() == typeof(OkObjectResult));
+            Assert.IsTrue(actionResult.GetType() == typeof(JsonResult));
 
-            OkObjectResult okObjectResult = (OkObjectResult)actionResult;
-            Assert.IsTrue(okObjectResult.Value.GetType() == typeof(ProjectObject));
+            JsonResult jsonResult = (JsonResult)actionResult;
+            Assert.IsTrue(jsonResult.Value.GetType() == typeof(ProjectObject));
 
-            ProjectObject createdProjectObject = (ProjectObject)okObjectResult.Value;
+            ProjectObject createdProjectObject = (ProjectObject)jsonResult.Value;
 
             Assert.IsTrue(createdProjectObject.Description == newProjectObject.Description);
             Assert.IsTrue(createdProjectObject.DisplayName == newProjectObject.DisplayName);
@@ -149,12 +142,12 @@ namespace Coscine.Api.Project.Tests
             FakeControllerContext(Users[0], stream);
 
             var actionResult = Controller.Store();
-            Assert.IsTrue(actionResult.GetType() == typeof(OkObjectResult));
+            Assert.IsTrue(actionResult.GetType() == typeof(JsonResult));
 
-            OkObjectResult okObjectResult = (OkObjectResult)actionResult;
-            Assert.IsTrue(okObjectResult.Value.GetType() == typeof(ProjectObject));
+            JsonResult result = (JsonResult)actionResult;
+            Assert.IsTrue(result.Value.GetType() == typeof(ProjectObject));
 
-            ProjectObject createdProjectObject = (ProjectObject)okObjectResult.Value;
+            ProjectObject createdProjectObject = (ProjectObject)result.Value;
             stream.Close();
 
             stream = ObjectFactory<ProjectObject>.SerializeToStream(createdProjectObject);
@@ -162,10 +155,10 @@ namespace Coscine.Api.Project.Tests
             FakeControllerContext(Users[0], stream);
 
             actionResult = Controller.Delete(createdProjectObject.Id.ToString());
-            Assert.IsTrue(actionResult.GetType() == typeof(OkObjectResult));
+            Assert.IsTrue(actionResult.GetType() == typeof(JsonResult));
 
-            okObjectResult = (OkObjectResult)actionResult;
-            Assert.IsTrue(okObjectResult.Value.GetType() == typeof(ProjectObject));
+            result = (JsonResult)actionResult;
+            Assert.IsTrue(result.Value.GetType() == typeof(ProjectObject));
 
             stream.Close();
         }
@@ -184,8 +177,8 @@ namespace Coscine.Api.Project.Tests
 
             var actionResult = Controller.Store();
 
-            OkObjectResult okObjectResult = (OkObjectResult)actionResult;
-            ProjectObject createdProjectObject = (ProjectObject)okObjectResult.Value;
+            JsonResult result = (JsonResult)actionResult;
+            ProjectObject createdProjectObject = (ProjectObject)result.Value;
             stream.Close();
 
             newProjectObject = new ProjectObject(Guid.NewGuid(), "NewProject", "NewDisplayName", DateTime.Now, DateTime.Now.AddYears(1), "test2;test3", "abc", "investigator", "grandId",
@@ -205,10 +198,10 @@ namespace Coscine.Api.Project.Tests
             FakeControllerContext(Users[0], stream);
 
             actionResult = Controller.Delete(createdProjectObject.Id.ToString());
-            Assert.IsTrue(actionResult.GetType() == typeof(OkObjectResult));
+            Assert.IsTrue(actionResult.GetType() == typeof(JsonResult));
 
-            okObjectResult = (OkObjectResult)actionResult;
-            Assert.IsTrue(okObjectResult.Value.GetType() == typeof(ProjectObject));
+            result = (JsonResult)actionResult;
+            Assert.IsTrue(result.Value.GetType() == typeof(ProjectObject));
 
             stream.Close();
         }
@@ -225,8 +218,8 @@ namespace Coscine.Api.Project.Tests
             FakeControllerContext(Users[0], stream);
             var actionResult = Controller.Store();
 
-            OkObjectResult okObjectResult = (OkObjectResult)actionResult;
-            ProjectObject createdProjectObject = (ProjectObject)okObjectResult.Value;
+            JsonResult result = (JsonResult)actionResult;
+            ProjectObject createdProjectObject = (ProjectObject)result.Value;
 
             ProjectObject newSubProjectObject = new ProjectObject(Guid.NewGuid(), "NewSubProject", "NewDisplayNameSub", DateTime.Now, DateTime.Now.AddYears(1), "test2;test3", "abc", "investigator", "grandId",
                                                                         new List<DisciplineObject>() { new DisciplineObject(Discipline.Id, Discipline.Url, Discipline.DisplayNameDe, Discipline.DisplayNameEn) },
@@ -238,8 +231,8 @@ namespace Coscine.Api.Project.Tests
             FakeControllerContext(Users[0], subStream);
             var subActionResult = Controller.Store();
 
-            OkObjectResult okSubObjectResult = (OkObjectResult)subActionResult;
-            ProjectObject createdSubProjectObject = (ProjectObject)okSubObjectResult.Value;
+            JsonResult resultSubProject = (JsonResult)subActionResult;
+            ProjectObject createdSubProjectObject = (ProjectObject)resultSubProject.Value;
 
             SubProjectModel subProjectModel = new SubProjectModel();
             var subProjects = subProjectModel.GetAllWhere((x) => x.ProjectId == createdProjectObject.Id);
diff --git a/src/Project.Tests/Properties/AssemblyInfo.cs b/src/Project.Tests/Properties/AssemblyInfo.cs
index 2c75877eab65dc9ed5018b64206de7e1e896fd3c..d18f3e22cf5a0c585cfbd30de9718def9631aef6 100644
--- a/src/Project.Tests/Properties/AssemblyInfo.cs
+++ b/src/Project.Tests/Properties/AssemblyInfo.cs
@@ -9,8 +9,8 @@ using System.Reflection;
 [assembly: AssemblyDescription("Project.Tests is a part of the CoScInE group.")]
 [assembly: AssemblyCompany("IT Center, RWTH Aachen University")]
 [assembly: AssemblyProduct("Project.Tests")]
-[assembly: AssemblyVersion("1.9.0.0")]
-[assembly: AssemblyFileVersion("1.9.0.0")]
-[assembly: AssemblyInformationalVersion("1.9.0.0")]
+[assembly: AssemblyVersion("1.10.0.0")]
+[assembly: AssemblyFileVersion("1.10.0.0")]
+[assembly: AssemblyInformationalVersion("1.10.0.0")]
 [assembly: AssemblyCopyright("2019 IT Center, RWTH Aachen University")]
 
diff --git a/src/Project.Tests/ResourceControllerTests.cs b/src/Project.Tests/ResourceControllerTests.cs
index 70cff59f23f3593b8114a91b44ae63a128165425..b69ef09f4864b6b37d24d2076046b796ac052a0f 100644
--- a/src/Project.Tests/ResourceControllerTests.cs
+++ b/src/Project.Tests/ResourceControllerTests.cs
@@ -23,19 +23,19 @@ namespace Coscine.Api.Project.Tests
         public void TestControllerIndex()
         {
             var actionResult = Controller.Index();
-            Assert.IsTrue(actionResult.GetType() == typeof(OkObjectResult));
+            Assert.IsTrue(actionResult.GetType() == typeof(JsonResult));
         }
 
         [Test]
         public void TestControllerGet()
         {
             var actionResult = Controller.Get(Resources[0].Id.ToString());
-            Assert.IsTrue(actionResult.GetType() == typeof(OkObjectResult));
+            Assert.IsTrue(actionResult.GetType() == typeof(JsonResult));
 
-            OkObjectResult okObjectResult = (OkObjectResult)actionResult;
-            Assert.IsTrue(okObjectResult.Value.GetType() == typeof(ResourceObject));
+            JsonResult result = (JsonResult)actionResult;
+            Assert.IsTrue(result.Value.GetType() == typeof(ResourceObject));
 
-            ResourceObject resourceObject = (ResourceObject)okObjectResult.Value;
+            ResourceObject resourceObject = (ResourceObject)result.Value;
 
             Assert.IsTrue(resourceObject.Id == Resources[0].Id);
             Assert.IsTrue(resourceObject.DisplayName == Resources[0].DisplayName);
@@ -49,18 +49,18 @@ namespace Coscine.Api.Project.Tests
         public void TestControllerUpdate()
         {
             var actionResult = Controller.Get(Resources[0].Id.ToString());
-            OkObjectResult okObjectResult = (OkObjectResult)actionResult;
-            ResourceObject resourceObject = (ResourceObject)okObjectResult.Value;
+            JsonResult result = (JsonResult)actionResult;
+            ResourceObject resourceObject = (ResourceObject)result.Value;
 
             resourceObject.DisplayName = "OtherName";
-            resourceObject.ResourceTypeOption = JObject.FromObject(new RDSResourceTypeObject(Guid.NewGuid(), "PITLABTTEST", "accesskey", "secretkey"));
+            resourceObject.ResourceTypeOption = JObject.FromObject(new RDSResourceTypeObject(Guid.NewGuid(), "PITLABTTEST", 0));
 
             Stream stream = ObjectFactory<ResourceObject>.SerializeToStream(resourceObject);
 
             FakeControllerContext(Users[0], stream);
 
             actionResult = Controller.Update(Resources[0].Id.ToString());
-            Assert.IsTrue(actionResult.GetType() == typeof(OkObjectResult));
+            Assert.IsTrue(actionResult.GetType() == typeof(JsonResult));
 
             // Cleanup
             stream.Close();
@@ -69,15 +69,8 @@ namespace Coscine.Api.Project.Tests
 
             FakeControllerContext(Users[0], stream);
 
-            try
-            {
-                Controller.Update(Resources[1].Id.ToString());
-                Assert.Fail();
-            }
-            catch (Exception e)
-            {
-                Assert.IsTrue(e.GetType() == typeof(NotAuthorizedException));
-            }
+            actionResult = Controller.Update(Resources[1].Id.ToString());
+            Assert.IsTrue(actionResult.GetType() == typeof(UnauthorizedObjectResult));
 
             // Cleanup
             stream.Close();
@@ -97,7 +90,7 @@ namespace Coscine.Api.Project.Tests
                 new List<DisciplineObject>() { new DisciplineObject(Discipline.Id, Discipline.Url, Discipline.DisplayNameDe, Discipline.DisplayNameEn) },
                 new VisibilityObject(Visibility.Id, Visibility.DisplayName),
                 new LicenseObject(License.Id, License.DisplayName),
-                JObject.FromObject(new RDSResourceTypeObject(Guid.NewGuid(), "PITLABTTEST", "accesskey", "secretkey")),
+                JObject.FromObject(new RDSResourceTypeObject(Guid.NewGuid(), "PITLABTTEST", 0)),
                 "link",
                 JToken.Parse("{}")
             );
@@ -107,9 +100,9 @@ namespace Coscine.Api.Project.Tests
             FakeControllerContext(Users[0], stream);
 
             var actionResult = Controller.StoreToProject(Projects[0].Id.ToString());
-            Assert.IsTrue(actionResult.GetType() == typeof(OkObjectResult));
-            OkObjectResult okObjectResult = (OkObjectResult)actionResult;
-            resourceObject = (ResourceObject)okObjectResult.Value;
+            Assert.IsTrue(actionResult.GetType() == typeof(JsonResult));
+            JsonResult result = (JsonResult)actionResult;
+            resourceObject = (ResourceObject)result.Value;
 
             // Cleanup
             stream.Close();
@@ -119,7 +112,7 @@ namespace Coscine.Api.Project.Tests
             FakeControllerContext(Users[0], stream);
 
             actionResult = Controller.Delete(resourceObject.Id.ToString());
-            Assert.IsTrue(actionResult.GetType() == typeof(OkObjectResult));
+            Assert.IsTrue(actionResult.GetType() == typeof(JsonResult));
 
             stream.Close();
         }
diff --git a/src/Project.Tests/ResourceTypeControllerTests.cs b/src/Project.Tests/ResourceTypeControllerTests.cs
index c2262a54e713b39d76f93df8d4cdc9425841098c..69dc700e7011ee811d28843a2f24c0abf828b81b 100644
--- a/src/Project.Tests/ResourceTypeControllerTests.cs
+++ b/src/Project.Tests/ResourceTypeControllerTests.cs
@@ -20,15 +20,14 @@ namespace Coscine.Api.Project.Tests
         public void TestGettingFields()
         {
             var actionResult = Controller.Fields(Resources[0].Type.Id.ToString());
-            Assert.IsTrue(actionResult.GetType() == typeof(OkObjectResult));
+            Assert.IsTrue(actionResult.GetType() == typeof(JsonResult));
 
-            OkObjectResult okObjectResult = (OkObjectResult)actionResult;
-            List<string> fields = (List<string>) okObjectResult.Value;
-            if(fields.Count() == 3)
+            JsonResult result = (JsonResult)actionResult;
+            List<string> fields = (List<string>) result.Value;
+            if(fields.Count() == 2)
             {
                 Assert.IsTrue(fields[0] == "BucketName");
-                Assert.IsTrue(fields[1] == "AccessKey");
-                Assert.IsTrue(fields[2] == "SecretKey");
+                Assert.IsTrue(fields[1] == "Size");
             }
             else
             {
diff --git a/src/Project.Tests/app.config b/src/Project.Tests/app.config
index de19d6e9b480b5fc3344bb4b0fab49f7e8aedbf5..744cc9b448c09b528c56f11c52d178304802d23d 100644
--- a/src/Project.Tests/app.config
+++ b/src/Project.Tests/app.config
@@ -88,7 +88,7 @@
       </dependentAssembly>
       <dependentAssembly>
         <assemblyIdentity name="Coscine.Database" publicKeyToken="767d77427707b70a" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-1.10.0.0" newVersion="1.10.0.0" />
+        <bindingRedirect oldVersion="0.0.0.0-1.11.0.0" newVersion="1.11.0.0" />
       </dependentAssembly>
       <dependentAssembly>
         <assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" />
@@ -102,6 +102,46 @@
         <assemblyIdentity name="Coscine.SharePoint.Webparts.Vue" publicKeyToken="0fe8d3e516df6d98" culture="neutral" />
         <bindingRedirect oldVersion="0.0.0.0-1.4.0.0" newVersion="1.4.0.0" />
       </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.IdentityModel.Logging" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-5.6.0.0" newVersion="5.6.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Configuration.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Logging" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Primitives" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.AspNetCore.Http.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.AspNetCore.Hosting.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Hosting.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.AspNetCore.Http.Features" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.AspNetCore.Routing.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
     </assemblyBinding>
   </runtime>
   <entityFramework>
diff --git a/src/Project.Tests/packages.config b/src/Project.Tests/packages.config
index bcf66bb91bc173941c00ca44f75a45d1af2146ff..65dd56553e3920d980e704f6f6b67c8a7c8297e0 100644
--- a/src/Project.Tests/packages.config
+++ b/src/Project.Tests/packages.config
@@ -5,9 +5,10 @@
   <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.7.0" targetFramework="net472" />
-  <package id="Coscine.ApiCommons" version="1.2.2" targetFramework="net472" />
+  <package id="Coscine.ApiCommons" version="1.2.2.3" targetFramework="net472" />
   <package id="Coscine.Configuration" version="1.4.0" targetFramework="net472" />
-  <package id="Coscine.Database" version="1.10.0" targetFramework="net472" />
+  <package id="Coscine.Database" version="1.11.0" targetFramework="net472" />
+  <package id="Coscine.Logging" version="0.0.1" targetFramework="net472" />
   <package id="Coscine.ProxyApi" version="1.2.0" targetFramework="net472" />
   <package id="Coscine.SharePoint.Webparts.Vue" version="1.4.0" targetFramework="net472" />
   <package id="dotNetRDF" version="2.2.1" targetFramework="net472" />
@@ -21,8 +22,10 @@
   <package id="Metadata" version="1.0.0" targetFramework="net472" />
   <package id="Microsoft.AspNetCore" version="2.2.0" targetFramework="net472" />
   <package id="Microsoft.AspNetCore.Antiforgery" version="2.2.0" targetFramework="net472" />
+  <package id="Microsoft.AspNetCore.Authentication" version="2.2.0" targetFramework="net472" />
   <package id="Microsoft.AspNetCore.Authentication.Abstractions" version="2.2.0" targetFramework="net472" />
   <package id="Microsoft.AspNetCore.Authentication.Core" version="2.2.0" targetFramework="net472" />
+  <package id="Microsoft.AspNetCore.Authentication.JwtBearer" version="2.2.0" targetFramework="net472" />
   <package id="Microsoft.AspNetCore.Authorization" version="2.2.0" targetFramework="net472" />
   <package id="Microsoft.AspNetCore.Authorization.Policy" version="2.2.0" targetFramework="net472" />
   <package id="Microsoft.AspNetCore.Connections.Abstractions" version="2.2.0" targetFramework="net472" />
@@ -114,13 +117,20 @@
   <package id="Microsoft.IdentityModel" version="7.0.0" targetFramework="net472" />
   <package id="Microsoft.IdentityModel.JsonWebTokens" version="5.6.0" targetFramework="net472" />
   <package id="Microsoft.IdentityModel.Logging" version="5.6.0" targetFramework="net472" />
+  <package id="Microsoft.IdentityModel.Protocols" version="5.3.0" targetFramework="net472" />
+  <package id="Microsoft.IdentityModel.Protocols.OpenIdConnect" version="5.3.0" targetFramework="net472" />
   <package id="Microsoft.IdentityModel.Tokens" version="5.6.0" targetFramework="net472" />
   <package id="Microsoft.Net.Http.Headers" version="2.2.0" targetFramework="net472" />
   <package id="Microsoft.Win32.Registry" version="4.5.0" targetFramework="net472" />
   <package id="Moq" version="4.12.0" targetFramework="net472" />
   <package id="Newtonsoft.Json" version="12.0.2" targetFramework="net472" />
   <package id="Newtonsoft.Json.Bson" version="1.0.2" targetFramework="net472" />
-  <package id="NUnit" version="3.11.0" targetFramework="net472" />
+  <package id="NLog" version="4.6.8" targetFramework="net472" />
+  <package id="NLog.Config" version="4.6.8" targetFramework="net472" />
+  <package id="NLog.Extensions.Logging" version="1.6.1" targetFramework="net472" />
+  <package id="NLog.Schema" version="4.6.8" targetFramework="net472" />
+  <package id="NLog.Web.AspNetCore" version="4.9.0" targetFramework="net472" />
+  <package id="NUnit" version="3.12.0" targetFramework="net472" />
   <package id="NUnit3TestAdapter" version="3.13.0" targetFramework="net472" />
   <package id="OpenLink.Data.Virtuoso" version="7.20.3214.1" targetFramework="net472" />
   <package id="System.AppContext" version="4.3.0" targetFramework="net472" />
@@ -165,6 +175,7 @@
   <package id="System.Threading.Thread" version="4.3.0" targetFramework="net472" />
   <package id="System.ValueTuple" version="4.5.0" targetFramework="net472" />
   <package id="System.Xml.ReaderWriter" version="4.3.1" targetFramework="net472" />
+  <package id="System.Xml.XmlDocument" version="4.3.0" targetFramework="net472" />
   <package id="System.Xml.XPath" version="4.3.0" targetFramework="net472" />
   <package id="System.Xml.XPath.XDocument" version="4.3.0" targetFramework="net472" />
   <package id="VDS.Common" version="1.10.0" targetFramework="net472" />
diff --git a/src/Project/App.config b/src/Project/App.config
index 2d786cbe5e3e0b1b95ae59e59195ecdafa957653..1c65e6d64329c85eff07137297a551beeaf3d045 100644
--- a/src/Project/App.config
+++ b/src/Project/App.config
@@ -91,7 +91,7 @@
       </dependentAssembly>
       <dependentAssembly>
         <assemblyIdentity name="Coscine.Database" publicKeyToken="767d77427707b70a" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-1.10.0.0" newVersion="1.10.0.0" />
+        <bindingRedirect oldVersion="0.0.0.0-1.11.0.0" newVersion="1.11.0.0" />
       </dependentAssembly>
       <dependentAssembly>
         <assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" />
@@ -105,6 +105,46 @@
         <assemblyIdentity name="Coscine.SharePoint.Webparts.Vue" publicKeyToken="0fe8d3e516df6d98" culture="neutral" />
         <bindingRedirect oldVersion="0.0.0.0-1.3.0.0" newVersion="1.3.0.0" />
       </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.IdentityModel.Logging" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-5.6.0.0" newVersion="5.6.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Configuration.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Logging.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Logging" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Primitives" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.AspNetCore.Http.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.AspNetCore.Hosting.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.Extensions.Hosting.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.AspNetCore.Http.Features" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Microsoft.AspNetCore.Routing.Abstractions" publicKeyToken="adb9793829ddae60" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
+      </dependentAssembly>
     </assemblyBinding>
   </runtime>
   <entityFramework>
diff --git a/src/Project/Controllers/DataSourceController.cs b/src/Project/Controllers/DataSourceController.cs
index 3e3a1ed2882a27be2d0bb4044ada9b0e93d4501f..7dd77b6e63196e5deb7110936e68baa377139cfc 100644
--- a/src/Project/Controllers/DataSourceController.cs
+++ b/src/Project/Controllers/DataSourceController.cs
@@ -5,6 +5,7 @@ using Coscine.ApiCommons.Factories;
 using Coscine.ApiCommons.Utils;
 using Coscine.Configuration;
 using Coscine.Database.Model;
+using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
 using Newtonsoft.Json.Linq;
 using System;
@@ -22,6 +23,7 @@ using System.Web;
 
 namespace Coscine.Api.Project.Controllers
 {
+    [Authorize]
     public class DataSourceController : Controller
     {
         private readonly IConfiguration _configuration;
@@ -30,6 +32,7 @@ namespace Coscine.Api.Project.Controllers
         private static readonly HttpClient Client;
         private readonly Authenticator _authenticator;
         private readonly ResourceModel _resourceModel;
+        private readonly ProjectModel _projectModel;
 
         static DataSourceController()
         {
@@ -45,6 +48,7 @@ namespace Coscine.Api.Project.Controllers
             _jwtHandler = new JWTHandler(_configuration);
             _authenticator = new Authenticator(this, _configuration);
             _resourceModel = new ResourceModel();
+            _projectModel = new ProjectModel();
         }
 
         // inferring a ../ (urlencoded) can manipulate the url.
@@ -53,6 +57,8 @@ namespace Coscine.Api.Project.Controllers
         [HttpGet("[controller]/{resourceId}/{path}")]
         public async Task<IActionResult> GetWaterButlerFolder(string resourceId, string path)
         {
+            var user = _authenticator.GetUser();
+
             if (!string.IsNullOrWhiteSpace(path))
             {
                 path = HttpUtility.UrlDecode(path);
@@ -64,6 +70,11 @@ namespace Coscine.Api.Project.Controllers
                 return check;
             }
 
+            if (!_resourceModel.HasAccess(user, resource, UserRoles.Owner, UserRoles.Member))
+            {
+                return BadRequest("User does not have permission to the resource.");
+            }
+
             var authHeader = BuildAuthHeader(resource);
 
             if (authHeader == null)
@@ -73,7 +84,7 @@ namespace Coscine.Api.Project.Controllers
             else
             {
                 // If the path is null, an empty string is added.
-                string url = $"{_configuration.GetString("coscine/global/waterbutler_url")}{resource.Type.DisplayName.ToLower()}{path}";
+                string url = $"{_configuration.GetString("coscine/global/waterbutler_url")}{GetResourceTypeName(resource)}{path}";
 
                 var request = new HttpRequestMessage(HttpMethod.Get, url);
                 request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authHeader);
@@ -107,6 +118,9 @@ namespace Coscine.Api.Project.Controllers
         [DisableRequestSizeLimit]
         public async Task<IActionResult> PutUploadFile(string resourceId, string path)
         {
+            var user = _authenticator.GetUser();
+
+
             if (!string.IsNullOrWhiteSpace(path))
             {
                 path = HttpUtility.UrlDecode(path);
@@ -118,6 +132,11 @@ namespace Coscine.Api.Project.Controllers
                 return check;
             }
 
+            if(!_resourceModel.HasAccess(user, resource, UserRoles.Owner, UserRoles.Member))
+            {
+                return BadRequest("User does not have permission to the resource.");
+            }
+
             var authHeader = BuildAuthHeader(resource, new string[] { "gitlab" });
 
             if (authHeader == null)
@@ -127,7 +146,7 @@ namespace Coscine.Api.Project.Controllers
             else
             {
                 // If the path is null, an empty string is added.
-                string url = $"{_configuration.GetString("coscine/global/waterbutler_url")}{resource.Type.DisplayName.ToLower()}/?kind=file&name={path}";
+                string url = $"{_configuration.GetString("coscine/global/waterbutler_url")}{GetResourceTypeName(resource)}/?kind=file&name={path}";
 
                 try
                 {
@@ -156,6 +175,8 @@ namespace Coscine.Api.Project.Controllers
         [DisableRequestSizeLimit]
         public async Task<IActionResult> PutUpdateFile(string resourceId, string path)
         {
+            var user = _authenticator.GetUser();
+
             if (!string.IsNullOrWhiteSpace(path))
             {
                 path = HttpUtility.UrlDecode(path);
@@ -167,6 +188,11 @@ namespace Coscine.Api.Project.Controllers
                 return check;
             }
 
+            if (!_resourceModel.HasAccess(user, resource, UserRoles.Owner, UserRoles.Member))
+            {
+                return BadRequest("User does not have permission to the resource.");
+            }
+
             var authHeader = BuildAuthHeader(resource, new string[] { "gitlab" });
 
             if (authHeader == null)
@@ -176,7 +202,7 @@ namespace Coscine.Api.Project.Controllers
             else
             {
                 // If the path is null, an empty string is added.
-                string url = $"{_configuration.GetString("coscine/global/waterbutler_url")}{resource.Type.DisplayName.ToLower()}/{path}?kind=file";
+                string url = $"{_configuration.GetString("coscine/global/waterbutler_url")}{GetResourceTypeName(resource)}/{path}?kind=file";
 
                 try
                 {
@@ -198,6 +224,29 @@ namespace Coscine.Api.Project.Controllers
             }
         }
 
+        private string GetResourceTypeName(Resource resource)
+        {
+            if (resource.Type.DisplayName.ToLower().Equals("s3")) {
+                return "rds";
+            }
+            else
+            {
+                return resource.Type.DisplayName.ToLower();
+            }
+        }
+
+        private string GetResourceTypeName(JToken resource)
+        {
+            if (resource["type"]["displayName"].ToString().ToLower().Equals("s3"))
+            {
+                return "rds";
+            }
+            else
+            {
+                return resource["type"]["displayName"].ToString().ToLower();
+            }
+        }
+
 
         public async Task<HttpResponseMessage> UploadFile(string url, string authHeader, Stream stream)
         {
@@ -210,6 +259,8 @@ namespace Coscine.Api.Project.Controllers
         [HttpDelete("[controller]/{resourceId}/{path}")]
         public async Task<IActionResult> Delete(string resourceId, string path)
         {
+            var user = _authenticator.GetUser();
+
             if (!string.IsNullOrWhiteSpace(path))
             {
                 path = HttpUtility.UrlDecode(path);
@@ -221,6 +272,11 @@ namespace Coscine.Api.Project.Controllers
                 return check;
             }
 
+            if (!_resourceModel.HasAccess(user, resource, UserRoles.Owner, UserRoles.Member))
+            {
+                return BadRequest("User does not have permission to the resource.");
+            }
+
             var authHeader = BuildAuthHeader(resource, new string[] { "gitlab" });
 
             if (authHeader == null)
@@ -230,7 +286,7 @@ namespace Coscine.Api.Project.Controllers
             else
             {
                 // If the path is null, an empty string is added.
-                string url = $"{_configuration.GetString("coscine/global/waterbutler_url")}{resource.Type.DisplayName.ToLower()}{path}";
+                string url = $"{_configuration.GetString("coscine/global/waterbutler_url")}{GetResourceTypeName(resource)}{path}";
 
                 var request = new HttpRequestMessage(HttpMethod.Delete, url);
                 request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authHeader);
@@ -263,22 +319,23 @@ namespace Coscine.Api.Project.Controllers
 
             JToken resource = ObjectFactory<JToken>.DeserializeFromStream(Request.Body);
 
-
             string authHeader = null;
-            if (resource["type"]["displayName"].ToString().ToLower() == "rds")
+            if (resource["type"]["displayName"].ToString().ToLower() == "s3")
             {
-                RDSResourceType rdsResourceType = new RDSResourceType();
-                rdsResourceType.BucketName = resource["resourceTypeOption"]["BucketName"].ToString();
-                rdsResourceType.AccessKey = resource["resourceTypeOption"]["AccessKey"].ToString();
-                rdsResourceType.SecretKey = resource["resourceTypeOption"]["SecretKey"].ToString();
-                authHeader = BuildRdsAuthHeader(rdsResourceType);
+                S3ResourceType s3ResourceType = new S3ResourceType();
+                s3ResourceType.BucketName = resource["resourceTypeOption"]["BucketName"].ToString();
+                s3ResourceType.AccessKey = resource["resourceTypeOption"]["AccessKey"].ToString();
+                s3ResourceType.SecretKey = resource["resourceTypeOption"]["SecretKey"].ToString();
+                authHeader = BuildS3AuthHeader(s3ResourceType);
             }
             else if (resource["type"]["displayName"].ToString().ToLower() == "gitlab")
             {
-                GitlabResourceType gitlabResourceType = new GitlabResourceType();
-                gitlabResourceType.RepositoryNumber = (int)resource["resourceTypeOption"]["RepositoryNumber"];
-                gitlabResourceType.RepositoryUrl = resource["resourceTypeOption"]["RepositoryUrl"].ToString();
-                gitlabResourceType.Token = resource["resourceTypeOption"]["Token"].ToString();
+                GitlabResourceType gitlabResourceType = new GitlabResourceType
+                {
+                    RepositoryNumber = (int)resource["resourceTypeOption"]["RepositoryNumber"],
+                    RepositoryUrl = resource["resourceTypeOption"]["RepositoryUrl"].ToString(),
+                    Token = resource["resourceTypeOption"]["Token"].ToString()
+                };
                 authHeader = BuildGitlabAuthHeader(gitlabResourceType);
             }
 
@@ -289,7 +346,7 @@ namespace Coscine.Api.Project.Controllers
             else
             {
                 // If the path is null, an empty string is added.
-                string url = $"{_configuration.GetString("coscine/global/waterbutler_url")}{resource["type"]["displayName"].ToString().ToLower()}{path}";
+                string url = $"{_configuration.GetString("coscine/global/waterbutler_url")}{GetResourceTypeName(resource)}{path}";
 
                 var request = new HttpRequestMessage(HttpMethod.Get, url);
                 request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authHeader);
@@ -351,7 +408,7 @@ namespace Coscine.Api.Project.Controllers
             {
                 return BadRequest($"{resourceId} is not a guid.");
             }
-            
+
             try
             {
                 resource = _resourceModel.GetById(resourceGuid);
@@ -359,11 +416,6 @@ namespace Coscine.Api.Project.Controllers
                 {
                     return NotFound($"Could not find resource with id: {resourceId}");
                 }
-                var user = _authenticator.GetUserFromToken();
-                if (!_resourceModel.OwnsResource(user, resource))
-                {
-                    return Forbid($"The user does not own the resource {resourceId}");
-                }
             }
             catch (Exception)
             {
@@ -413,6 +465,13 @@ namespace Coscine.Api.Project.Controllers
 
                 authHeader = BuildRdsAuthHeader(rdsResourceType);
             }
+            else if (resource.Type.DisplayName.ToLower() == "s3")
+            {
+                S3ResourceTypeModel s3ResourceTypeModel = new S3ResourceTypeModel();
+                var s3ResourceType = s3ResourceTypeModel.GetById(resource.ResourceTypeOptionId.Value);
+
+                authHeader = BuildS3AuthHeader(s3ResourceType);
+            }
             else if (resource.Type.DisplayName.ToLower() == "gitlab")
             {
                 GitlabResourceTypeModel gitlabResourceTypeModel = new GitlabResourceTypeModel();
@@ -430,8 +489,8 @@ namespace Coscine.Api.Project.Controllers
 
             var credentials = new Dictionary<string, object>
             {
-                { "access_key", rdsResourceType.AccessKey },
-                { "secret_key", rdsResourceType.SecretKey }
+                { "access_key", _configuration.GetStringAndWait("coscine/global/buckets/accessKey") },
+                { "secret_key", _configuration.GetStringAndWait("coscine/global/buckets/secretKey") }
             };
 
             var settings = new Dictionary<string, object>
@@ -442,6 +501,24 @@ namespace Coscine.Api.Project.Controllers
             return BuildWaterbutlerPayload(auth, credentials, settings);
         }
 
+        private string BuildS3AuthHeader(S3ResourceType s3ResourceType)
+        {
+            var auth = new Dictionary<string, object>();
+
+            var credentials = new Dictionary<string, object>
+            {
+                { "access_key", s3ResourceType.AccessKey },
+                { "secret_key", s3ResourceType.SecretKey }
+            };
+
+            var settings = new Dictionary<string, object>
+            {
+                { "bucket", s3ResourceType.BucketName }
+            };
+
+            return BuildWaterbutlerPayload(auth, credentials, settings);
+        }
+
         private string BuildGitlabAuthHeader(GitlabResourceType gitlabResourceType)
         {
 
diff --git a/src/Project/Controllers/DisciplineController.cs b/src/Project/Controllers/DisciplineController.cs
index 62c1ea0c994bbfb054171c03ae4986067e8a4198..34ae92d571cd01013de3d444e6e42b1eed827348 100644
--- a/src/Project/Controllers/DisciplineController.cs
+++ b/src/Project/Controllers/DisciplineController.cs
@@ -1,33 +1,27 @@
 using Coscine.Api.Project.Models;
 using Coscine.Api.Project.ReturnObjects;
-using Coscine.ApiCommons;
+using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
-using System;
-using System.Collections.Generic;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace Coscine.Api.Project.Controllers
 {
+    [Authorize]
     public class DisciplineController : Controller
     {
-        private readonly Authenticator _authenticator;
         private readonly DisciplineModel _disciplineModel;
 
         public DisciplineController()
         {
-            _authenticator = new Authenticator(this, Program.Configuration);
             _disciplineModel = new DisciplineModel();
         }
 
         [Route("[controller]")]
         public IActionResult Index()
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
-            {
-                return _disciplineModel.GetAll().OrderBy(discipline => discipline.DisplayNameDe.Substring(discipline.DisplayNameDe.Length - 3)).Select((discipline) => new DisciplineObject(discipline.Id, discipline.Url, discipline.DisplayNameDe, discipline.DisplayNameEn));
-            }));
+            return Json(_disciplineModel.GetAll()
+                .OrderBy(discipline => discipline.DisplayNameDe.Substring(discipline.DisplayNameDe.Length - 3))
+                .Select((discipline) => new DisciplineObject(discipline.Id, discipline.Url, discipline.DisplayNameDe, discipline.DisplayNameEn)));
         }
     }
 }
diff --git a/src/Project/Controllers/InstituteController.cs b/src/Project/Controllers/InstituteController.cs
index 7ef066fd65bdf510de0fcc8cea173fc60dbe48d2..2fff9d6f9256c56de08db5b49bb6b9999cfcd077 100644
--- a/src/Project/Controllers/InstituteController.cs
+++ b/src/Project/Controllers/InstituteController.cs
@@ -1,33 +1,26 @@
 using Coscine.Api.Project.Models;
 using Coscine.Api.Project.ReturnObjects;
-using Coscine.ApiCommons;
+using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
-using System;
-using System.Collections.Generic;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace Coscine.Api.Project.Controllers
 {
+    [Authorize]
     public class InstituteController : Controller
     {
-        private readonly Authenticator _authenticator;
         private readonly InstituteModel _instituteModel;
 
         public InstituteController()
         {
-            _authenticator = new Authenticator(this, Program.Configuration);
             _instituteModel = new InstituteModel();
         }
 
         [Route("[controller]")]
         public IActionResult Index()
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
-            {
-                return _instituteModel.GetAll().Select((institute) => new InstituteObject(institute.Id, institute.IKZ, institute.DisplayName));
-            }));
+            return Json(_instituteModel.GetAll()
+                .Select((institute) => new InstituteObject(institute.Id, institute.IKZ, institute.DisplayName)));
         }
     }
 }
diff --git a/src/Project/Controllers/LicenseController.cs b/src/Project/Controllers/LicenseController.cs
index 88568555a35a52b99644f414926b96c1588db74f..c4210d9876bfaba22baf91813ba49b5dad38c24a 100644
--- a/src/Project/Controllers/LicenseController.cs
+++ b/src/Project/Controllers/LicenseController.cs
@@ -1,33 +1,26 @@
 using Coscine.Api.Project.Models;
 using Coscine.Api.Project.ReturnObjects;
-using Coscine.ApiCommons;
+using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
-using System;
-using System.Collections.Generic;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace Coscine.Api.Project.Controllers
 {
+    [Authorize]
     public class LicenseController : Controller
     {
-        private readonly Authenticator _authenticator;
         private readonly LicenseModel _licenseModel;
 
         public LicenseController()
         {
-            _authenticator = new Authenticator(this, Program.Configuration);
             _licenseModel = new LicenseModel();
         }
 
         [Route("[controller]")]
         public IActionResult Index()
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
-            {
-                return _licenseModel.GetAll().Select((license) => new LicenseObject(license.Id, license.DisplayName));
-            }));
+                return Json(_licenseModel.GetAll()
+                    .Select((license) => new LicenseObject(license.Id, license.DisplayName)));
         }
     }
 }
diff --git a/src/Project/Controllers/MetadataController.cs b/src/Project/Controllers/MetadataController.cs
index 018a1da0965662a4b1a94f8041d943f926d5c3b8..9812aaddccccb1de3fed3fddca062a682d3b5b7d 100644
--- a/src/Project/Controllers/MetadataController.cs
+++ b/src/Project/Controllers/MetadataController.cs
@@ -11,15 +11,18 @@ using VDS.RDF.Parsing;
 using VDS.RDF;
 using Metadata;
 using System.Web;
-using System.IO;
+using Microsoft.AspNetCore.Authorization;
 
 namespace Coscine.Api.Project.Controllers
 {
+
+    [Authorize]
     public class MetadataController : Controller
     {
         private readonly Authenticator _authenticator;
         private readonly MetadataModel _metadataModel;
         private readonly ResourceModel _resourceModel;
+        private readonly ProjectModel _projectModel;
         private readonly Util _util;
 
         public MetadataController()
@@ -27,31 +30,29 @@ namespace Coscine.Api.Project.Controllers
             _authenticator = new Authenticator(this, Program.Configuration);
             _metadataModel = new MetadataModel();
             _resourceModel = new ResourceModel();
+            _projectModel = new ProjectModel();
             _util = new Util();
         }
 
         [Route("[controller]")]
         public IActionResult Index()
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
-            {
-                return NoContent();
-            }));
+            return NoContent();
         }
 
         // returns the basic application profile
         [HttpGet("[controller]/resource/{projectId}/ap/{applicationProfileId}")]
         public IActionResult GetApplicationProfile(Guid projectId, string applicationProfileId)
         {
-            var user = _authenticator.GetUserFromToken();
+            var user = _authenticator.GetUser();
 
-            if (_metadataModel.IsProjectMember(user, projectId))
+            if (_projectModel.HasAccess(user, _projectModel.GetById(projectId), UserRoles.Owner, UserRoles.Member))
             {
                 var graph = _util.GetGraph(HttpUtility.UrlDecode(applicationProfileId));                
 
                 var json = JToken.Parse(VDS.RDF.Writing.StringWriter.Write(graph, new RdfJsonWriter()));
                 
-                return Ok(json);
+                return Json(json);
             }
             else
             {
@@ -64,10 +65,10 @@ namespace Coscine.Api.Project.Controllers
         [HttpGet("[controller]/resource/{resourceId}/apc/{applicationProfileId}")]
         public IActionResult GetApplicationProfileComplete(string resourceId, string applicationProfileId)
         {
-            var user = _authenticator.GetUserFromToken();
+            var user = _authenticator.GetUser();
 
             var resource = _resourceModel.GetById(Guid.Parse(resourceId));
-            if (_metadataModel.IsProjectMember(user, resource) && applicationProfileId != null)
+            if (_resourceModel.HasAccess(user, resource, UserRoles.Owner, UserRoles.Member) && applicationProfileId != null)
             {
                 var graph = _util.GetGraph(HttpUtility.UrlDecode(applicationProfileId));
                 var fixedValuesGraph = new Graph();
@@ -90,150 +91,143 @@ namespace Coscine.Api.Project.Controllers
         [HttpGet("[controller]/project/{projectId}/aplist/")]
         public IActionResult ListAllApplicationProfiles(Guid projectId)
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
+            var user = _authenticator.GetUser();
+            if (_projectModel.HasAccess(user, _projectModel.GetById(projectId), UserRoles.Owner, UserRoles.Member))
             {
-                if (_metadataModel.IsProjectMember(user, projectId))
-                {
-                    var graphUris = _util.ListGraphs();
+                var graphUris = _util.ListGraphs();
 
-                    return new JArray(graphUris.Select(x => x.ToString()).Where(x => x.StartsWith("https://purl.org/coscine/ap/")));
-                }
-                else
-                {
-                    throw new NotAuthorizedException("User is no project member!");
-                }
-            }));
+                return Json(new JArray(graphUris.Select(x => x.ToString()).Where(x => x.StartsWith("https://purl.org/coscine/ap/"))));
+            }
+            else
+            {
+                throw new NotAuthorizedException("User is no project member!");
+            }
         }
 
         [HttpGet("[controller]/resource/{resourceId}/filename/{filename}/ver/{version}")]
         public IActionResult GetMetadataForFile(string resourceId, string filename, string version)
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
+            var user = _authenticator.GetUser();
+            var resource = _resourceModel.GetById(Guid.Parse(resourceId));
+            if (_resourceModel.HasAccess(user, resource, UserRoles.Owner, UserRoles.Member))
             {
-                var resource = _resourceModel.GetById(Guid.Parse(resourceId));
-                if (_metadataModel.IsProjectMember(user, resource))
-                {
-                    var id = _metadataModel.GenerateId(resourceId, filename, version);
-                    var graph = _util.GetGraph(id);
-                    return JToken.Parse(VDS.RDF.Writing.StringWriter.Write(graph, new RdfJsonWriter()));
-                }
-                else
-                {
-                    throw new NotAuthorizedException("User is no project member!");
-                }
-            }));
+                var id = _metadataModel.GenerateId(resourceId, filename, version);
+                var graph = _util.GetGraph(id);
+                return Json(JToken.Parse(VDS.RDF.Writing.StringWriter.Write(graph, new RdfJsonWriter())).ToString());
+            }
+            else
+            {
+                throw new NotAuthorizedException("User is no project member!");
+            }
         }
 
         [HttpPut("[controller]/resource/{resourceId}/filename/{filename}/ver/{version}")]
         public IActionResult StoreMetadataForFile(string resourceId, string filename, string version)
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
+            var innerBlock = ObjectFactory<JToken>.DeserializeFromStream(Request.Body);
+            var graphName = _metadataModel.GenerateId(resourceId, filename, version);
+            var graphNameUri = new Uri(graphName);
+            var json = new JObject
             {
-                var innerBlock = ObjectFactory<JToken>.DeserializeFromStream(Request.Body);
-                var graphName = _metadataModel.GenerateId(resourceId, filename, version);
-                var graphNameUri = new Uri(graphName);
-                var json = new JObject
-                {
-                    [graphName] = innerBlock
-                };
+                [graphName] = innerBlock
+            };
 
-                var resource = _resourceModel.GetById(Guid.Parse(resourceId));
-                if (_metadataModel.IsProjectMember(user, resource))
-                {
-                    var graph = new Graph();
-                    graph.LoadFromString(json.ToString(), new RdfJsonParser());
+            var user = _authenticator.GetUser();
+            var resource = _resourceModel.GetById(Guid.Parse(resourceId));
 
-                    var fixedValuesGraph = new Graph();
-                    fixedValuesGraph.LoadFromString(resource.FixedValues, new RdfJsonParser());
+            if (_resourceModel.HasAccess(user, resource, UserRoles.Owner, UserRoles.Member))
+            {
+                var graph = new Graph();
+                graph.LoadFromString(json.ToString(), new RdfJsonParser());
+
+                var fixedValuesGraph = new Graph();
+                fixedValuesGraph.LoadFromString(resource.FixedValues, new RdfJsonParser());
 
-                    foreach(var triple in fixedValuesGraph.Triples.Where(x => x.Predicate.ToString() == "https://purl.org/coscine/fixedValue"))
+                foreach(var triple in fixedValuesGraph.Triples.Where(x => x.Predicate.ToString() == "https://purl.org/coscine/fixedValue"))
+                {
+                    // Remove any existing triples
+                    foreach (var triple2 in graph.GetTriplesWithSubjectPredicate(graph.CreateUriNode(graphNameUri), triple.Subject).ToList())
                     {
-                        // Remove any existing triples
-                        foreach (var triple2 in graph.GetTriplesWithSubjectPredicate(graph.CreateUriNode(graphNameUri), triple.Subject).ToList())
-                        {
-                            graph.Retract(triple2);
-                        }
-                        graph.Assert(graph.CreateUriNode(graphNameUri), triple.Subject, triple.Object);
+                        graph.Retract(triple2);
                     }
+                    graph.Assert(graph.CreateUriNode(graphNameUri), triple.Subject, triple.Object);
+                }
 
-                    // Default values is not checked or added
+                // Default values is not checked or added
 
-                    // validate the data
-                    if (_util.ValidateShacl(graph, graphNameUri))
+                // validate the data
+                if (_util.ValidateShacl(graph, graphNameUri))
+                {
+                    // store the data
+                    if (_util.HasGraph(graphNameUri))
                     {
-                        // store the data
-                        if (_util.HasGraph(graphNameUri))
-                        {
-                            _util.ClearGraph(graphNameUri);
-                        }
-                        else
-                        {
-                            _util.CreateNamedGraph(graphNameUri);
-                        }
-
-                        // BaseUri must be set for the sparql query
-                        graph.BaseUri = graphNameUri;
-                        _util.AddGraph(graph);
-
-                        return NoContent();
+                        _util.ClearGraph(graphNameUri);
                     }
                     else
                     {
-                        throw new NotAuthorizedException("Data has the wrong format!");
+                        _util.CreateNamedGraph(graphNameUri);
                     }
 
+                    // BaseUri must be set for the sparql query
+                    graph.BaseUri = graphNameUri;
+                    _util.AddGraph(graph);
+
+                    return NoContent();
                 }
                 else
                 {
-                    throw new NotAuthorizedException("User is no project member!");
+                    throw new NotAuthorizedException("Data has the wrong format!");
                 }
-            }));
+
+            }
+            else
+            {
+                throw new NotAuthorizedException("User is no project member!");
+            }
         }
 
         [HttpGet("[controller]/vocabulary/{projectId}/{path}")]
         public IActionResult GetVocabulary(Guid projectId, string path)
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
+            var user = _authenticator.GetUser();
+            if (_projectModel.HasAccess(user, _projectModel.GetById(projectId), UserRoles.Owner, UserRoles.Member))
             {
-                if (_metadataModel.IsProjectMember(user, projectId))
-                {
-                    var graph = _util.GetGraph(HttpUtility.UrlDecode(path));
+                var graph = _util.GetGraph(HttpUtility.UrlDecode(path));
 
-                    JArray de = new JArray();
-                    foreach (var kv in _util.GetVocabularyLabels(graph, "de"))
-                    {
-                        JObject obj = new JObject
-                        {
-                            ["value"] = kv.Key,
-                            ["name"] = kv.Value
-                        };
-                        de.Add(obj);
-                    }
-
-                    JArray en = new JArray();
-                    foreach(var kv in _util.GetVocabularyLabels(graph, "en"))
+                var de = new JArray();
+                foreach (var kv in _util.GetVocabularyLabels(graph, "de"))
+                {
+                    JObject obj = new JObject
                     {
-                        JObject obj = new JObject
-                        {
-                            ["value"] = kv.Key,
-                            ["name"] = kv.Value
-                        };
-                        en.Add(obj);
-                    }
+                        ["value"] = kv.Key,
+                        ["name"] = kv.Value
+                    };
+                    de.Add(obj);
+                }
 
-                    JObject json = new JObject
+                var en = new JArray();
+                foreach(var kv in _util.GetVocabularyLabels(graph, "en"))
+                {
+                    JObject obj = new JObject
                     {
-                        ["de"] = de,
-                        ["en"] = en
+                        ["value"] = kv.Key,
+                        ["name"] = kv.Value
                     };
-
-                    return json;
+                    en.Add(obj);
                 }
-                else
+
+                JObject json = new JObject
                 {
-                    throw new NotAuthorizedException("User is no project member!");
-                }
-            }));
+                    ["de"] = de,
+                    ["en"] = en
+                };
+
+                return Json(json);
+            }
+            else
+            {
+                throw new NotAuthorizedException("User is no project member!");
+            }
         }
 
     }
diff --git a/src/Project/Controllers/ProjectController.cs b/src/Project/Controllers/ProjectController.cs
index d2a952bf18680ef7e256762b7e8f66abf5fc136a..898f51d338605ccecb8c2ba228aa4cb5d9796f14 100644
--- a/src/Project/Controllers/ProjectController.cs
+++ b/src/Project/Controllers/ProjectController.cs
@@ -1,20 +1,19 @@
 using Coscine.Action;
 using Coscine.Action.EventArgs;
-using Coscine.Action.Implementations.Project;
 using Coscine.Api.Project.Models;
 using Coscine.Api.Project.ReturnObjects;
 using Coscine.ApiCommons;
-using Coscine.ApiCommons.Exceptions;
 using Coscine.ApiCommons.Factories;
-using Coscine.Database.Model;
 using Microsoft.AspNetCore.Mvc;
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using Coscine.Configuration;
+using Microsoft.AspNetCore.Authorization;
+using System.Collections.Generic;
 
 namespace Coscine.Api.Project.Controllers
 {
+    [Authorize]
     public class ProjectController : Controller
     {
         private readonly Authenticator _authenticator;
@@ -27,105 +26,94 @@ namespace Coscine.Api.Project.Controllers
             _authenticator = new Authenticator(this, Program.Configuration);
             _configuration = Program.Configuration;
             _projectModel = new ProjectModel();
-            _emitter = new Emitter(this._configuration);
+            _emitter = new Emitter(_configuration);
         }
 
         [Route("[controller]")]
         public IActionResult Index()
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
-            {
-                return _projectModel.GetAllWhere((project) =>                
-                    (from projectRole in project.ProjectRolesProjectIdIds
-                            where projectRole.User == user
-                            && projectRole.Role.DisplayName == "Owner"
-                            select projectRole).Any()
-                ).Select((project) => _projectModel.CreateReturnObjectFromDatabaseObject(project));
-            }));
+            var user = _authenticator.GetUser();
+
+            return Ok(_projectModel.GetWithAccess(user, UserRoles.Member, UserRoles.Owner).ToList()
+                .Select((project) => _projectModel.CreateReturnObjectFromDatabaseObject(project)));
+
         }
 
         [HttpGet("[controller]/{id}")]
         public IActionResult Get(string id)
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
-            {
-                var project = _projectModel.GetById(Guid.Parse(id));
-                if (_projectModel.CanSeeProject(user, project))
-                {
-                    return _projectModel.CreateReturnObjectFromDatabaseObject(project);
-                }
-                else
-                {
-                    throw new UnauthorizedAccessException("User is not allowed to see given project Id!");
-                }
-            }));
+            var user = _authenticator.GetUser();
+            var project = _projectModel.GetById(Guid.Parse(id));
+            if (_projectModel.HasAccess(user, project, UserRoles.Member, UserRoles.Owner))
+            {
+                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)
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
-            {
-                var project = _projectModel.GetById(Guid.Parse(id));
-                ResourceModel resourceModel = new ResourceModel();
-                ResourceTypeModel resourceTypeModel = new ResourceTypeModel();
-                if (_projectModel.CanSeeProject(user, project))
-                {
-                    return resourceModel.GetAllWhere((resource) =>
-                            (from projectResource in resource.ProjectResourceResourceIdIds
-                            where projectResource.ProjectId == project.Id
-                            select projectResource).Any())
-                            .Select((resource) =>
-                            {
-                                return resourceModel.CreateReturnObjectFromDatabaseObject(resource);
-                            });
-                }
-                else
-                {
-                    throw new UnauthorizedAccessException("User cannot see resources of given project!");
-                }
-            }));
+            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))
+            {
+                return Json(resourceModel.GetAllWhere((resource) =>
+                        (from projectResource in resource.ProjectResourceResourceIdIds
+                         where projectResource.ProjectId == project.Id
+                         select projectResource).Any())
+                        .Select((resource) =>
+                        {
+                            return resourceModel.CreateReturnObjectFromDatabaseObject(resource);
+                        }));
+            }
+            else
+            {
+                return Unauthorized($"User is not allowed to see given the project {id}");
+            }
         }
 
         [HttpPost("[controller]/{id}")]
         public IActionResult Update(string id)
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
-            {
-                ProjectObject projectObject = ObjectFactory<ProjectObject>.DeserializeFromStream(Request.Body);
-                var project = _projectModel.GetById(Guid.Parse(id));
-                if(_projectModel.OwnsProject(user, project))
-                {
-                    return _projectModel.UpdateByObject(project, projectObject);
-                }
-                else
-                {
-                    throw new NotAuthorizedException("The user is not authorized to perform an update on the selected project!");
-                }
-            }));
+            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))
+            {
+                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)
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
-            {
-                var project = _projectModel.GetById(Guid.Parse(id));
-                if (_projectModel.OwnsProject(user, project))
-                {
-                    DeleteProject(project);
-                    return _projectModel.CreateReturnObjectFromDatabaseObject(project);
-                }
-                else
-                {
-                    throw new NotAuthorizedException("The user is not authorized to perform an update on the selected project!");
-                }
-            }));
+            var user = _authenticator.GetUser();
+            var project = _projectModel.GetById(Guid.Parse(id));
+            if (_projectModel.HasAccess(user, project, UserRoles.Owner))
+            {
+                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(Coscine.Database.Model.Project project)
+        public void DeleteProject(Database.Model.Project project)
         {
-            SubProjectModel subProjectModel = new SubProjectModel();
+            var subProjectModel = new SubProjectModel();
             foreach(var subProject in subProjectModel.GetAllWhere((subProject) => subProject.ProjectId == project.Id))
             {
                 subProjectModel.Delete(subProject);
@@ -137,7 +125,7 @@ namespace Coscine.Api.Project.Controllers
                 subProjectModel.Delete(subProject);
             }
 
-            ProjectResourceModel projectResourceModel = new ProjectResourceModel();
+            var projectResourceModel = new ProjectResourceModel();
             ResourceModel resourceModel = new ResourceModel();
             foreach (var projectResource in projectResourceModel.GetAllWhere((projectResource) => projectResource.ProjectId == project.Id))
             {
@@ -145,19 +133,19 @@ namespace Coscine.Api.Project.Controllers
                 resourceModel.Delete(resourceModel.GetById(projectResource.ResourceId));
             }
 
-            ProjectRoleModel projectRoleModel = new ProjectRoleModel();
+            var projectRoleModel = new ProjectRoleModel();
             foreach (var projectRole in projectRoleModel.GetAllWhere((projectRole) => projectRole.ProjectId == project.Id))
             {
                 projectRoleModel.Delete(projectRole);
             }
 
-            ProjectDisciplineModel projectDisciplineModel = new ProjectDisciplineModel();
+            var projectDisciplineModel = new ProjectDisciplineModel();
             foreach (var projectDiscipline in projectDisciplineModel.GetAllWhere((projectDiscipline) => projectDiscipline.ProjectId == project.Id))
             {
                 projectDisciplineModel.Delete(projectDiscipline);
             }
 
-            ProjectInstituteModel projectInstituteModel = new ProjectInstituteModel();
+            var projectInstituteModel = new ProjectInstituteModel();
             foreach (var projectInstitute in projectInstituteModel.GetAllWhere((projectInstitute) => projectInstitute.ProjectId == project.Id))
             {
                 projectInstituteModel.Delete(projectInstitute);
@@ -174,27 +162,34 @@ namespace Coscine.Api.Project.Controllers
         [HttpPost("[controller]")]
         public IActionResult Store()
         {
-            return base.Ok(_authenticator.ValidateAndExecute((user) =>
-            {
-                ProjectObject projectObject = ObjectFactory<ProjectObject>.DeserializeFromStream(Request.Body);
-                var project = _projectModel.StoreFromObject(projectObject, user);
-
-                if (projectObject.ParentId != null 
-                    && projectObject.ParentId != new Guid()
-                    && _projectModel.IsMemberOrHigher(user, _projectModel.GetById(projectObject.ParentId))) // for now, only an owner can add subprojects to projects
-                {
-                    SubProjectModel subProjectModel = new SubProjectModel();
-                    subProjectModel.LinkSubProject(projectObject.ParentId, project.Id);
-                }
-
-                _emitter.EmitProjectCreate(new ProjectEventArgs(_configuration)
-                {
-                    Project = project,
-                    ProjectOwner = user
-                });
-
-                return _projectModel.CreateReturnObjectFromDatabaseObject(project);
-            }));
+            var user = _authenticator.GetUser();
+            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);
+
+            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
+            });
+
+            return Json(_projectModel.CreateReturnObjectFromDatabaseObject(project));
         }
     }
 }
diff --git a/src/Project/Controllers/ProjectRoleController.cs b/src/Project/Controllers/ProjectRoleController.cs
index f7638fdeeb9ba3ac0c90e482c0ac0e2d25c17d3d..4dca837349c9e050fa3be359c769b75d98f7883a 100644
--- a/src/Project/Controllers/ProjectRoleController.cs
+++ b/src/Project/Controllers/ProjectRoleController.cs
@@ -1,27 +1,24 @@
 using Coscine.Action;
 using Coscine.Action.EventArgs;
-using Coscine.Action.Implementations.User;
 using Coscine.Api.Project.Models;
 using Coscine.Api.Project.ReturnObjects;
 using Coscine.ApiCommons;
-using Coscine.ApiCommons.Exceptions;
 using Coscine.ApiCommons.Factories;
-using Coscine.Database.Model;
+using Coscine.Configuration;
+using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
 using System;
-using System.Collections.Generic;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace Coscine.Api.Project.Controllers
 {
+    [Authorize]
     public class ProjectRoleController : Controller
     {
         private readonly Authenticator _authenticator;
         private readonly ProjectRoleModel _projectRoleModel;
         private readonly Emitter _emitter;
-        private readonly Coscine.Configuration.IConfiguration _configuration;
+        private readonly IConfiguration _configuration;
 
         public ProjectRoleController()
         {
@@ -34,120 +31,115 @@ namespace Coscine.Api.Project.Controllers
         [Route("[controller]/{projectId}")]
         public IActionResult Index(string projectId)
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
+            var userModel = new UserModel();
+            var roleModel = new RoleModel();
+            var projectModel = new ProjectModel();
+            Guid.TryParse(projectId, out Guid projectIdGuid);
+            var user = _authenticator.GetUser();
+
+            if (projectModel.HasAccess(user, projectModel.GetById(projectIdGuid), UserRoles.Owner, UserRoles.Member))
             {
-                UserModel userModel = new UserModel();
-                RoleModel roleModel = new RoleModel();
-                ProjectModel projectModel = new ProjectModel();
-                Guid.TryParse(projectId, out Guid projectIdGuid);
-                if (projectModel.OwnsProject(user, projectModel.GetById(projectIdGuid)))
+                return Json(_projectRoleModel.GetAllWhere((projectRole) =>
+                    (projectRole.ProjectId == projectIdGuid)
+                ).Select((projectRole) =>
                 {
-                    return _projectRoleModel.GetAllWhere((projectRole) =>
-                        (projectRole.ProjectId == projectIdGuid)
-                    ).Select((projectRole) =>
+                    var userInst = projectRole.User;
+                    if (userInst == null)
                     {
-                        User userInst = projectRole.User;
-                        if (userInst == null)
-                        {
-                            userInst = userModel.GetById(projectRole.UserId);
-                        }
-                        Role role = projectRole.Role;
-                        if (role == null)
-                        {
-                            role = roleModel.GetById(projectRole.RoleId);
-                        }
-                        return new ProjectRoleObject(projectRole.ProjectId, new UserObject(userInst.Id, userInst.DisplayName, userInst.Givenname, userInst.Surname, userInst.EmailAddress), new RoleObject(role.Id, role.DisplayName));
-                    });
-                }
-                else
-                {
-                    throw new UnauthorizedAccessException("User is not allowed to list all users to the given project!");
-                }
-            }));
+                        userInst = userModel.GetById(projectRole.UserId);
+                    }
+                    var role = projectRole.Role;
+                    if (role == null)
+                    {
+                        role = roleModel.GetById(projectRole.RoleId);
+                    }
+                    return new ProjectRoleObject(projectRole.ProjectId, new UserObject(userInst.Id, userInst.DisplayName, userInst.Givenname, userInst.Surname, userInst.EmailAddress), new RoleObject(role.Id, role.DisplayName));
+                }));
+            }
+            else
+            {
+                return Unauthorized("User is not allowed to list all users to the given project!");
+            }
         }
 
         //Get all roles for current user and given project
         [HttpGet("[controller]/project/{projectId}")]
         public IActionResult Get(string projectId)
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
-            {
-                RoleModel roleModel = new RoleModel();
-                Guid.TryParse(projectId, out Guid projectIdGuid);
-                UserObject userObject = new UserObject(user.Id, user.DisplayName, user.Givenname, user.Surname, user.EmailAddress);
+            var roleModel = new RoleModel();
+            Guid.TryParse(projectId, out Guid projectIdGuid);
+            var user = _authenticator.GetUser();
+            var userObject = new UserObject(user.Id, user.DisplayName, user.Givenname, user.Surname, user.EmailAddress);
 
-                return _projectRoleModel.GetAllWhere((projectRole) =>
-                    (projectRole.UserId == user.Id &&
-                    projectRole.ProjectId == projectIdGuid)
-                ).Select((projectRole) => {
-                    if(projectRole.Role == null)
-                    {
-                        projectRole.Role = roleModel.GetById(projectRole.RoleId);
-                    }
-                    return new ProjectRoleObject(projectRole.RelationId, userObject, new RoleObject(projectRole.Role.Id, projectRole.Role.DisplayName));
-                });
+            return Json(_projectRoleModel.GetAllWhere((projectRole) =>
+                (projectRole.UserId == user.Id &&
+                projectRole.ProjectId == projectIdGuid)
+            ).Select((projectRole) => {
+                if(projectRole.Role == null)
+                {
+                    projectRole.Role = roleModel.GetById(projectRole.RoleId);
+                }
+                return new ProjectRoleObject(projectRole.RelationId, userObject, new RoleObject(projectRole.Role.Id, projectRole.Role.DisplayName));
             }));
         }
 
         [HttpPost("[controller]")]
         public IActionResult Set()
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
+            var projectRoleObject = ObjectFactory<ProjectRoleObject>.DeserializeFromStream(Request.Body);
+            var projectModel = new ProjectModel();
+            var project = projectModel.GetById(projectRoleObject.ProjectId);
+            var roleModel = new RoleModel();
+            var role = roleModel.GetById(projectRoleObject.Role.Id);
+            var userModel = new UserModel();
+            var userToAdd = userModel.GetById(projectRoleObject.User.Id);
+            var user = _authenticator.GetUser();
+
+            if (projectModel.HasAccess(user, project, UserRoles.Owner))
             {
-                ProjectRoleObject projectRoleObject = ObjectFactory<ProjectRoleObject>.DeserializeFromStream(Request.Body);
-                ProjectModel projectModel = new ProjectModel();
-                var project = projectModel.GetById(projectRoleObject.ProjectId);
-                RoleModel roleModel = new RoleModel();
-                var role = roleModel.GetById(projectRoleObject.Role.Id);
-                UserModel userModel = new UserModel();
-                var userToAdd = userModel.GetById(projectRoleObject.User.Id);
-                if (projectModel.OwnsProject(user, project))
+                _emitter.EmitUserAdd(new UserEventArgs(_configuration)
                 {
-                    _emitter.EmitUserAdd(new UserEventArgs(this._configuration)
-                    {
-                        Project = project,
-                        Role = role,
-                        User = userToAdd
-                    });
-                    return _projectRoleModel.SetFromObject(projectRoleObject);
-                }
-                else
-                {
-                    throw new NotAuthorizedException("The user is not authorized to store a project role to the given project!");
-                }
-            }));
+                    Project = project,
+                    Role = role,
+                    User = userToAdd
+                });
+                return Json(_projectRoleModel.SetFromObject(projectRoleObject));
+            }
+            else
+            {
+                return Unauthorized("The user is not authorized to store a project role to the given project!");
+            }
         }
 
         [HttpDelete("[controller]/project/{projectId}/user/{userId}/role/{roleId}")]
         public IActionResult Delete(Guid projectId, Guid userId, Guid roleId)
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
-            {
-                ProjectModel projectModel = new ProjectModel();
-                if (projectModel.OwnsProject(user, projectModel.GetById(projectId)))
-                {
-                    _projectRoleModel.CheckIfLastOwnerWillBeRemoved(roleId, projectId);
+            var projectModel = new ProjectModel();
+            var user = _authenticator.GetUser();
 
-                    var project = projectModel.GetById(projectId);
-                    UserModel userModel = new UserModel();
-                    var userToRemove = userModel.GetById(userId);
+            if (projectModel.HasAccess(user, projectModel.GetById(projectId), UserRoles.Owner))
+            {
+                _projectRoleModel.CheckIfLastOwnerWillBeRemoved(roleId, projectId);
 
-                    _emitter.EmitUserRemove(new UserEventArgs(this._configuration)
-                    {
-                        Project = project,
-                        User = userToRemove
-                    });
+                var project = projectModel.GetById(projectId);
+                var userModel = new UserModel();
+                var userToRemove = userModel.GetById(userId);
 
-                    return _projectRoleModel.Delete(_projectRoleModel.GetWhere((projectRole) =>
-                            projectRole.ProjectId == projectId
-                            && projectRole.UserId == userId
-                            && projectRole.RoleId == roleId));
-                }
-                else
+                _emitter.EmitUserRemove(new UserEventArgs(this._configuration)
                 {
-                    throw new NotAuthorizedException("The user is not authorized to delete a project role for the given project!");
-                }
-            }));
+                    Project = project,
+                    User = userToRemove
+                });
+
+                return Json(_projectRoleModel.Delete(_projectRoleModel.GetWhere((projectRole) =>
+                        projectRole.ProjectId == projectId
+                        && projectRole.UserId == userId
+                        && projectRole.RoleId == roleId)));
+            }
+            else
+            {
+                return Unauthorized("The user is not authorized to delete a project role for the given project!");
+            }
         }
     }
 }
diff --git a/src/Project/Controllers/ResourceController.cs b/src/Project/Controllers/ResourceController.cs
index 4368b1ed91e2d59494f646c686d061c3b53342e1..b972eb635aec9e91521a9666eebdc1cbf3f9db85 100644
--- a/src/Project/Controllers/ResourceController.cs
+++ b/src/Project/Controllers/ResourceController.cs
@@ -1,18 +1,18 @@
 using Coscine.Api.Project.Models;
 using Coscine.Api.Project.ReturnObjects;
 using Coscine.ApiCommons;
-using Coscine.ApiCommons.Exceptions;
 using Coscine.ApiCommons.Factories;
 using Microsoft.AspNetCore.Mvc;
 using System;
 using System.Linq;
-using Newtonsoft.Json.Linq;
 using Coscine.Action;
 using Coscine.Configuration;
 using Coscine.Action.EventArgs;
+using Microsoft.AspNetCore.Authorization;
 
 namespace Coscine.Api.Project.Controllers
 {
+    [Authorize]
     public class ResourceController : Controller
     {
         private readonly Authenticator _authenticator;
@@ -31,106 +31,96 @@ namespace Coscine.Api.Project.Controllers
         [Route("[controller]")]
         public IActionResult Index()
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
-            {
-                return _resourceModel.GetAllWhere((resource) =>                
-                    (from projectResource in resource.ProjectResourceResourceIdIds
-                            where (from projectRole in projectResource.Project.ProjectRolesProjectIdIds
-                                   where projectRole.User == user
-                                   && projectRole.Role.DisplayName == "Owner"
-                                   select projectRole).Any()
-                            select projectResource).Any()
-                ).Select((resource) => _resourceModel.CreateReturnObjectFromDatabaseObject(resource));
-            }));
+            var user = _authenticator.GetUser();
+            return Json(_resourceModel.GetAllWhere((resource) =>                
+                (from projectResource in resource.ProjectResourceResourceIdIds
+                        where (from projectRole in projectResource.Project.ProjectRolesProjectIdIds
+                                where projectRole.User == user
+                                && (projectRole.Role.DisplayName == "Owner" || projectRole.Role.DisplayName == "Member")
+                                select projectRole).Any()
+                        select projectResource).Any()
+            ).Select((resource) => _resourceModel.CreateReturnObjectFromDatabaseObject(resource)));
         }
 
 
         [HttpGet("[controller]/{id}")]
         public IActionResult Get(string id)
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
+            var resource = _resourceModel.GetById(Guid.Parse(id));
+            var user = _authenticator.GetUser();
+            if (_resourceModel.HasAccess(user, resource, UserRoles.Owner, UserRoles.Member))
             {
-                var resource = _resourceModel.GetById(Guid.Parse(id));
-                if (_resourceModel.OwnsResource(user, resource))
-                {
-                    _resourceModel.SetType(resource);
-                    return _resourceModel.CreateReturnObjectFromDatabaseObject(resource);
-                }
-                else
-                {
-                    throw new NotAuthorizedException("User does not own resource!");
-                }
-            }));
+                _resourceModel.SetType(resource);
+                return Json(_resourceModel.CreateReturnObjectFromDatabaseObject(resource));
+            }
+            else
+            {
+                return Unauthorized("User does not own resource!");
+            }
         }
 
         [HttpPost("[controller]/{id}")]
         public IActionResult Update(string id)
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
+            var resourceObject = ObjectFactory<ResourceObject>.DeserializeFromStream(Request.Body);
+            var resource = _resourceModel.GetById(Guid.Parse(id));
+            var user = _authenticator.GetUser();
+
+            if (_resourceModel.HasAccess(user, resource, UserRoles.Owner))
             {
-                ResourceObject resourceObject = ObjectFactory<ResourceObject>.DeserializeFromStream(Request.Body);
-                var resource = _resourceModel.GetById(Guid.Parse(id));
-                if (_resourceModel.OwnsResource(user, resource))
-                {
-                    return _resourceModel.UpdateByObject(resource, resourceObject);
-                }
-                else
-                {
-                    throw new NotAuthorizedException("The user is not authorized to perform an update on the selected resource!");
-                }
-            }));
+                return Json(_resourceModel.UpdateByObject(resource, resourceObject));
+            }
+            else
+            {
+                return Unauthorized("The user is not authorized to perform an update on the selected resource!");
+            }
         }
 
         [HttpDelete("[controller]/{id}")]
         public IActionResult Delete(string id)
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
+            var resource = _resourceModel.GetById(Guid.Parse(id));
+            var user = _authenticator.GetUser();
+            if (_resourceModel.HasAccess(user, resource, UserRoles.Owner))
             {
-                var resource = _resourceModel.GetById(Guid.Parse(id));
-                if (_resourceModel.OwnsResource(user, resource))
+                var returnObject = _resourceModel.CreateReturnObjectFromDatabaseObject(resource);
+                _emitter.EmitResourceDelete(new ResourceEventArgs(_configuration)
                 {
-                    var returnObject = _resourceModel.CreateReturnObjectFromDatabaseObject(resource);
-                    _emitter.EmitResourceDelete(new ResourceEventArgs(_configuration)
-                    {
-                        Resource = resource
-                    });
-                    _resourceModel.DeleteResource(resource);
-                    return returnObject;
-                }
-                else
-                {
-                    throw new NotAuthorizedException("The user is not authorized to perform an update on the selected resource!");
-                }
-            }));
+                    Resource = resource
+                });
+                _resourceModel.DeleteResource(resource);
+                return Json(returnObject);
+            }
+            else
+            {
+                return Unauthorized("The user is not authorized to perform an update on the selected resource!");
+            }
         }
 
         [HttpPost("[controller]/project/{projectId}")]
         public IActionResult StoreToProject(string projectId)
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
+            var resourceObject = ObjectFactory<ResourceObject>.DeserializeFromStream(Request.Body);
+            var projectModel = new ProjectModel();
+            var project = projectModel.GetById(Guid.Parse(projectId));
+            var user = _authenticator.GetUser();
+
+            if (projectModel.HasAccess(user, project, UserRoles.Owner, UserRoles.Member))
             {
-                ResourceObject resourceObject = ObjectFactory<ResourceObject>.DeserializeFromStream(Request.Body);
+                var resource = _resourceModel.StoreFromObject(resourceObject);
+                projectModel.AddResource(project, resource);
 
-                ProjectModel projectModel = new ProjectModel();
-                var project = projectModel.GetById(Guid.Parse(projectId));
-                if (projectModel.OwnsProject(user, project))
+                _emitter.EmitResourceCreate(new ResourceEventArgs(_configuration)
                 {
-                    var resource = _resourceModel.StoreFromObject(resourceObject);
-
-                    projectModel.AddResource(project, resource);
+                    Resource = resource
+                });
 
-                    _emitter.EmitResourceCreate(new ResourceEventArgs(_configuration)
-                    {
-                        Resource = resource
-                    });
-
-                    return _resourceModel.CreateReturnObjectFromDatabaseObject(resource);
-                }
-                else
-                {
-                    throw new NotAuthorizedException("The user is not authorized to add a new resource to the selected project!");
-                }                
-            }));
+                return Json(_resourceModel.CreateReturnObjectFromDatabaseObject(resource));
+            }
+            else
+            {
+                return Unauthorized("The user is not authorized to add a new resource to the selected project!");
+            }
         }
     }
 }
diff --git a/src/Project/Controllers/ResourceTypeController.cs b/src/Project/Controllers/ResourceTypeController.cs
index fd5179b7c8900ad4edf844b4b4bece01486e91c1..04e097a20774308c9c39ddc4c8f61c5edb10a2fb 100644
--- a/src/Project/Controllers/ResourceTypeController.cs
+++ b/src/Project/Controllers/ResourceTypeController.cs
@@ -1,15 +1,14 @@
 using Coscine.Api.Project.Models;
 using Coscine.Api.Project.ReturnObjects;
 using Coscine.ApiCommons;
+using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
 using System;
-using System.Collections.Generic;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace Coscine.Api.Project.Controllers
 {
+    [Authorize]
     public class ResourceTypeController : Controller
     {
         private readonly Authenticator _authenticator;
@@ -25,39 +24,40 @@ namespace Coscine.Api.Project.Controllers
         [Route("[controller]")]
         public IActionResult Index()
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
-            {
-                return _resourceTypeModel.GetAll().Select((resourceType) => new ResourceTypeObject(resourceType.Id, resourceType.DisplayName));
-            }));
+                return Json(_resourceTypeModel.GetAll()
+                    .Select((resourceType) => new ResourceTypeObject(resourceType.Id, resourceType.DisplayName)));
         }
 
         [Route("[controller]/{id}/fields")]
         public IActionResult Fields(string id)
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
-            {
-                var resourceType = _resourceTypeModel.GetById(Guid.Parse(id));
+            var resourceType = _resourceTypeModel.GetById(Guid.Parse(id));
 
-                if(resourceType.DisplayName == "rds")
+                if (resourceType.DisplayName == "s3")
                 {
-                    return Type.GetType("Coscine.Api.Project.ReturnObjects.RDSResourceTypeObject").GetProperties()
+                    return Json(Type.GetType("Coscine.Api.Project.ReturnObjects.S3ResourceTypeObject").GetProperties()
                             .Where((property) => property.Name != "Id")
                             .Select((property) => property.Name)
-                            .ToList();
+                            .ToList());
+                }
+                else if (resourceType.DisplayName == "rds")
+                {
+                    return Json(Type.GetType("Coscine.Api.Project.ReturnObjects.RDSResourceTypeObject").GetProperties()
+                            .Where((property) => property.Name != "Id")
+                            .Select((property) => property.Name)
+                            .ToList());
                 }
                 else if(resourceType.DisplayName == "gitlab")
                 {
-                    return Type.GetType("Coscine.Api.Project.ReturnObjects.GitlabResourceTypeObject").GetProperties()
+                    return Json(Type.GetType("Coscine.Api.Project.ReturnObjects.GitlabResourceTypeObject").GetProperties()
                             .Where((property) => property.Name != "Id")
                             .Select((property) => property.Name)
-                            .ToList();
+                            .ToList());
                 }
                 else
                 {
                     throw new ArgumentException("Invalid Resource Type!");
                 }
-            }));
         }
-
-    }   
+    }
 }
diff --git a/src/Project/Controllers/RoleController.cs b/src/Project/Controllers/RoleController.cs
index 7ef12a81c1144b60f9188ad02d14100907611005..d2596276883d053ca450895743a8847766cf9cd6 100644
--- a/src/Project/Controllers/RoleController.cs
+++ b/src/Project/Controllers/RoleController.cs
@@ -1,33 +1,26 @@
 using Coscine.Api.Project.Models;
 using Coscine.Api.Project.ReturnObjects;
-using Coscine.ApiCommons;
+using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
-using System;
-using System.Collections.Generic;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace Coscine.Api.Project.Controllers
 {
+    [Authorize]
     public class RoleController : Controller
     {
-        private readonly Authenticator _authenticator;
         private readonly RoleModel _roleModel;
 
         public RoleController()
         {
-            _authenticator = new Authenticator(this, Program.Configuration);
             _roleModel = new RoleModel();
         }
 
         [Route("[controller]")]
         public IActionResult Index()
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
-            {
-                return _roleModel.GetAll().Select((role) => new RoleObject(role.Id, role.DisplayName));
-            }));
+            return Json(_roleModel.GetAll()
+                .Select((role) => new RoleObject(role.Id, role.DisplayName)));
         }
     }
 }
diff --git a/src/Project/Controllers/SubProjectController.cs b/src/Project/Controllers/SubProjectController.cs
index 74db39e5298c4766a70fb996e2ff0567a4c50717..da95361f1cd2ac6a99d17d8e498c8eadc92784c5 100644
--- a/src/Project/Controllers/SubProjectController.cs
+++ b/src/Project/Controllers/SubProjectController.cs
@@ -1,12 +1,13 @@
 using Coscine.Api.Project.Models;
-using Coscine.Api.Project.ReturnObjects;
 using Coscine.ApiCommons;
+using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
 using System;
 using System.Linq;
 
 namespace Coscine.Api.Project.Controllers
 {
+    [Authorize]
     public class SubProjectController : Controller
     {
         private readonly Authenticator _authenticator;
@@ -21,22 +22,20 @@ namespace Coscine.Api.Project.Controllers
         [HttpGet("[controller]/{parentId}")]
         public IActionResult Get(string parentId)
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
+            var parentGuid = new Guid(parentId);
+            var projectModel = new ProjectModel();
+            var user = _authenticator.GetUser();
+            if (projectModel.HasAccess(user, projectModel.GetById(parentGuid), UserRoles.Owner, UserRoles.Member))
             {
-                Guid parentGuid = new Guid(parentId);
-                ProjectModel projectModel = new ProjectModel();
-                if (projectModel.CanSeeProject(user, projectModel.GetById(parentGuid)))
-                {
-                    var subProjects = _subProjectModel.GetAllWhere((subProjectM) => (subProjectM.ProjectId == parentGuid))
-                                                     .Select((subProject) => projectModel.GetById(subProject.SubProjectId))
-                                                     .Select((project) => projectModel.CreateReturnObjectFromDatabaseObject(project, parentGuid));
-                    return subProjects;
-                }
-                else
-                {
-                    throw new UnauthorizedAccessException("User is not allowed to create a subproject for the given project id!");
-                }
-            }));
+                var subProjects = _subProjectModel.GetAllWhere((subProjectM) => (subProjectM.ProjectId == parentGuid))
+                                                    .Select((subProject) => projectModel.GetById(subProject.SubProjectId))
+                                                    .Select((project) => projectModel.CreateReturnObjectFromDatabaseObject(project, parentGuid));
+                return Json(subProjects);
+            }
+            else
+            {
+                return Unauthorized("User is not allowed to create a subproject for the given project id!");
+            }
         }
     }
 }
diff --git a/src/Project/Controllers/VisibilityController.cs b/src/Project/Controllers/VisibilityController.cs
index c14fe74d68f83496a80edab63e0fb6fdd6a3277d..bdf9bc3bcd55c9a906a0c9575ab58e651b451bb5 100644
--- a/src/Project/Controllers/VisibilityController.cs
+++ b/src/Project/Controllers/VisibilityController.cs
@@ -1,33 +1,26 @@
 using Coscine.Api.Project.Models;
 using Coscine.Api.Project.ReturnObjects;
-using Coscine.ApiCommons;
+using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Mvc;
-using System;
-using System.Collections.Generic;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace Coscine.Api.Project.Controllers
 {
+    [Authorize]
     public class VisibilityController : Controller
     {
-        private readonly Authenticator _authenticator;
         private readonly VisibilityModel _visibilityModel;
 
         public VisibilityController()
         {
-            _authenticator = new Authenticator(this, Program.Configuration);
             _visibilityModel = new VisibilityModel();
         }
 
         [Route("[controller]")]
         public IActionResult Index()
         {
-            return Ok(_authenticator.ValidateAndExecute((user) =>
-            {
-                return _visibilityModel.GetAll().Select((visibility) => new VisibilityObject(visibility.Id, visibility.DisplayName));
-            }));
+            return Json(_visibilityModel.GetAll()
+                .Select((visibility) => new VisibilityObject(visibility.Id, visibility.DisplayName)));
         }
     }
 }
diff --git a/src/Project/Models/MetadataModel.cs b/src/Project/Models/MetadataModel.cs
index 5b7697a52dae3dc77ef7b73f9bc4569d7351a1ae..5ce7769ae026c19d7af1930a9032d6516fa0cebb 100644
--- a/src/Project/Models/MetadataModel.cs
+++ b/src/Project/Models/MetadataModel.cs
@@ -52,30 +52,5 @@ namespace Coscine.Api.Project.Models
         {
             return $"https://purl.org/coscine/md/{resourceId}/{filename}/{version}/";
         }
-
-        public bool IsProjectMember(User user, Resource resource)
-        {
-            return DatabaseConnection.ConnectToDatabase((db) =>
-            {
-                return (from relation in db.ProjectRoles
-                        where relation.UserId == user.Id
-                            && (relation.Role.DisplayName == "Owner" || relation.Role.DisplayName == "Member")
-                            && (relation.Project.ProjectResourceProjectIdIds != null && relation.Project.ProjectResourceProjectIdIds.
-                                Any((projectResource) => projectResource.Resource == resource))
-                        select relation).Any();
-            });
-        }
-
-        public bool IsProjectMember(User user, Guid projectId)
-        {
-            return DatabaseConnection.ConnectToDatabase((db) =>
-            {
-                return (from relation in db.ProjectRoles
-                        where relation.UserId == user.Id
-                            && (relation.Role.DisplayName == "Owner" || relation.Role.DisplayName == "Member")
-                            && (relation.ProjectId == projectId)
-                        select relation).Any();
-            });
-        }
     }
 }
diff --git a/src/Project/Models/ProjectModel.cs b/src/Project/Models/ProjectModel.cs
index 97b533d40b1fb2f5f8f30922d00e65f0c11cc969..418837381c5cd371d143d52ffad100059aacee3c 100644
--- a/src/Project/Models/ProjectModel.cs
+++ b/src/Project/Models/ProjectModel.cs
@@ -102,28 +102,42 @@ namespace Coscine.Api.Project.Models
             return projectRole;
         }
 
-        public bool CanSeeProject(User user, Coscine.Database.Model.Project project)
+        public bool HasAccess(User user, Database.Model.Project project, params string[] allowedAccess)
         {
-            return IsMemberOrHigher(user, project);
+            ProjectRoleModel projectRoleModel = new ProjectRoleModel();
+            allowedAccess = allowedAccess.Select(x => x.ToLower().Trim()).ToArray();
+
+            IEnumerable<Coscine.Database.Model.ProjectRole> projectRoles = projectRoleModel.GetAllWhere(
+                (projectRoleRelation) => projectRoleRelation.ProjectId == project.Id && 
+                                         projectRoleRelation.UserId == user.Id &&
+                                         allowedAccess.Contains(projectRoleRelation.Role.DisplayName.ToLower()));
+            return projectRoles.Count() > 0;
         }
 
-        public bool IsMemberOrHigher(User user, Coscine.Database.Model.Project project)
+        private IEnumerable<Database.Model.Project> QueryAllProjectsWithAccess(User user, params string[] allowedAccess)
         {
-            return DatabaseConnection.ConnectToDatabase((db) => (from relation in db.ProjectRoles
-                                                                 where relation.Project == project
-                                                                     && relation.User == user
-                                                                     && (relation.Role.DisplayName == "Owner"
-                                                                         || relation.Role.DisplayName == "Member")
-                                                                 select relation).Any());
+            ProjectRoleModel projectRoleModel = new ProjectRoleModel();
+            ProjectModel projectModel = new ProjectModel();
+
+            allowedAccess = allowedAccess.Select(x => x.ToLower().Trim()).ToArray();
+            var allUserProjectRoles = projectRoleModel.GetAllWhere((projectRoleRelation) => projectRoleRelation.UserId == user.Id && 
+                                                                                            allowedAccess.Contains(projectRoleRelation.Role.DisplayName.ToLower()));
+            var allowedProjectIds = allUserProjectRoles.Select((projectRole) => projectRole.ProjectId);
+            var allowedProjects = projectModel.GetAllWhere((project) => allowedProjectIds.Contains(project.Id));
+            return allowedProjects.ToList();
         }
 
-        public bool OwnsProject(User user, Coscine.Database.Model.Project project)
+        public IEnumerable<Database.Model.Project> GetWithAccess(User user, params string[] allowedAccess)
         {
-            return DatabaseConnection.ConnectToDatabase((db) => (from relation in db.ProjectRoles
-                         where relation.Project == project
-                             && relation.User == user
-                             && relation.Role.DisplayName == "Owner"
-                             select relation).Any());
+            ProjectRoleModel projectRoleModel = new ProjectRoleModel();
+            ProjectModel projectModel = new ProjectModel();
+
+            allowedAccess = allowedAccess.Select(x => x.ToLower().Trim()).ToArray();
+            var allUserProjectRoles = projectRoleModel.GetAllWhere((projectRoleRelation) => projectRoleRelation.UserId == user.Id &&
+                                                                                            allowedAccess.Contains(projectRoleRelation.Role.DisplayName.ToLower()));
+            var allowedProjectIds = allUserProjectRoles.Select((projectRole) => projectRole.ProjectId);
+            var allowedProjects = projectModel.GetAllWhere((project) => allowedProjectIds.Contains(project.Id));
+            return allowedProjects.ToList();
         }
 
         public void AddResource(Coscine.Database.Model.Project project, Resource resource)
@@ -165,7 +179,12 @@ namespace Coscine.Api.Project.Models
             return Update(project);
         }
 
-        public ProjectObject CreateReturnObjectFromDatabaseObject(Database.Model.Project project, Guid parentId = new Guid())
+        public ProjectObject CreateReturnObjectFromDatabaseObject(Database.Model.Project project)
+        {
+            return CreateReturnObjectFromDatabaseObject(project, new Guid());
+        }
+
+        public ProjectObject CreateReturnObjectFromDatabaseObject(Database.Model.Project project, Guid parentId)
         {
             IEnumerable<DisciplineObject> disciplines = new List<DisciplineObject>();
             if(project.ProjectDisciplineProjectIdIds == null)
diff --git a/src/Project/Models/ResourceModel.cs b/src/Project/Models/ResourceModel.cs
index ab80817ce44bd7d922eb57c55843061d50f49c07..d5259de066595a8be680566cd8358134ff902de7 100644
--- a/src/Project/Models/ResourceModel.cs
+++ b/src/Project/Models/ResourceModel.cs
@@ -1,5 +1,6 @@
 using Coscine.Api.Project.ReturnObjects;
 using Coscine.ApiCommons.Models;
+using Coscine.Configuration;
 using Coscine.Database.Model;
 using LinqToDB;
 using Newtonsoft.Json.Linq;
@@ -12,8 +13,11 @@ namespace Coscine.Api.Project.Models
 {
     public class ResourceModel : DatabaseModel<Resource>
     {
+        private readonly IConfiguration _configuration;
+
         public ResourceModel() : base(Program.Configuration)
         {
+            _configuration = Program.Configuration;
         }
 
         public Resource StoreFromObject(ResourceObject resourceObject)
@@ -84,26 +88,47 @@ namespace Coscine.Api.Project.Models
                 if (resource.ResourceTypeOptionId != null)
                 {
                     RDSResourceType rdsResourceType = rdsResourceTypeModel.GetById(resource.ResourceTypeOptionId.Value);
-
-                    rdsResourceType.BucketName = rdsResourceTypeObject.BucketName;
-                    rdsResourceType.AccessKey = rdsResourceTypeObject.AccessKey ?? rdsResourceType.AccessKey;
-                    rdsResourceType.SecretKey = rdsResourceTypeObject.SecretKey ?? rdsResourceType.SecretKey;
-
                     rdsResourceTypeModel.Update(rdsResourceType);
                 }
                 else
                 {
                     RDSResourceType rdsResourceType = new RDSResourceType()
                     {
-                        BucketName = rdsResourceTypeObject.BucketName,
-                        AccessKey = rdsResourceTypeObject.AccessKey,
-                        SecretKey = rdsResourceTypeObject.SecretKey
+                        BucketName = GetRDSBucketName(),
+                        Size = rdsResourceTypeObject.Size,
                     };
                     rdsResourceTypeModel.Insert(rdsResourceType);
                     resource.ResourceTypeOptionId = rdsResourceType.Id;
                     Update(resource);
                 }
             }
+            else if (resource.Type.DisplayName == "s3")
+            {
+                S3ResourceTypeObject s3ResourceTypeObject = resourceTypeOption.ToObject<S3ResourceTypeObject>();
+                S3ResourceTypeModel s3ResourceTypeModel = new S3ResourceTypeModel();
+                if (resource.ResourceTypeOptionId != null)
+                {
+                    S3ResourceType s3ResourceType = s3ResourceTypeModel.GetById(resource.ResourceTypeOptionId.Value);
+
+                    s3ResourceType.BucketName = s3ResourceTypeObject.BucketName;
+                    s3ResourceType.AccessKey = s3ResourceTypeObject.AccessKey ?? s3ResourceType.AccessKey;
+                    s3ResourceType.SecretKey = s3ResourceTypeObject.SecretKey ?? s3ResourceType.SecretKey;
+
+                    s3ResourceTypeModel.Update(s3ResourceType);
+                }
+                else
+                {
+                    S3ResourceType s3ResourceType = new S3ResourceType()
+                    {
+                        BucketName = s3ResourceTypeObject.BucketName,
+                        AccessKey = s3ResourceTypeObject.AccessKey,
+                        SecretKey = s3ResourceTypeObject.SecretKey
+                    };
+                    s3ResourceTypeModel.Insert(s3ResourceType);
+                    resource.ResourceTypeOptionId = s3ResourceType.Id;
+                    Update(resource);
+                }
+            }
             else if (resource.Type.DisplayName == "gitlab")
             {
                 GitlabResourceTypeObject gitlabResourceTypeObject = resourceTypeOption.ToObject<GitlabResourceTypeObject>();
@@ -137,6 +162,17 @@ namespace Coscine.Api.Project.Models
             }
         }
 
+        private string GetRDSBucketName()
+        {
+            var prefix = _configuration.GetStringAndWait("coscine/global/buckets/prefix");
+            var number = Int32.Parse(_configuration.GetStringAndWait("coscine/global/buckets/currentid"));
+            var maxNumber = Int32.Parse(_configuration.GetStringAndWait("coscine/global/buckets/highestid"));
+            var newNumber = number % maxNumber == 0 ? 1 : number + 1;
+            _configuration.Put("coscine/global/buckets/currentid", "" + newNumber);
+
+            return String.Format("{0}{1,3:000}", prefix, number);
+        }
+
         private void SetDisciplines(Resource resource, IEnumerable<DisciplineObject> disciplines)
         {
             ResourceDisciplineModel resourceDisciplineModel = new ResourceDisciplineModel();
@@ -155,17 +191,15 @@ namespace Coscine.Api.Project.Models
             }
         }
 
-        public bool OwnsResource(User user, Resource resource)
+        public bool HasAccess(User user, Database.Model.Resource resource, params string[] allowedAccess)
         {
-            return DatabaseConnection.ConnectToDatabase((db) =>
-            {
-                return (from relation in db.ProjectRoles
-                        where relation.User == user
-                            && relation.Role.DisplayName == "Owner"
-                            && (relation.Project.ProjectResourceProjectIdIds != null && relation.Project.ProjectResourceProjectIdIds.
-                                Any((projectResource) => projectResource.Resource == resource))
-                        select relation).Any();
-            });
+            IEnumerable<string> allowedAccessLabels = allowedAccess.Select(x => x.ToLower().Trim()).ToList();
+            return DatabaseConnection.ConnectToDatabase((db) => (from relation in db.ProjectRoles
+                                                                 where relation.Project.ProjectResourceProjectIdIds != null && relation.Project.ProjectResourceProjectIdIds
+                                                                    .Any((projectResource) => projectResource.Resource.Id == resource.Id)
+                                                                     && relation.User.Id == user.Id
+                                                                     && allowedAccessLabels.Contains(relation.Role.DisplayName.ToLower())
+                                                                 select relation).Any());
         }
 
         public int UpdateByObject(Resource resource, ResourceObject resourceObject)
@@ -220,6 +254,11 @@ namespace Coscine.Api.Project.Models
                 RDSResourceTypeModel rdsResourceTypeModel = new RDSResourceTypeModel();
                 rdsResourceTypeModel.Delete(rdsResourceTypeModel.GetById(resource.ResourceTypeOptionId.Value));
             }
+            else if (resource.Type.DisplayName == "s3" && resource.ResourceTypeOptionId != null)
+            {
+                S3ResourceTypeModel s3ResourceTypeModel = new S3ResourceTypeModel();
+                s3ResourceTypeModel.Delete(s3ResourceTypeModel.GetById(resource.ResourceTypeOptionId.Value));
+            }
             else if (resource.Type.DisplayName == "gitlab" && resource.ResourceTypeOptionId != null)
             {
                 GitlabResourceTypeModel gitlabResourceTypeModel = new GitlabResourceTypeModel();
@@ -255,7 +294,13 @@ namespace Coscine.Api.Project.Models
             {
                 RDSResourceTypeModel rdsResourceTypeModel = new RDSResourceTypeModel();
                 var rdsResourceType = rdsResourceTypeModel.GetById(resource.ResourceTypeOptionId.Value);
-                resourceTypeOptionObject = new RDSResourceTypeObject(rdsResourceType.Id, rdsResourceType.BucketName, null, null);
+                resourceTypeOptionObject = new RDSResourceTypeObject(rdsResourceType.Id, rdsResourceType.BucketName, (int)rdsResourceType.Size);
+            }
+            else if (resource.Type.DisplayName == "s3" && resource.ResourceTypeOptionId != null)
+            {
+                S3ResourceTypeModel s3ResourceTypeModel = new S3ResourceTypeModel();
+                var s3ResourceType = s3ResourceTypeModel.GetById(resource.ResourceTypeOptionId.Value);
+                resourceTypeOptionObject = new S3ResourceTypeObject(s3ResourceType.Id, s3ResourceType.BucketName, null, null);
             }
             else if(resource.Type.DisplayName == "gitlab" && resource.ResourceTypeOptionId != null)
             {
diff --git a/src/Project/Models/S3ResourceTypeModel.cs b/src/Project/Models/S3ResourceTypeModel.cs
new file mode 100644
index 0000000000000000000000000000000000000000..33aef5403e9a91f35dc2d856eb58fc19b0641e4c
--- /dev/null
+++ b/src/Project/Models/S3ResourceTypeModel.cs
@@ -0,0 +1,35 @@
+using Coscine.ApiCommons.Models;
+using Coscine.Database.Model;
+using LinqToDB;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Coscine.Api.Project.Models
+{
+    public class S3ResourceTypeModel : DatabaseModel<S3ResourceType>
+    {
+        public S3ResourceTypeModel() : base(Program.Configuration)
+        {
+
+        }
+
+        public override Expression<Func<S3ResourceType, Guid>> GetIdFromObject()
+        {
+            return (rdsResourceType) => rdsResourceType.Id;
+        }
+
+        public override ITable<S3ResourceType> GetITableFromDatabase(CoscineDB db)
+        {
+            return db.S3ResourceTypes;
+        }
+
+        public override void SetObjectId(S3ResourceType databaseObject, Guid id)
+        {
+            databaseObject.Id = id;
+        }
+    }
+}
diff --git a/src/Project/Project.csproj b/src/Project/Project.csproj
index a56c773c684b97ed9f90e138475d2b9558f73076..79c2e9f687fc18f7c0199b50e4a87e8c5df19612 100644
--- a/src/Project/Project.csproj
+++ b/src/Project/Project.csproj
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\packages\NUnit.3.12.0\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" />
   <Import Project="..\packages\linq2db.t4models.2.6.4\build\linq2db.t4models.props" Condition="Exists('..\packages\linq2db.t4models.2.6.4\build\linq2db.t4models.props')" />
   <Import Project="..\packages\linq2db.SqlServer.2.6.4\build\linq2db.SqlServer.props" Condition="Exists('..\packages\linq2db.SqlServer.2.6.4\build\linq2db.SqlServer.props')" />
   <Import Project="..\packages\Microsoft.CodeAnalysis.Analyzers.2.9.2\build\Microsoft.CodeAnalysis.Analyzers.props" Condition="Exists('..\packages\Microsoft.CodeAnalysis.Analyzers.2.9.2\build\Microsoft.CodeAnalysis.Analyzers.props')" />
@@ -48,14 +49,17 @@
     <Reference Include="Coscine.Action, Version=1.7.0.0, Culture=neutral, processorArchitecture=AMD64">
       <HintPath>..\packages\Coscine.Action.1.7.0\lib\net461\Coscine.Action.dll</HintPath>
     </Reference>
-    <Reference Include="Coscine.ApiCommons, Version=1.2.2.0, Culture=neutral, PublicKeyToken=af4c1345df96546b, processorArchitecture=MSIL">
-      <HintPath>..\packages\Coscine.ApiCommons.1.2.2\lib\net461\Coscine.ApiCommons.dll</HintPath>
+    <Reference Include="Coscine.ApiCommons, Version=1.2.2.3, Culture=neutral, PublicKeyToken=af4c1345df96546b, processorArchitecture=MSIL">
+      <HintPath>..\packages\Coscine.ApiCommons.1.2.2.3\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.10.0.0, Culture=neutral, PublicKeyToken=767d77427707b70a, processorArchitecture=MSIL">
-      <HintPath>..\packages\Coscine.Database.1.10.0\lib\net461\Coscine.Database.dll</HintPath>
+    <Reference Include="Coscine.Database, Version=1.11.0.0, Culture=neutral, PublicKeyToken=767d77427707b70a, processorArchitecture=MSIL">
+      <HintPath>..\packages\Coscine.Database.1.11.0\lib\net461\Coscine.Database.dll</HintPath>
+    </Reference>
+    <Reference Include="Coscine.Logging, Version=0.0.1.0, Culture=neutral, PublicKeyToken=e1ed402bc3f6525e, processorArchitecture=MSIL">
+      <HintPath>..\packages\Coscine.Logging.0.0.1\lib\net461\Coscine.Logging.dll</HintPath>
     </Reference>
     <Reference Include="Coscine.ProxyApi, Version=1.2.0.0, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\packages\Coscine.ProxyApi.1.2.0\lib\net461\Coscine.ProxyApi.dll</HintPath>
@@ -93,12 +97,18 @@
     <Reference Include="Microsoft.AspNetCore.Antiforgery, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
       <HintPath>..\packages\Microsoft.AspNetCore.Antiforgery.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Antiforgery.dll</HintPath>
     </Reference>
+    <Reference Include="Microsoft.AspNetCore.Authentication, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.AspNetCore.Authentication.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Authentication.dll</HintPath>
+    </Reference>
     <Reference Include="Microsoft.AspNetCore.Authentication.Abstractions, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
       <HintPath>..\packages\Microsoft.AspNetCore.Authentication.Abstractions.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Authentication.Abstractions.dll</HintPath>
     </Reference>
     <Reference Include="Microsoft.AspNetCore.Authentication.Core, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
       <HintPath>..\packages\Microsoft.AspNetCore.Authentication.Core.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Authentication.Core.dll</HintPath>
     </Reference>
+    <Reference Include="Microsoft.AspNetCore.Authentication.JwtBearer, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.AspNetCore.Authentication.JwtBearer.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Authentication.JwtBearer.dll</HintPath>
+    </Reference>
     <Reference Include="Microsoft.AspNetCore.Authorization, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
       <HintPath>..\packages\Microsoft.AspNetCore.Authorization.2.2.0\lib\netstandard2.0\Microsoft.AspNetCore.Authorization.dll</HintPath>
     </Reference>
@@ -362,6 +372,12 @@
     <Reference Include="Microsoft.IdentityModel.Logging, Version=5.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
       <HintPath>..\packages\Microsoft.IdentityModel.Logging.5.6.0\lib\net461\Microsoft.IdentityModel.Logging.dll</HintPath>
     </Reference>
+    <Reference Include="Microsoft.IdentityModel.Protocols, Version=5.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.IdentityModel.Protocols.5.3.0\lib\net461\Microsoft.IdentityModel.Protocols.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect, Version=5.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.IdentityModel.Protocols.OpenIdConnect.5.3.0\lib\net461\Microsoft.IdentityModel.Protocols.OpenIdConnect.dll</HintPath>
+    </Reference>
     <Reference Include="Microsoft.IdentityModel.Tokens, Version=5.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
       <HintPath>..\packages\Microsoft.IdentityModel.Tokens.5.6.0\lib\net461\Microsoft.IdentityModel.Tokens.dll</HintPath>
     </Reference>
@@ -379,6 +395,18 @@
       <HintPath>..\packages\Newtonsoft.Json.Bson.1.0.2\lib\net45\Newtonsoft.Json.Bson.dll</HintPath>
       <Private>True</Private>
     </Reference>
+    <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
+      <HintPath>..\packages\NLog.4.6.8\lib\net45\NLog.dll</HintPath>
+    </Reference>
+    <Reference Include="NLog.Extensions.Logging, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
+      <HintPath>..\packages\NLog.Extensions.Logging.1.6.1\lib\net461\NLog.Extensions.Logging.dll</HintPath>
+    </Reference>
+    <Reference Include="NLog.Web.AspNetCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
+      <HintPath>..\packages\NLog.Web.AspNetCore.4.9.0\lib\net461\NLog.Web.AspNetCore.dll</HintPath>
+    </Reference>
+    <Reference Include="nunit.framework, Version=3.12.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
+      <HintPath>..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.AppContext, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
       <HintPath>..\packages\System.AppContext.4.3.0\lib\net463\System.AppContext.dll</HintPath>
@@ -495,6 +523,7 @@
       <Private>True</Private>
       <Private>True</Private>
     </Reference>
+    <Reference Include="System.Runtime.Serialization" />
     <Reference Include="System.Security" />
     <Reference Include="System.Security.AccessControl, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
       <HintPath>..\packages\System.Security.AccessControl.4.5.0\lib\net461\System.Security.AccessControl.dll</HintPath>
@@ -530,6 +559,7 @@
       <HintPath>..\packages\System.Security.Principal.Windows.4.5.1\lib\net461\System.Security.Principal.Windows.dll</HintPath>
       <Private>True</Private>
     </Reference>
+    <Reference Include="System.ServiceModel" />
     <Reference Include="System.ServiceProcess" />
     <Reference Include="System.Text.Encoding.CodePages, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
       <HintPath>..\packages\System.Text.Encoding.CodePages.4.5.1\lib\net461\System.Text.Encoding.CodePages.dll</HintPath>
@@ -606,6 +636,7 @@
     <Compile Include="Models\ProjectModel.cs" />
     <Compile Include="Models\ProjectResourceModel.cs" />
     <Compile Include="Models\ProjectRoleModel.cs" />
+    <Compile Include="Models\S3ResourceTypeModel.cs" />
     <Compile Include="Models\RDSResourceTypeModel.cs" />
     <Compile Include="Models\ResourceDisciplineModel.cs" />
     <Compile Include="Models\MetadataModel.cs" />
@@ -619,6 +650,7 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="ReturnObjects\GitlabResourceTypeObject.cs" />
     <Compile Include="ReturnObjects\LicenseObject.cs" />
+    <Compile Include="ReturnObjects\S3ResourceTypeObject.cs" />
     <Compile Include="ReturnObjects\RDSResourceTypeObject.cs" />
     <Compile Include="ReturnObjects\ResourceTypeOptionObject.cs" />
     <Compile Include="ReturnObjects\VisibilityObject.cs" />
@@ -632,6 +664,7 @@
     <Compile Include="ReturnObjects\UserObject.cs" />
     <Compile Include="ReturnObjects\WaterbutlerFolder.cs" />
     <Compile Include="Startup.cs" />
+    <Compile Include="UserRoles.cs" />
   </ItemGroup>
   <ItemGroup>
     <None Include="App.config" />
@@ -656,6 +689,7 @@
     <Error Condition="!Exists('..\packages\Microsoft.CodeAnalysis.Analyzers.2.9.2\build\Microsoft.CodeAnalysis.Analyzers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeAnalysis.Analyzers.2.9.2\build\Microsoft.CodeAnalysis.Analyzers.props'))" />
     <Error Condition="!Exists('..\packages\linq2db.SqlServer.2.6.4\build\linq2db.SqlServer.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\linq2db.SqlServer.2.6.4\build\linq2db.SqlServer.props'))" />
     <Error Condition="!Exists('..\packages\linq2db.t4models.2.6.4\build\linq2db.t4models.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\linq2db.t4models.2.6.4\build\linq2db.t4models.props'))" />
+    <Error Condition="!Exists('..\packages\NUnit.3.12.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit.3.12.0\build\NUnit.props'))" />
   </Target>
   <Import Project="..\packages\Microsoft.Extensions.Configuration.UserSecrets.2.2.0\build\netstandard2.0\Microsoft.Extensions.Configuration.UserSecrets.targets" Condition="Exists('..\packages\Microsoft.Extensions.Configuration.UserSecrets.2.2.0\build\netstandard2.0\Microsoft.Extensions.Configuration.UserSecrets.targets')" />
   <Import Project="..\packages\Microsoft.AspNetCore.Server.IIS.2.2.2\build\netstandard2.0\Microsoft.AspNetCore.Server.IIS.targets" Condition="Exists('..\packages\Microsoft.AspNetCore.Server.IIS.2.2.2\build\netstandard2.0\Microsoft.AspNetCore.Server.IIS.targets')" />
diff --git a/src/Project/Properties/AssemblyInfo.cs b/src/Project/Properties/AssemblyInfo.cs
index 0cf8d791c023660830c4b18c4d0b43011aea3bd2..189524a97c5b1ca7e4468964ead1739f3dbc32ba 100644
--- a/src/Project/Properties/AssemblyInfo.cs
+++ b/src/Project/Properties/AssemblyInfo.cs
@@ -9,8 +9,8 @@ using System.Reflection;
 [assembly: AssemblyDescription("Project is a part of the CoScInE group.")]
 [assembly: AssemblyCompany("IT Center, RWTH Aachen University")]
 [assembly: AssemblyProduct("Project")]
-[assembly: AssemblyVersion("1.9.0.0")]
-[assembly: AssemblyFileVersion("1.9.0.0")]
-[assembly: AssemblyInformationalVersion("1.9.0.0")]
+[assembly: AssemblyVersion("1.10.0.0")]
+[assembly: AssemblyFileVersion("1.10.0.0")]
+[assembly: AssemblyInformationalVersion("1.10.0.0")]
 [assembly: AssemblyCopyright("2019 IT Center, RWTH Aachen University")]
 
diff --git a/src/Project/ReturnObjects/RDSResourceTypeObject.cs b/src/Project/ReturnObjects/RDSResourceTypeObject.cs
index 35d846842e81252c167469d38c375892307b0b04..daa4de5dca7007240612934685a83e5820a6145c 100644
--- a/src/Project/ReturnObjects/RDSResourceTypeObject.cs
+++ b/src/Project/ReturnObjects/RDSResourceTypeObject.cs
@@ -7,16 +7,13 @@ namespace Coscine.Api.Project.ReturnObjects
     {
         public Guid Id { get; set; }
         public string BucketName { get; set; }
-        public string AccessKey { get; set; }
-        public string SecretKey { get; set; }
+        public int Size { get; set; }
 
-        public RDSResourceTypeObject(Guid id, string bucketName, string accessKey, string secretKey)
+        public RDSResourceTypeObject(Guid id, string bucketName, int size)
         {
             Id = id;
             BucketName = bucketName;
-
-            AccessKey = accessKey;
-            SecretKey = secretKey;
+            Size = size;
         }
     }
 }
diff --git a/src/Project/ReturnObjects/S3ResourceTypeObject.cs b/src/Project/ReturnObjects/S3ResourceTypeObject.cs
new file mode 100644
index 0000000000000000000000000000000000000000..f539a9744ae788649efd7b7c21d5527ed36396a6
--- /dev/null
+++ b/src/Project/ReturnObjects/S3ResourceTypeObject.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace Coscine.Api.Project.ReturnObjects
+{
+    [Serializable]
+    public class S3ResourceTypeObject : ResourceTypeOptionObject
+    {
+        public Guid Id { get; set; }
+        public string BucketName { get; set; }
+        public string AccessKey { get; set; }
+        public string SecretKey { get; set; }
+
+        public S3ResourceTypeObject(Guid id, string bucketName, string accessKey, string secretKey)
+        {
+            Id = id;
+            BucketName = bucketName;
+
+            AccessKey = accessKey;
+            SecretKey = secretKey;
+        }
+    }
+}
diff --git a/src/Project/UserRoles.cs b/src/Project/UserRoles.cs
new file mode 100644
index 0000000000000000000000000000000000000000..4a3b85301f9344ddc458577e6533dd782f871e22
--- /dev/null
+++ b/src/Project/UserRoles.cs
@@ -0,0 +1,8 @@
+namespace Coscine.Api.Project
+{
+    public static class UserRoles
+    {
+        public static string Member { get; } = "member";
+        public static string Owner { get; } = "owner";
+    }
+}
diff --git a/src/Project/packages.config b/src/Project/packages.config
index 4e0f5359c4c1f026ba38b41e276c44392dd09b12..5e90374248bd73e3a1448e5112b4f951e76998be 100644
--- a/src/Project/packages.config
+++ b/src/Project/packages.config
@@ -4,9 +4,10 @@
   <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.7.0" targetFramework="net472" />
-  <package id="Coscine.ApiCommons" version="1.2.2" targetFramework="net472" />
+  <package id="Coscine.ApiCommons" version="1.2.2.3" targetFramework="net472" />
   <package id="Coscine.Configuration" version="1.4.0" targetFramework="net472" />
-  <package id="Coscine.Database" version="1.10.0" targetFramework="net472" />
+  <package id="Coscine.Database" version="1.11.0" targetFramework="net472" />
+  <package id="Coscine.Logging" version="0.0.1" targetFramework="net472" />
   <package id="Coscine.ProxyApi" version="1.2.0" targetFramework="net472" />
   <package id="Coscine.SharePoint.Webparts.Vue" version="1.4.0" targetFramework="net472" />
   <package id="dotNetRDF" version="2.2.1" targetFramework="net472" />
@@ -20,8 +21,10 @@
   <package id="Metadata" version="1.0.0" targetFramework="net472" />
   <package id="Microsoft.AspNetCore" version="2.2.0" targetFramework="net472" />
   <package id="Microsoft.AspNetCore.Antiforgery" version="2.2.0" targetFramework="net472" />
+  <package id="Microsoft.AspNetCore.Authentication" version="2.2.0" targetFramework="net472" />
   <package id="Microsoft.AspNetCore.Authentication.Abstractions" version="2.2.0" targetFramework="net472" />
   <package id="Microsoft.AspNetCore.Authentication.Core" version="2.2.0" targetFramework="net472" />
+  <package id="Microsoft.AspNetCore.Authentication.JwtBearer" version="2.2.0" targetFramework="net472" />
   <package id="Microsoft.AspNetCore.Authorization" version="2.2.0" targetFramework="net472" />
   <package id="Microsoft.AspNetCore.Authorization.Policy" version="2.2.0" targetFramework="net472" />
   <package id="Microsoft.AspNetCore.Connections.Abstractions" version="2.2.0" targetFramework="net472" />
@@ -113,11 +116,19 @@
   <package id="Microsoft.IdentityModel" version="7.0.0" targetFramework="net472" />
   <package id="Microsoft.IdentityModel.JsonWebTokens" version="5.6.0" targetFramework="net472" />
   <package id="Microsoft.IdentityModel.Logging" version="5.6.0" targetFramework="net472" />
+  <package id="Microsoft.IdentityModel.Protocols" version="5.3.0" targetFramework="net472" />
+  <package id="Microsoft.IdentityModel.Protocols.OpenIdConnect" version="5.3.0" targetFramework="net472" />
   <package id="Microsoft.IdentityModel.Tokens" version="5.6.0" targetFramework="net472" />
   <package id="Microsoft.Net.Http.Headers" version="2.2.0" targetFramework="net472" />
   <package id="Microsoft.Win32.Registry" version="4.5.0" targetFramework="net472" />
   <package id="Newtonsoft.Json" version="12.0.2" targetFramework="net472" />
   <package id="Newtonsoft.Json.Bson" version="1.0.2" targetFramework="net472" />
+  <package id="NLog" version="4.6.8" targetFramework="net472" />
+  <package id="NLog.Config" version="4.6.8" targetFramework="net472" />
+  <package id="NLog.Extensions.Logging" version="1.6.1" targetFramework="net472" />
+  <package id="NLog.Schema" version="4.6.8" targetFramework="net472" />
+  <package id="NLog.Web.AspNetCore" version="4.9.0" targetFramework="net472" />
+  <package id="NUnit" version="3.12.0" targetFramework="net472" />
   <package id="OpenLink.Data.Virtuoso" version="7.20.3214.1" targetFramework="net472" />
   <package id="System.AppContext" version="4.3.0" targetFramework="net472" />
   <package id="System.Buffers" version="4.5.0" targetFramework="net472" />