Skip to content

Commit

Permalink
Merge pull request #300 from DigitalExcellence/release/0.8.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Brend-Smits authored Nov 6, 2020
2 parents a164ed4 + 75d3852 commit 653ed67
Show file tree
Hide file tree
Showing 106 changed files with 12,545 additions and 1,370 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/staging-deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ jobs:
docker-compose down
docker-compose pull
sleep 10s
docker-compose up -d
docker-compose up -d
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -333,3 +333,6 @@ profile


IdentityServer/tempkey.rsa

/API/Uploads/Images/*
!/API/Uploads/Images/.gitkeep
10 changes: 9 additions & 1 deletion API/1_API.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
Expand All @@ -15,6 +15,14 @@
<None Remove="Resources\Project\**" />
</ItemGroup>

<ItemGroup>
<None Remove="Uploads\Images\.gitkeep" />
</ItemGroup>

<ItemGroup>
<Content Include="Uploads\Images\.gitkeep" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="AutoMapper" Version="9.0.0" />
<PackageReference Include="FluentValidation.AspNetCore" Version="8.6.2" />
Expand Down
65 changes: 65 additions & 0 deletions API/Common/AuthorizationHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Digital Excellence Copyright (C) 2020 Brend Smits
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You can find a copy of the GNU Lesser General Public License
* along with this program, in the LICENSE.md file in the root project directory.
* If not, see https://www.gnu.org/licenses/lgpl-3.0.txt
*/

using Models;
using Services.Services;
using System.Threading.Tasks;

namespace API.Common
{
/// <summary>
/// The implementation for the authorization helper.
/// </summary>
public class AuthorizationHelper : IAuthorizationHelper
{

private readonly IUserService userService;

/// <summary>
/// Initializes a new instance of the <see cref="AuthorizationHelper"/> class.
/// </summary>
/// <param name="userService">The user service for communicating with the logic layer.</param>
public AuthorizationHelper(IUserService userService)
{
this.userService = userService;
}

/// <summary>
/// This method checks if a user has the correct scope to use the endpoint.
/// This method checks for a normal scope and the data officer scope within the
/// same institution.
/// </summary>
/// <param name="loggedInUser">The user model of the logged in user.</param>
/// <param name="scope">The required scope for accessing this endpoint.</param>
/// <param name="dataOfficerScope">The required scope for accessing this
/// endpoint for data officers within the same institution.</param>
/// <param name="propertyOfUserId">The id of the user owner of the property
/// which the logged in user wants to access.</param>
/// <returns>bool: true if the user is allowed, false if the user is not allowed.</returns>
public async Task<bool> UserIsAllowed(User loggedInUser, string scope, string dataOfficerScope, int propertyOfUserId)
{
bool hasUserWriteScope = userService.UserHasScope(loggedInUser.IdentityId, scope);
bool hasCorrectDataOfficerRights =
userService.UserHasScope(loggedInUser.IdentityId, dataOfficerScope) &&
await userService.HasSameInstitution(loggedInUser.Id, propertyOfUserId);
bool isAllowed = hasUserWriteScope || hasCorrectDataOfficerRights;
return isAllowed;
}

}

}
47 changes: 47 additions & 0 deletions API/Common/IAuthorizationHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Digital Excellence Copyright (C) 2020 Brend Smits
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You can find a copy of the GNU Lesser General Public License
* along with this program, in the LICENSE.md file in the root project directory.
* If not, see https://www.gnu.org/licenses/lgpl-3.0.txt
*/

using Models;
using System.Threading.Tasks;

