diff --git a/src/User.Tests/App.config b/src/User.Tests/App.config index 342324830f388445687556d071b8e314125da385..4ea3b8bcbdfca81dcd8fa77339da7cdeb2328258 100644 --- a/src/User.Tests/App.config +++ b/src/User.Tests/App.config @@ -147,6 +147,17 @@ <dependentAssembly> <assemblyIdentity name="Coscine.Logging" publicKeyToken="e1ed402bc3f6525e" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-1.0.1.0" newVersion="1.0.1.0" /> + </dependentAssembly> <dependentAssembly> + <assemblyIdentity name="Microsoft.IdentityModel.Logging" publicKeyToken="31bf3856ad364e35" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.IdentityModel.Tokens" publicKeyToken="31bf3856ad364e35" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> diff --git a/src/User.Tests/User.Tests.csproj b/src/User.Tests/User.Tests.csproj index d5aa793738cabc54d4efd9af21a47bb2133c3853..54e218c05455cd31a83c12cc95e1c991e8f70438 100644 --- a/src/User.Tests/User.Tests.csproj +++ b/src/User.Tests/User.Tests.csproj @@ -84,12 +84,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> @@ -345,6 +351,12 @@ <Reference Include="Microsoft.IdentityModel.Logging, Version=5.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <HintPath>..\packages\Microsoft.IdentityModel.Logging.5.5.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.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <HintPath>..\packages\Microsoft.IdentityModel.Tokens.5.5.0\lib\net461\Microsoft.IdentityModel.Tokens.dll</HintPath> </Reference> diff --git a/src/User.Tests/UserControllerTests.cs b/src/User.Tests/UserControllerTests.cs index 4ccdf19cd44f99447f8831652aab8e714b5a910e..e8ee1448ea2f7045f76e2ee5399535ec5032eadb 100644 --- a/src/User.Tests/UserControllerTests.cs +++ b/src/User.Tests/UserControllerTests.cs @@ -12,6 +12,7 @@ using Moq; using NUnit.Framework; using System.Collections.Generic; using System.IO; +using System.Security.Claims; namespace User.Tests { @@ -64,6 +65,11 @@ namespace User.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/User.Tests/packages.config b/src/User.Tests/packages.config index f72790f30920443e2fbe5ad65e85cc6ae18509cf..7b8fb0aed87ab6cb9c1b5e75b696d5bceb1f4d2e 100644 --- a/src/User.Tests/packages.config +++ b/src/User.Tests/packages.config @@ -15,8 +15,10 @@ <package id="LinqKit" version="1.1.16" targetFramework="net461" /> <package id="Microsoft.AspNetCore" version="2.2.0" targetFramework="net461" /> <package id="Microsoft.AspNetCore.Antiforgery" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Authentication" version="2.2.0" targetFramework="net461" /> <package id="Microsoft.AspNetCore.Authentication.Abstractions" version="2.2.0" targetFramework="net461" /> <package id="Microsoft.AspNetCore.Authentication.Core" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Authentication.JwtBearer" version="2.2.0" targetFramework="net461" /> <package id="Microsoft.AspNetCore.Authorization" version="2.2.0" targetFramework="net461" /> <package id="Microsoft.AspNetCore.Authorization.Policy" version="2.2.0" targetFramework="net461" /> <package id="Microsoft.AspNetCore.Connections.Abstractions" version="2.2.0" targetFramework="net461" /> @@ -107,6 +109,8 @@ <package id="Microsoft.Extensions.WebEncoders" version="2.2.0" targetFramework="net461" /> <package id="Microsoft.IdentityModel.JsonWebTokens" version="5.5.0" targetFramework="net461" /> <package id="Microsoft.IdentityModel.Logging" version="5.5.0" targetFramework="net461" /> + <package id="Microsoft.IdentityModel.Protocols" version="5.3.0" targetFramework="net461" /> + <package id="Microsoft.IdentityModel.Protocols.OpenIdConnect" version="5.3.0" targetFramework="net461" /> <package id="Microsoft.IdentityModel.Tokens" version="5.5.0" targetFramework="net461" /> <package id="Microsoft.Net.Http.Headers" version="2.2.0" targetFramework="net461" /> <package id="Microsoft.Win32.Registry" version="4.5.0" targetFramework="net461" /> diff --git a/src/User/App.config b/src/User/App.config index 1e00acd80c44f9f6748626fc78fd312fe759fcaa..bc9385c9ab589ec7770c0863a33c774370f7062e 100644 --- a/src/User/App.config +++ b/src/User/App.config @@ -150,6 +150,17 @@ <dependentAssembly> <assemblyIdentity name="Coscine.Logging" publicKeyToken="e1ed402bc3f6525e" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-1.0.1.0" newVersion="1.0.1.0" /> + </dependentAssembly> <dependentAssembly> + <assemblyIdentity name="Microsoft.IdentityModel.Logging" publicKeyToken="31bf3856ad364e35" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="Microsoft.IdentityModel.Tokens" publicKeyToken="31bf3856ad364e35" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0" /> + </dependentAssembly> + <dependentAssembly> + <assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" /> + <bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> diff --git a/src/User/Controllers/UserController.cs b/src/User/Controllers/UserController.cs index 285df3f18da5216baac4390f980c1e1b2233e24f..deed51b7cfc99e337758ab2a01a647888493709f 100644 --- a/src/User/Controllers/UserController.cs +++ b/src/User/Controllers/UserController.cs @@ -6,9 +6,11 @@ using Microsoft.AspNetCore.Mvc; using System; using System.Linq; using System.ComponentModel.DataAnnotations; +using Microsoft.AspNetCore.Authorization; namespace Coscine.Api.User.Controllers { + [Authorize] public class UserController : Controller { private readonly Authenticator _authenticator; @@ -23,50 +25,50 @@ namespace Coscine.Api.User.Controllers [HttpPost("[controller]/email")] public IActionResult ChangeContactMail() { - return Ok(_authenticator.ValidateAndExecute((user) => + var user = _authenticator.GetUser(); + + UserObject userObject = ObjectFactory<UserObject>.DeserializeFromStream(Request.Body); + if (new EmailAddressAttribute().IsValid(userObject.EmailAddress)) + { + user.EmailAddress = userObject.EmailAddress; + return Ok(_userModel.Update(user)); + } + else { - UserObject userObject = ObjectFactory<UserObject>.DeserializeFromStream(Request.Body); - if (new EmailAddressAttribute().IsValid(userObject.EmailAddress)) - { - user.EmailAddress = userObject.EmailAddress; - return _userModel.Update(user); - } - else - { - throw new FormatException("Incorrect E-Mail format!"); - } - })); + throw new FormatException("Incorrect E-Mail format!"); + } } [HttpGet("[controller]/user")] public IActionResult GetUser() { - return Ok(_authenticator.ValidateAndExecute((user) => new UserObject(user.Id, user.DisplayName, user.EmailAddress))); + var user = _authenticator.GetUser(); + return Ok(new UserObject(user.Id, user.DisplayName, user.EmailAddress)); } [HttpGet("[controller]/query/{queryString}/project/{projectId}")] public IActionResult Query(string queryString, string projectId) { - return Ok(_authenticator.ValidateAndExecute((user) => { - string lowerQueryString = queryString.ToLower(); - Guid.TryParse(projectId, out Guid projectIdGuid); - ProjectModel projectModel = new ProjectModel(); - if (projectModel.OwnsProject(user, projectModel.GetById(projectIdGuid))) - { - return _userModel.GetAllWhere((dbUser) => - (dbUser.DisplayName.ToLower().Contains(lowerQueryString) - || dbUser.EmailAddress.ToLower().Contains(lowerQueryString)) - && !((from projectRole in dbUser.ProjectRolesUserIdIds - where projectRole.ProjectId == projectIdGuid - select projectRole).Any())) - .Take(10) - .Select((dbUser) => new UserObject(dbUser.Id, dbUser.DisplayName, null)); - } - else - { - throw new UnauthorizedAccessException("User is not allowed to query users with respect to given project!"); - } - })); + var user = _authenticator.GetUser(); + string lowerQueryString = queryString.ToLower(); + Guid.TryParse(projectId, out Guid projectIdGuid); + ProjectModel projectModel = new ProjectModel(); + + if (projectModel.HasAccess(user, projectModel.GetById(projectIdGuid))) + { + return Ok(_userModel.GetAllWhere((dbUser) => + (dbUser.DisplayName.ToLower().Contains(lowerQueryString) + || dbUser.EmailAddress.ToLower().Contains(lowerQueryString)) + && !((from projectRole in dbUser.ProjectRolesUserIdIds + where projectRole.ProjectId == projectIdGuid + select projectRole).Any())) + .Take(10) + .Select((dbUser) => new UserObject(dbUser.Id, dbUser.DisplayName, null))); + } + else + { + throw new UnauthorizedAccessException("User is not allowed to query users with respect to given project!"); + } } } diff --git a/src/User/Models/ProjectModel.cs b/src/User/Models/ProjectModel.cs index d37fdea69bcdb32c39659a29ccddf63864d7c9f0..2e6b7e9be5fa27cc8fbe5eafc81dac13e342c58e 100644 --- a/src/User/Models/ProjectModel.cs +++ b/src/User/Models/ProjectModel.cs @@ -17,12 +17,12 @@ namespace Coscine.Api.User.Models } - public bool OwnsProject(Coscine.Database.Model.User user, Project project) + public bool HasAccess(Coscine.Database.Model.User user, Project project) { return DatabaseConnection.ConnectToDatabase((db) => (from relation in db.ProjectRoles where relation.Project == project && relation.User == user - && relation.Role.DisplayName == "Owner" + && (relation.Role.DisplayName == "Owner" || relation.Role.DisplayName == "Member") select relation).Any()); } diff --git a/src/User/User.csproj b/src/User/User.csproj index 95257bd2c912c921f91fd4f8352cb830970184e3..ad4828c8e1252265610d23079dd00541bc4f3151 100644 --- a/src/User/User.csproj +++ b/src/User/User.csproj @@ -82,12 +82,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> @@ -343,6 +349,12 @@ <Reference Include="Microsoft.IdentityModel.Logging, Version=5.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <HintPath>..\packages\Microsoft.IdentityModel.Logging.5.5.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.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <HintPath>..\packages\Microsoft.IdentityModel.Tokens.5.5.0\lib\net461\Microsoft.IdentityModel.Tokens.dll</HintPath> </Reference> @@ -542,6 +554,7 @@ <Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="ReturnObjects\UserObject.cs" /> <Compile Include="Startup.cs" /> + <Compile Include="UserRoles.cs" /> </ItemGroup> <ItemGroup> <None Include="App.config" /> diff --git a/src/User/UserRoles.cs b/src/User/UserRoles.cs new file mode 100644 index 0000000000000000000000000000000000000000..25b4281beb01c92e10ee7f8b5826832490793f27 --- /dev/null +++ b/src/User/UserRoles.cs @@ -0,0 +1,8 @@ +namespace Coscine.Api.User +{ + public static class UserRoles + { + public static string Member { get; } = "member"; + public static string Owner { get; } = "owner"; + } +} \ No newline at end of file diff --git a/src/User/packages.config b/src/User/packages.config index daa5f64253799b59a37fbb394a449d2b52d6c68e..13aa266f25577ddfc3a1dde743af58985355728f 100644 --- a/src/User/packages.config +++ b/src/User/packages.config @@ -14,8 +14,10 @@ <package id="LinqKit" version="1.1.16" targetFramework="net461" /> <package id="Microsoft.AspNetCore" version="2.2.0" targetFramework="net461" /> <package id="Microsoft.AspNetCore.Antiforgery" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Authentication" version="2.2.0" targetFramework="net461" /> <package id="Microsoft.AspNetCore.Authentication.Abstractions" version="2.2.0" targetFramework="net461" /> <package id="Microsoft.AspNetCore.Authentication.Core" version="2.2.0" targetFramework="net461" /> + <package id="Microsoft.AspNetCore.Authentication.JwtBearer" version="2.2.0" targetFramework="net461" /> <package id="Microsoft.AspNetCore.Authorization" version="2.2.0" targetFramework="net461" /> <package id="Microsoft.AspNetCore.Authorization.Policy" version="2.2.0" targetFramework="net461" /> <package id="Microsoft.AspNetCore.Connections.Abstractions" version="2.2.0" targetFramework="net461" /> @@ -106,6 +108,8 @@ <package id="Microsoft.Extensions.WebEncoders" version="2.2.0" targetFramework="net461" /> <package id="Microsoft.IdentityModel.JsonWebTokens" version="5.5.0" targetFramework="net461" /> <package id="Microsoft.IdentityModel.Logging" version="5.5.0" targetFramework="net461" /> + <package id="Microsoft.IdentityModel.Protocols" version="5.3.0" targetFramework="net461" /> + <package id="Microsoft.IdentityModel.Protocols.OpenIdConnect" version="5.3.0" targetFramework="net461" /> <package id="Microsoft.IdentityModel.Tokens" version="5.5.0" targetFramework="net461" /> <package id="Microsoft.Net.Http.Headers" version="2.2.0" targetFramework="net461" /> <package id="Microsoft.Win32.Registry" version="4.5.0" targetFramework="net461" />