namespace API.Common
{
/// <summary>
/// The interface for the authorization helper
/// </summary>
public interface IAuthorizationHelper
{
/// <summary>
/// This method checks if a user has the correct scope to use the endpoint.
/// This method checks for a normal scope and the data officer scope within the
/// same institution.
/// </summary>
/// <param name="loggedInUser">The user model of the logged in user.</param>
/// <param name="scope">The required scope for accessing this endpoint.</param>
/// <param name="dataOfficerScope">The required scope for accessing this
/// endpoint for data officers within the same institution.</param>
/// <param name="propertyOfUserId">The id of the user owner of the property
/// which the logged in user wants to access.</param>
/// <returns>bool: true if the user is allowed, false if the user is not allowed.</returns>
public Task<bool> UserIsAllowed(User loggedInUser,
string scope,
string dataOfficerScope,
int propertyOfUserId);

}

}
27 changes: 26 additions & 1 deletion API/Configuration/MappingProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,26 @@ public class MappingProfile : Profile
/// </summary>
public MappingProfile()
{
CreateMap<UserResource, User>();
CreateMap<UserUserResourceResult, UserUser>();

CreateMap<UserUser, UserUserResourceResult>()
.ForMember(q => q.Id, opt => opt.MapFrom(q => q.FollowedUser.Id))
.ForMember(q => q.Name, opt => opt.MapFrom(q => q.FollowedUser.Name))
.ForAllOtherMembers(o => o.Ignore());

CreateMap<UserProject, UserProjectResourceResult>()
.ForMember(q => q.Id, opt => opt.MapFrom(p => p.Project.Id))
.ForMember(q => q.Name, opt => opt.MapFrom(p => p.Project.Name))
.ForMember(q => q.ShortDescription, opt => opt.MapFrom(p => p.Project.ShortDescription))
.ForMember(q => q.Uri, opt => opt.MapFrom(p => p.Project.Uri))
.ForMember(q => q.Description, opt => opt.MapFrom(p => p.Project.Description))
.ForAllOtherMembers(o => o.Ignore());


CreateMap<User, UserResourceResult>();

CreateMap<UserResource, User>();

CreateMap<User, LimitedUserResourceResult>();

CreateMap<ProjectResource, Project>();
Expand All @@ -57,8 +75,15 @@ public MappingProfile()
CreateMap<EmbeddedProjectResource, EmbeddedProject>();
CreateMap<EmbeddedProject, EmbeddedProjectResourceResult>();

CreateMap<FileResourceResult, File>();
CreateMap<File, FileResourceResult>().ForMember(e => e.UploaderUserId,
opt => opt.MapFrom(e => e.Uploader.Id));

CreateMap<RoleScopeResource, RoleScope>();
CreateMap<RoleScope, RoleScopeResource>();

CreateMap<InstitutionResource, Institution>();
CreateMap<Institution, InstitutionResourceResult>();
}
}
}
22 changes: 16 additions & 6 deletions API/Controllers/EmbedController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* If not, see https://www.gnu.org/licenses/lgpl-3.0.txt
*/

using API.Common;
using API.Extensions;
using API.Resources;
using AutoMapper;
Expand All @@ -27,9 +28,7 @@
using Services.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace API.Controllers
Expand All @@ -47,6 +46,7 @@ public class EmbedController : ControllerBase
private readonly IMapper mapper;
private readonly IProjectService projectService;
private readonly IUserService userService;
private readonly IAuthorizationHelper authorizationHelper;

/// <summary>
/// Initializes a new instance of the <see cref="EmbedController"/> class
Expand All @@ -55,12 +55,18 @@ public class EmbedController : ControllerBase
/// <param name="mapper">The mapper which is used to convert the resources to the models to the resource results.</param>
/// <param name="projectService">The project service which is used to communicate with the logic layer.</param>
/// <param name="userService">The user service which is used to communicate with the logic layer.</param>
public EmbedController(IEmbedService embedService, IMapper mapper, IProjectService projectService, IUserService userService)
/// <param name="authorizationHelper">The authorization helper which is used to communicate with the authorization helper class.</param>
public EmbedController(IEmbedService embedService,
IMapper mapper,
IProjectService projectService,
IUserService userService,
IAuthorizationHelper authorizationHelper)
{
this.embedService = embedService;
this.mapper = mapper;
this.projectService = projectService;
this.userService = userService;
this.authorizationHelper = authorizationHelper;
}

/// <summary>
Expand All @@ -83,7 +89,7 @@ public async Task<IActionResult> GetAllEmbeddedProjects()
/// </summary>
/// <param name="guid">The unique identifier which is used for searching the embedded project.</param>
/// <returns>This method returns the project resource result.</returns>
/// <response code="200">This endpoint returns a embedded project with the specified guid.</response>
/// <response code="200">This endpoint returns an embedded project with the specified guid.</response>
/// <response code="400">The 400 Bad Request status code is returned when the guid is not specified.</response>
/// <response code="404">The 404 Not Found status code is returned when no project could be
/// found with the specified guid.</response>
Expand Down Expand Up @@ -179,8 +185,8 @@ public async Task<IActionResult> CreateEmbeddedProject(EmbeddedProjectResource e
}

string identity = HttpContext.User.GetIdentityId(HttpContext);
bool isAllowed = userService.UserHasScope(identity, nameof(Defaults.Scopes.EmbedWrite));
User user = await userService.GetUserByIdentityIdAsync(identity);
bool isAllowed = userService.UserHasScope(identity, nameof(Defaults.Scopes.EmbedWrite));

if(!(project.UserId == user.Id || isAllowed))
{
Expand Down Expand Up @@ -253,7 +259,11 @@ public async Task<IActionResult> DeleteEmbeddedProject(string guid)
}

string identity = HttpContext.User.GetIdentityId(HttpContext);
bool isAllowed = userService.UserHasScope(identity, nameof(Defaults.Scopes.EmbedWrite));
User user = await userService.GetUserByIdentityIdAsync(identity);
bool isAllowed = await authorizationHelper.UserIsAllowed(user,
nameof(Defaults.Scopes.EmbedWrite),
nameof(Defaults.Scopes.InstitutionEmbedWrite),
embeddedProject.UserId);

if(!(embeddedProject.User.IdentityId == identity || isAllowed))
{
Expand Down
Loading

0 comments on commit 653ed67

Please sign in to comment.