Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 00bc20f8

Přidáno uživatelem Dominik Chlouba před téměř 4 roky(ů)

Removed unused Azure AD project, updated identity core, custom authorization middleware - permission oriented authorization
ref #8556

Zobrazit rozdíly:

Leuze.sln
35 35
EndProject
36 36
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Leuze.Tests.Core.Domain", "tests\Core\Leuze.Tests.Core.Domain\Leuze.Tests.Core.Domain.csproj", "{8ECAEA01-61F3-402D-B94E-E54FC0C94C8E}"
37 37
EndProject
38
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Leuze.Core.Infrastructure.ActiveDirectory", "src\Core\Infrastructure\Leuze.Core.Infrastructure.ActiveDirectory\Leuze.Core.Infrastructure.ActiveDirectory.csproj", "{1407144F-48F6-404E-A890-961B739D030D}"
39
EndProject
40 38
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Leuze.Tests.Core.Infrastructure.ActiveDirectory", "tests\Core\Leuze.Tests.Core.Infrastructure.ActiveDirectory\Leuze.Tests.Core.Infrastructure.ActiveDirectory.csproj", "{C1813611-5FF2-4E70-B7E5-A4E8553F0B66}"
41 39
EndProject
42 40
Global
......
77 75
		{8ECAEA01-61F3-402D-B94E-E54FC0C94C8E}.Debug|Any CPU.Build.0 = Debug|Any CPU
78 76
		{8ECAEA01-61F3-402D-B94E-E54FC0C94C8E}.Release|Any CPU.ActiveCfg = Release|Any CPU
79 77
		{8ECAEA01-61F3-402D-B94E-E54FC0C94C8E}.Release|Any CPU.Build.0 = Release|Any CPU
80
		{1407144F-48F6-404E-A890-961B739D030D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
81
		{1407144F-48F6-404E-A890-961B739D030D}.Debug|Any CPU.Build.0 = Debug|Any CPU
82
		{1407144F-48F6-404E-A890-961B739D030D}.Release|Any CPU.ActiveCfg = Release|Any CPU
83
		{1407144F-48F6-404E-A890-961B739D030D}.Release|Any CPU.Build.0 = Release|Any CPU
84 78
		{C1813611-5FF2-4E70-B7E5-A4E8553F0B66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
85 79
		{C1813611-5FF2-4E70-B7E5-A4E8553F0B66}.Debug|Any CPU.Build.0 = Debug|Any CPU
86 80
		{C1813611-5FF2-4E70-B7E5-A4E8553F0B66}.Release|Any CPU.ActiveCfg = Release|Any CPU
......
102 96
		{D037B7D3-CA28-4EBD-9E2F-3F3D347950CF} = {C5588326-929D-42B3-912B-9D838373B48E}
103 97
		{B74BED5E-F175-4A6E-B4AC-8625E0E4E287} = {C5588326-929D-42B3-912B-9D838373B48E}
104 98
		{8ECAEA01-61F3-402D-B94E-E54FC0C94C8E} = {B74BED5E-F175-4A6E-B4AC-8625E0E4E287}
105
		{1407144F-48F6-404E-A890-961B739D030D} = {6A0F1F61-D0EB-4132-B722-5787D7046CC0}
106 99
		{C1813611-5FF2-4E70-B7E5-A4E8553F0B66} = {B74BED5E-F175-4A6E-B4AC-8625E0E4E287}
107 100
	EndGlobalSection
108 101
	GlobalSection(ExtensibilityGlobals) = postSolution
docs/Leuze.Core.Application.Identity.xml
68 68
            
69 69
            </summary>
70 70
        </member>
71
        <member name="P:Leuze.Core.Application.Identity.ApplicationRole.UserRoles">
71
        <member name="P:Leuze.Core.Application.Identity.ApplicationRole.Users">
72 72
            <summary>
73 73
            
74 74
            </summary>
......
90 90
            
91 91
            </summary>
92 92
        </member>
93
        <member name="M:Leuze.Core.Application.Identity.ApplicationRole.ChangeName(System.String)">
94
            <summary>
95
            
96
            </summary>
97
            <param name="name"></param>
98
        </member>
93 99
        <member name="T:Leuze.Core.Application.Identity.ApplicationRoleClaim">
94 100
            <summary>
95 101
            
......
105 111
            
106 112
            </summary>
107 113
        </member>
108
        <member name="M:Leuze.Core.Application.Identity.ApplicationUser.#ctor(System.String,System.String)">
114
        <member name="M:Leuze.Core.Application.Identity.ApplicationUser.#ctor(System.String,System.String,System.Boolean)">
109 115
            <summary>
110 116
            
111 117
            </summary>
112 118
            <param name="userName"></param>
113 119
            <param name="email"></param>
120
            <param name="isAdUser"></param>
114 121
        </member>
115
        <member name="P:Leuze.Core.Application.Identity.ApplicationUser.UserRoles">
122
        <member name="P:Leuze.Core.Application.Identity.ApplicationUser.IsAdUser">
123
            <summary>
124
            
125
            </summary>
126
        </member>
127
        <member name="P:Leuze.Core.Application.Identity.ApplicationUser.Roles">
116 128
            <summary>
117 129
            
118 130
            </summary>
......
147 159
            
148 160
            </summary>
149 161
        </member>
162
        <member name="T:Leuze.Core.Application.Identity.IApplicationUserProvider">
163
            <summary>
164
                An application service that provides currently authenticated user from presentation layer such as ASP.NET application or Console App.
165
            </summary>
166
        </member>
167
        <member name="P:Leuze.Core.Application.Identity.IApplicationUserProvider.UserId">
168
            <summary>
169
                The current user identifier.
170
            </summary>
171
        </member>
172
        <member name="P:Leuze.Core.Application.Identity.IApplicationUserProvider.User">
173
            <summary>
174
                The current user ClaimsPrincipal.
175
            </summary>
176
        </member>
177
        <member name="P:Leuze.Core.Application.Identity.IApplicationUserProvider.IsAuthenticated">
178
            <summary>
179
                Checks whether the user is authenticated.
180
            </summary>
181
        </member>
150 182
    </members>
151 183
</doc>
src/Core/Application/Leuze.Core.Application.Identity/ApplicationRole.cs
21 21
        /// <param name="name"></param>
22 22
        public ApplicationRole(string name) => (Name, NormalizedName) = (name, name.ToUpper());
23 23

  
24
        private List<ApplicationPermission> _permissions = new List<ApplicationPermission>();
25

  
24 26
        /// <summary>
25 27
        /// 
26 28
        /// </summary>
27
        public ICollection<ApplicationPermission> Permissions { get; private set; } = new List<ApplicationPermission>();
29
        public IReadOnlyCollection<ApplicationPermission> Permissions => _permissions.AsReadOnly();
30

  
31
        private List<ApplicationUser> _users = new List<ApplicationUser>();
28 32

  
29 33
        /// <summary>
30 34
        /// 
31 35
        /// </summary>
32
        public ICollection<ApplicationUserRole> UserRoles { get; private set; } = new List<ApplicationUserRole>();
36
        public IReadOnlyCollection<ApplicationUser> Users => _users.AsReadOnly();
33 37

  
34 38
        /// <summary>
35 39
        /// 
36 40
        /// </summary>
37 41
        /// <param name="permission"></param>
38
        public void AssignPermission(ApplicationPermission permission) => Permissions.Add(permission);
42
        public void AssignPermission(ApplicationPermission permission) => _permissions.Add(permission);
39 43

  
40 44
        /// <summary>
41 45
        /// 
42 46
        /// </summary>
43 47
        /// <param name="permission"></param>
44
        public void RemovePermission(ApplicationPermission permission) => Permissions.Remove(permission);
48
        public void RemovePermission(ApplicationPermission permission) => _permissions.Remove(permission);
45 49

  
46 50
        /// <summary>
47 51
        /// 
48 52
        /// </summary>
49
        public void ClearPermissions() => Permissions.Clear();
53
        public void ClearPermissions() => _permissions.Clear();
54

  
55
        /// <summary>
56
        /// 
57
        /// </summary>
58
        /// <param name="name"></param>
59
        public void ChangeName(string name) => (Name, NormalizedName) = (name, name.ToUpper());
50 60
    }
51 61
}
src/Core/Application/Leuze.Core.Application.Identity/ApplicationUser.cs
20 20
        /// </summary>
21 21
        /// <param name="userName"></param>
22 22
        /// <param name="email"></param>
23
        public ApplicationUser(string userName, string email) => (UserName, Email) = (userName, email);
23
        /// <param name="isAdUser"></param>
24
        public ApplicationUser(string userName, string email, bool isAdUser)
25
            => (UserName, Email, IsAdUser) = (userName, email, isAdUser);
24 26

  
25 27
        /// <summary>
26 28
        /// 
27 29
        /// </summary>
28
        public ICollection<ApplicationUserRole> UserRoles { get; private set; } = new List<ApplicationUserRole>();
30
        public bool IsAdUser { get; private set; }
31

  
32
        private List<ApplicationRole> _roles = new List<ApplicationRole>();
33

  
34
        /// <summary>
35
        /// 
36
        /// </summary>
37
        public IReadOnlyCollection<ApplicationRole> Roles => _roles.AsReadOnly();
29 38

  
30 39
    }
31 40
}
src/Core/Application/Leuze.Core.Application.Identity/ApplicationUserRole.cs
6 6
    /// <summary>
7 7
    /// 
8 8
    /// </summary>
9
    public sealed class ApplicationUserRole : IdentityUserRole<Guid>
9
    public class ApplicationUserRole : IdentityUserRole<Guid>
10 10
    {
11 11
        /// <summary>
12 12
        /// 
13 13
        /// </summary>
14
        public ApplicationUser User { get; set; } = null!;
14
        public virtual ApplicationUser User { get; set; } = null!;
15 15

  
16 16
        /// <summary>
17 17
        /// 
18 18
        /// </summary>
19
        public ApplicationRole Role { get; set; } = null!;
19
        public virtual ApplicationRole Role { get; set; } = null!;
20 20

  
21 21
    }
22 22
}
src/Core/Application/Leuze.Core.Application.Identity/IApplicationUserProvider.cs
1
using System.Security.Claims;
2

  
3
namespace Leuze.Core.Application.Identity
4
{
5
    /// <summary>
6
    ///     An application service that provides currently authenticated user from presentation layer such as ASP.NET application or Console App.
7
    /// </summary>
8
    public interface IApplicationUserProvider
9
    {
10
        /// <summary>
11
        ///     The current user identifier.
12
        /// </summary>
13
        string? UserId { get; }
14

  
15
        /// <summary>
16
        ///     The current user ClaimsPrincipal.
17
        /// </summary>
18
        public ClaimsPrincipal? User { get; }
19

  
20
        /// <summary>
21
        ///     Checks whether the user is authenticated.
22
        /// </summary>
23
        bool IsAuthenticated { get; }
24
    }
25
}
src/Core/Application/Leuze.Core.Application.UI/Leuze.Core.Application.UI.csproj
23 23

  
24 24
  <ItemGroup>
25 25
    <PackageReference Include="BlazorStyled" Version="3.1.0" />
26
    <PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0" />
26 27
  </ItemGroup>
27 28

  
28 29
  <ItemGroup>
src/Core/Application/Leuze.Core.Application.UI/Pages/Counter.razor
1
@page "/counter"
2

  
3
<h1>Counter</h1>
4

  
5
<p>Current count: @currentCount</p>
6

  
7
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
8

  
9
@code {
10
    private int currentCount = 0;
11

  
12
    private void IncrementCount()
13
    {
14
        currentCount++;
15
    }
16
}
src/Core/Application/Leuze.Core.Application.UI/Pages/Index.razor
1 1
@page "/"
2 2
@layout MainLayout
3
@attribute [Authorize]
3 4

  
4 5
<h1>Hello, world!</h1>
5 6

  
src/Core/Application/Leuze.Core.Application.UI/Shared/MainLayout.razor
1 1
@inherits LayoutComponentBase
2 2
@inject NavigationManager _navManager
3
@inject AuthenticationStateProvider AuthenticationStateProvider
3 4
<div class="top-row px-4">
4
    <img src="Resources/Icons/logo.svg" alt="logo" style="width:111px;height:28px;"/>
5
    <img src="Resources/Icons/sign-out.svg" style="width:18px;height:20px;"/>
5
    <img src="Resources/Icons/logo.svg" alt="logo" style="width:111px;height:28px;" />
6
    <div>
7
        @Name
8
        <a href="/MicrosoftIdentity/Account/SignOut">
9
            <img src="Resources/Icons/sign-out.svg" style="width:18px;height:20px;" />
10
        </a>
11
    </div>
6 12
</div>
7 13

  
8 14

  
......
11 17
        <NavMenu />
12 18
    </div>
13 19

  
14
        <div class="main">
15
            <div class="content px-4">
16
                @Body
17
            </div>
20
    <div class="main">
21
        <div class="content px-4">
22
            @Body
18 23
        </div>
19 24
    </div>
25
</div>
26

  
27
@code {        
20 28

  
21
@code {
29
    private string Name { get; set; } = string.Empty;
22 30

  
23
    /*protected override void OnAfterRender(bool firstRender)
31
    protected override async Task OnInitializedAsync()
24 32
    {
25
        base.OnAfterRender(firstRender);
26
        if (firstRender) _navManager.NavigateTo("account/login");
27
    }*/
33
        base.OnInitialized();
34
        var identity = await AuthenticationStateProvider.GetAuthenticationStateAsync();
35
        Name = identity.User.Identity!.Name!;
36
    }
28 37
}
src/Core/Application/Leuze.Core.Application/Authentication/ApplicationUserProvider.cs
1
using Leuze.Core.Application.Identity;
2
using Microsoft.AspNetCore.Http;
3
using System;
4
using System.Collections.Generic;
5
using System.Linq;
6
using System.Security.Claims;
7
using System.Text;
8
using System.Threading.Tasks;
9

  
10
namespace Leuze.Core.Application.Authentication
11
{
12
    /// <inheritdoc />
13
    public class ApplicationUserProvider : IApplicationUserProvider
14
    {
15
        /// <summary>
16
        ///     A public constructor with required http context accessor to get user claims.
17
        /// </summary>
18
        /// <param name="httpContextAccessor">The HTTP Context accessor.</param>
19
        public ApplicationUserProvider(IHttpContextAccessor httpContextAccessor)
20
        {
21
            UserId = httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier);
22
            User = httpContextAccessor.HttpContext?.User;
23
            IsAuthenticated = UserId != null;
24
        }
25

  
26
        /// <inheritdoc />
27
        public string? UserId { get; }
28

  
29
        /// <inheritdoc />
30
        public ClaimsPrincipal? User { get; }
31

  
32
        /// <inheritdoc />
33
        public bool IsAuthenticated { get; }
34
    }
35
}
src/Core/Application/Leuze.Core.Application/Authentication/DomainUserProvider.cs
1
namespace Leuze.Core.Application.Authentication
1
using Leuze.Core.Application.Identity;
2
using Leuze.Core.Domain.Domains.Users;
3
using Leuze.Core.Domain.Domains.Users.Services.Abstractions;
4
using Leuze.Core.Domain.Repositories;
5
using System;
6
using System.Threading.Tasks;
7

  
8
namespace Leuze.Core.Application.Authentication
2 9
{
3 10
    /// <inheritdoc />
4
    public class DomainUserProvider// : IDomainUserProvider
11
    public class DomainUserProvider : IDomainUserProvider
5 12
    {
6
        /*private readonly IApplicationUserProvider _userProvider;
7
        private readonly IStorage _unitOfWork;
13
        private readonly IApplicationUserProvider _userProvider;
14
        private readonly IDomainUserRepository _domainUserRepository;
8 15

  
9
        public DomainUserProvider(IApplicationUserProvider userProvider, IStorage unitOfWork)
16
        /// <summary>
17
        /// 
18
        /// </summary>
19
        /// <param name="userProvider"></param>
20
        /// <param name="domainUserRepository"></param>
21
        public DomainUserProvider(IApplicationUserProvider userProvider, IDomainUserRepository domainUserRepository)
10 22
        {
11 23
            _userProvider = userProvider;
12
            _unitOfWork = unitOfWork;
24
            _domainUserRepository = domainUserRepository;
13 25
        }
14 26

  
15 27
        /// <inheritdoc />
......
21 33
            if (CurrentUserId is null)
22 34
                return null;
23 35

  
24
            return null;
25
            //TODO: Implement
26
            //return await _unitOfWork.DomainUsers.FindAsync(CurrentUserId);
36
            return await _domainUserRepository.GetOptionalByIdAsync(CurrentUserId);
37
        }
38

  
39
        /// <inheritdoc />
40
        public async Task<DomainUser> GetRequiredCurrentUserAsync()
41
        {
42
            if (CurrentUserId is null)
43
                throw new UnauthorizedAccessException();
44

  
45
            var user = await _domainUserRepository.GetByIdAsync(CurrentUserId.Value);
46

  
47
            if (user is null)
48
                throw new UnauthorizedAccessException();
49

  
50
            return user;
27 51
        }
28 52

  
29 53
        /// <summary>
......
39 63
                return userId;
40 64

  
41 65
            return null;
42
        }*/
66
        }
43 67
    }
44 68
}
src/Core/Application/Leuze.Core.Application/Authentication/IApplicationUserProvider.cs
1
namespace Leuze.Core.Application.Authentication
2
{
3
    /// <summary>
4
    ///     An application service that provides currently authenticated user from presentation layer such as ASP.NET application or Console App.
5
    /// </summary>
6
    public interface IApplicationUserProvider
7
    {
8
        /*/// <summary>
9
        ///     The current user identifier.
10
        /// </summary>
11
        string? UserId { get; }
12

  
13
        /// <summary>
14
        ///     The current user ClaimsPrincipal.
15
        /// </summary>
16
        public ClaimsPrincipal? User { get; }
17

  
18
        /// <summary>
19
        ///     Checks whether the user is authenticated.
20
        /// </summary>
21
        bool IsAuthenticated { get; }*/
22
    }
23
}
src/Core/Application/Leuze.Core.Application/Authorization/PermissionAuthorizationHandler.cs
1
using Leuze.Core.Application.Identity;
2
using Microsoft.AspNetCore.Authorization;
3
using Microsoft.AspNetCore.Identity;
4
using System.Threading.Tasks;
5

  
6
namespace Leuze.Core.Application.Authorization
7
{
8
    /// <summary>
9
    /// Permission-based authorization handler.
10
    /// </summary>
11
    public class PermissionAuthorizationHandler : AuthorizationHandler<PermissionRequirement>
12
    {
13
        private readonly UserManager<ApplicationUser> _userManager;
14
        private readonly PermissionManager _permissionManager;
15

  
16
        /// <summary>
17
        /// Handler constructor with required dependencies.
18
        /// </summary>
19
        /// <param name="userManager">The user manager.</param>
20
        /// <param name="permissionManager">The permission manager.</param>
21
        public PermissionAuthorizationHandler(UserManager<ApplicationUser> userManager, PermissionManager permissionManager)
22
            => (_userManager, _permissionManager) = (userManager, permissionManager);
23

  
24
        /// <inheritdoc />
25
        protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
26
        {
27
            if (context.User.Identity is null || !context.User.Identity.IsAuthenticated)
28
            {
29
                context.Fail();
30
                return;
31
            }
32

  
33
            // Get all the roles the user belongs to and check if any of the roles has the permission required
34
            // for the authorization to succeed.
35
            var user = await _userManager.GetUserAsync(context.User);
36
            if (user is null)
37
            {
38
                context.Fail();
39
                return;
40
            }
41

  
42
            var hasPermission = await _permissionManager.HasPermissionAsync(user.Id, requirement.PermissionName);
43
            if (hasPermission) context.Succeed(requirement);
44
            else context.Fail();
45
        }
46
    }
47
}
src/Core/Application/Leuze.Core.Application/Authorization/PermissionManager.cs
1
using Leuze.Core.Domain.Repositories;
2
using System;
3
using System.Threading.Tasks;
4

  
5
namespace Leuze.Core.Application.Authorization
6
{
7
    /// <summary>
8
    /// 
9
    /// </summary>
10
    public class PermissionManager
11
    {
12
        private readonly IUserRepository _userRepository;
13

  
14
        /// <summary>
15
        /// 
16
        /// </summary>
17
        /// <param name="userRepository"></param>
18
        public PermissionManager(IUserRepository userRepository)
19
            => _userRepository = userRepository;
20

  
21
        /// <summary>
22
        /// 
23
        /// </summary>
24
        /// <param name="id"></param>
25
        /// <param name="permission"></param>
26
        /// <returns></returns>
27
        public async Task<bool> HasPermissionAsync(Guid id, string permission)
28
            => await _userRepository.HasPermissionAsync(id, permission);
29

  
30
    }
31
}
src/Core/Application/Leuze.Core.Application/Authorization/PermissionPolicyProvider.cs
1
using Microsoft.AspNetCore.Authorization;
2
using Microsoft.Extensions.Options;
3
using System;
4
using System.Threading.Tasks;
5

  
6
namespace Leuze.Core.Application.Authorization
7
{
8
    /// <summary>
9
    ///     Authorization policy provider for permission based authorization.
10
    /// <para>
11
    ///     Provider creates policies dynamically when the permission policies are used.
12
    /// </para>
13
    /// </summary>
14
    public class PermissionPolicyProvider : IAuthorizationPolicyProvider
15
    {
16
        /// <summary>
17
        ///     Fallback authorization policy provider.
18
        /// </summary>
19
        public DefaultAuthorizationPolicyProvider FallbackPolicyProvider { get; }
20

  
21
        /// <summary>
22
        ///     Creates an permission policy provider that creates policies dynamically based on permission in the application.
23
        /// </summary>
24
        /// <param name="options">Authorization configuration.</param>
25
        public PermissionPolicyProvider(IOptions<AuthorizationOptions> options)
26
            => FallbackPolicyProvider = new DefaultAuthorizationPolicyProvider(options);
27

  
28
        /// <inheritdoc />
29
        public Task<AuthorizationPolicy> GetDefaultPolicyAsync() => FallbackPolicyProvider.GetDefaultPolicyAsync();
30

  
31
        /// <inheritdoc />
32
        public Task<AuthorizationPolicy?> GetFallbackPolicyAsync() => FallbackPolicyProvider.GetFallbackPolicyAsync();
33

  
34
        /// <inheritdoc />
35
        public Task<AuthorizationPolicy?> GetPolicyAsync(string policyName)
36
        {
37
            if (policyName.StartsWith("PRIVILEGE.", StringComparison.OrdinalIgnoreCase))
38
            {
39
                var policy = new AuthorizationPolicyBuilder();
40
                policy.AddRequirements(new PermissionRequirement(policyName.Replace("PRIVILEGE.", "")));
41
                return Task.FromResult(policy.Build())!;
42
            }
43

  
44
            // Policy is not for permissions, try the default provider.
45
            return FallbackPolicyProvider.GetPolicyAsync(policyName);
46
        }
47
    }
48
}
src/Core/Application/Leuze.Core.Application/Authorization/PermissionRequirement.cs
1
using Microsoft.AspNetCore.Authorization;
2

  
3
namespace Leuze.Core.Application.Authorization
4
{
5
    /// <summary>
6
    ///     Authorization requirement for permissions in the system.
7
    /// </summary>
8
    public class PermissionRequirement : IAuthorizationRequirement
9
    {
10
        /// <summary>
11
        ///     Initializes permission requirement with the permission name.
12
        /// </summary>
13
        /// <param name="permissionName">The permission name.</param>
14
        public PermissionRequirement(string permissionName)
15
            => PermissionName = permissionName;
16

  
17
        /// <summary>
18
        ///     The permission name.
19
        /// </summary>
20
        public string PermissionName { get; private set; }
21
    }
22
}
src/Core/Application/Leuze.Core.Application/CQRS/Auth/Commads/VerifyAdUser.cs
1
using Leuze.Core.Application.Identity;
2
using Leuze.Core.Domain.Domains.Users;
3
using Leuze.Core.Domain.Repositories;
4
using Microsoft.AspNetCore.Identity;
5
using System;
6
using System.Collections.Generic;
7
using System.Linq;
8
using System.Text;
9
using System.Threading;
10
using System.Threading.Tasks;
11

  
12
namespace Leuze.Core.Application.CQRS.Auth.Commands
13
{
14
    /// <summary>
15
    /// 
16
    /// </summary>
17
    public static class VerifyAdUser
18
    {
19
        /// <summary>
20
        /// 
21
        /// </summary>
22
        public record Command(string Email, string Name) : IBaseRequest<Response>;
23

  
24
        /// <summary>
25
        /// 
26
        /// </summary>
27
        public record Response(ApplicationUser User);
28

  
29
        /// <summary>
30
        /// 
31
        /// </summary>
32
        public class Handler : IBaseRequestHandler<Command, Response>
33
        {
34
            private readonly IUserRepository _userRepository;
35
            private readonly IDomainUserRepository _domainUserRepository;
36

  
37
            /// <summary>
38
            /// 
39
            /// </summary>
40
            /// <param name="userRepository"></param>
41
            /// <param name="domainUserRepository"></param>
42
            /// <param name="userManager"></param>
43
            public Handler(IUserRepository userRepository, IDomainUserRepository domainUserRepository)
44
                => (_userRepository, _domainUserRepository) = (userRepository, domainUserRepository);
45

  
46
            /// <summary>
47
            /// 
48
            /// </summary>
49
            /// <param name="request"></param>
50
            /// <param name="cancellationToken"></param>
51
            /// <returns></returns>
52
            public async Task<RequestResponse<Response>> Handle(Command request, CancellationToken cancellationToken)
53
            {
54
                var user = await _userRepository.GetAdByEmailAsync(request.Email);
55

  
56
                if(user is not null)
57
                {
58
                    var domainUser = await _domainUserRepository.GetByIdAsync(user.Id);
59

  
60
                    if (domainUser is null) return RequestResponse<Response>.CreateErrorResponse($"Domain user with ID '{user.Id}' not found");
61
                    if(domainUser.Name.FullName != request.Name)
62
                    {
63
                        domainUser.ChangeName(new(request.Name));
64
                        await _domainUserRepository.UpdateAsync(domainUser);
65
                    }
66
                    return RequestResponse<Response>.CreateSuccessResponse(new(user));
67
                }
68

  
69
                var canCreate = await _userRepository.CanCreateByEmailAsync(request.Email);
70
                if(!canCreate) return RequestResponse<Response>.CreateErrorResponse($"User with email '{request.Email}' already exists");
71

  
72
                user = new(request.Email, request.Email, true);
73
                await _userRepository.AddAsync(user);
74

  
75
                // Have to be loaded with Leuze DB context - otherwise want to create duplicate record in DB, but user must be created using UserManager (it's safe)
76
                user = await _userRepository.GetAdByEmailAsync(request.Email);
77

  
78
                DomainUser newDomainUser = new(user, new(request.Name), new(request.Email));
79
                await _domainUserRepository.AddAsync(newDomainUser);
80

  
81
                return RequestResponse<Response>.CreateSuccessResponse(new(user));
82
            }
83
        }
84

  
85
    }
86
}
src/Core/Application/Leuze.Core.Application/CQRS/Auth/Commads/VerifyLocalUser.cs
1
using Leuze.Core.Application.Identity;
2
using Microsoft.AspNetCore.Identity;
3
using System;
4
using System.Collections.Generic;
5
using System.Linq;
6
using System.Text;
7
using System.Threading;
8
using System.Threading.Tasks;
9

  
10
namespace Leuze.Core.Application.CQRS.Auth.Commads
11
{
12
    /// <summary>
13
    /// 
14
    /// </summary>
15
    public static class VerifyLocalUser
16
    {
17
        /// <summary>
18
        /// 
19
        /// </summary>
20
        public record Command(string Email, string Password) : IBaseRequest<Response>;
21

  
22
        /// <summary>
23
        /// 
24
        /// </summary>
25
        public record Response();
26

  
27
        /// <summary>
28
        /// 
29
        /// </summary>
30
        public class Handler : IBaseRequestHandler<Command, Response>
31
        {
32
            private readonly SignInManager<ApplicationUser> _signInManager;
33
            private readonly UserManager<ApplicationUser> _userManager;
34

  
35
            /// <summary>
36
            /// 
37
            /// </summary>
38
            /// <param name="signInManager"></param>
39
            /// <param name="userManager"></param>
40
            public Handler(SignInManager<ApplicationUser> signInManager, UserManager<ApplicationUser> userManager)
41
                => (_signInManager, _userManager) = (signInManager, userManager);
42

  
43
            /// <summary>
44
            /// 
45
            /// </summary>
46
            /// <param name="request"></param>
47
            /// <param name="cancellationToken"></param>
48
            /// <returns></returns>
49
            public async Task<RequestResponse<Response>> Handle(Command request, CancellationToken cancellationToken)
50
            {
51
                var user = await _userManager.FindByEmailAsync(request.Email);
52
                if (user is null)
53
                    return RequestResponse<Response>.CreateErrorResponse($"Invalid email or password");
54

  
55
                var result = await _signInManager.CheckPasswordSignInAsync(user, request.Password, false);
56
                if(!result.Succeeded)
57
                    return RequestResponse<Response>.CreateErrorResponse($"Invalid email or password");
58

  
59
                await _signInManager.SignInAsync(user, true);
60

  
61
                return RequestResponse<Response>.CreateSuccessResponse(new());
62
            }
63
        }
64

  
65
    }
66
}
src/Core/Application/Leuze.Core.Application/CQRS/Users/Commands/CreateLocalUser.cs
1
using Leuze.Core.Application.Configuration;
2
using Leuze.Core.Application.Identity;
3
using Leuze.Core.Domain.Domains.Users;
4
using Leuze.Core.Domain.Repositories;
5
using Microsoft.AspNetCore.Http;
6
using Microsoft.AspNetCore.Identity;
7
using Microsoft.AspNetCore.Identity.UI.Services;
8
using Microsoft.Extensions.Options;
9
using System;
10
using System.Collections.Generic;
11
using System.Threading;
12
using System.Threading.Tasks;
13

  
14
namespace Leuze.Core.Application.CQRS.Users.Commands
15
{
16
    /// <summary>
17
    /// 
18
    /// </summary>
19
    public static class CreateLocalUser
20
    {
21
        /// <summary>
22
        /// 
23
        /// </summary>
24
        public record Command(string Name, string Email, Guid? SeniorUserId, IList<Guid> Roles) : IBaseRequest<Response>;
25

  
26
        /// <summary>
27
        /// 
28
        /// </summary>
29
        public record Response();
30

  
31
        /// <summary>
32
        /// 
33
        /// </summary>
34
        public class Handler : IBaseRequestHandler<Command, Response>
35
        {
36
            private readonly IDomainUserRepository _domainUserRepository;
37
            private readonly IUserRepository _userRepository;
38
            private readonly UserManager<ApplicationUser> _userManager;
39
            private readonly AppSettings _appSettings;
40
            private readonly IHttpContextAccessor _httpContextAccessor;
41

  
42
            /// <summary>
43
            /// 
44
            /// </summary>
45
            /// <param name="domainUserRepository"></param>
46
            /// <param name="userManager"></param>
47
            /// <param name="emailSender"></param>
48
            /// <param name="options"></param>
49
            /// <param name="httpContextAccessor"></param>
50
            /// <param name="userRepository"></param>
51
            public Handler(IDomainUserRepository domainUserRepository, UserManager<ApplicationUser> userManager,
52
                IOptions<AppSettings> options, IHttpContextAccessor httpContextAccessor, IUserRepository userRepository)
53
                => (_domainUserRepository, _userManager, _appSettings, _httpContextAccessor, _userRepository)
54
                        = (domainUserRepository, userManager, options.Value, httpContextAccessor, userRepository);
55

  
56
            /// <summary>
57
            /// 
58
            /// </summary>
59
            /// <param name="request"></param>
60
            /// <param name="cancellationToken"></param>
61
            /// <returns></returns>
62
            public async Task<RequestResponse<Response>> Handle(Command request, CancellationToken cancellationToken)
63
            {
64
                var user = await _userManager.FindByEmailAsync(request.Email);
65
                if (user is not null)
66
                    return RequestResponse<Response>.CreateErrorResponse($"User with email '{request.Email}' already exists");
67

  
68
                user = new ApplicationUser(request.Email, request.Email, false);
69
                var result = await _userManager.CreateAsync(user);
70
                if (!result.Succeeded)
71
                    return RequestResponse<Response>.CreateErrorResponse($"User with username '{request.Email}' failed to create");
72

  
73
                user = await _userRepository.GetByIdAsync(user.Id);
74

  
75
                DomainUser? senior = null!;
76
                if (request.SeniorUserId.HasValue) senior = await _domainUserRepository.GetOptionalByIdAsync(request.SeniorUserId);
77

  
78
                DomainUser domainUser = new(user, new(request.Name), new(request.Email));
79

  
80
                await _domainUserRepository.AddAsync(domainUser);
81

  
82
                var resetToken = await _userManager.GeneratePasswordResetTokenAsync(user);
83

  
84
                /*await _emailSender.SendAsync(new NewUserTemplate(
85
                    null!,
86
                    new MailAddress(domainUser.Email.GetEmailAddress()),
87
                    "Vytvořen účet - Leuze",
88
                    new() { ResetLink = $"{_httpContextAccessor.HttpContext!.Request.Scheme}://{_httpContextAccessor.HttpContext!.Request.Host}/{_appSettings.Authentication.ResetUrl}/?token={resetToken}&user={user.Email}" }
89
                ));*/
90

  
91
                return RequestResponse<Response>.CreateSuccessResponse(new());
92
            }
93
        }
94

  
95
    }
96
}
src/Core/Application/Leuze.Core.Application/CQRS/Users/Queries/GetFilteredUsers.cs
1
using Leuze.Core.Domain.Domains.Users.DTOs;
2
using Leuze.Core.Domain.Repositories;
3
using System;
4
using System.Collections.Generic;
5
using System.Linq;
6
using System.Text;
7
using System.Threading;
8
using System.Threading.Tasks;
9

  
10
namespace Leuze.Core.Application.CQRS.Users.Queries
11
{
12
    /// <summary>
13
    /// 
14
    /// </summary>
15
    public static class GetFilteredUsers
16
    {
17
        /// <summary>
18
        /// 
19
        /// </summary>
20
        public record Query(int PageNumber, int PageSize) : IBaseRequest<Response>;
21

  
22
        /// <summary>
23
        /// 
24
        /// </summary>
25
        public record Response(List<UserDto> List, int Total);
26

  
27
        /// <summary>
28
        /// 
29
        /// </summary>
30
        public class Handler : IBaseRequestHandler<Query, Response>
31
        {
32
            private readonly IDomainUserRepository _domainUserRepository;
33

  
34
            /// <summary>
35
            /// 
36
            /// </summary>
37
            /// <param name="domainUserRepository"></param>
38
            public Handler(IDomainUserRepository domainUserRepository)
39
                => (_domainUserRepository) = (domainUserRepository);
40

  
41
            /// <summary>
42
            /// 
43
            /// </summary>
44
            /// <param name="request"></param>
45
            /// <param name="cancellationToken"></param>
46
            /// <returns></returns>
47
            public async Task<RequestResponse<Response>> Handle(Query request, CancellationToken cancellationToken)
48
            {
49
                var result = await _domainUserRepository.GetFilteredListAsync(request.PageNumber, request.PageSize);
50
                return RequestResponse<Response>.CreateSuccessResponse(new(result.List, result.Total));
51
            }
52
        }
53

  
54
    }
55
}
src/Core/Application/Leuze.Core.Application/Configuration/Actions.cs
16 16
using Microsoft.AspNetCore.Authorization;
17 17
using Microsoft.AspNetCore.Mvc.Authorization;
18 18
using Microsoft.Identity.Web.UI;
19
using System.Threading.Tasks;
20
using System.Security.Claims;
21
using Microsoft.AspNetCore.Authentication;
22
using Microsoft.AspNetCore.Authentication.Cookies;
23
using Microsoft.AspNetCore.Http;
24
using Leuze.Core.Application.Identity;
25
using Microsoft.AspNetCore.Identity;
26
using Leuze.Core.Domain.Repositories;
27
using Leuze.Core.Application.CQRS.Auth.Commands;
28
using Leuze.Core.Application.Configuration.Extensions;
19 29

  
20 30
namespace Leuze.Core.Application.Configuration
21 31
{
......
51 61

  
52 62
            applicationBuilder.UseHttpsRedirection();
53 63
            applicationBuilder.UseStaticFiles();
54
            applicationBuilder.UseCookiePolicy();
55 64
            applicationBuilder.UseRouting();
56 65
            applicationBuilder.UseAuthentication();
57 66
            applicationBuilder.UseAuthorization();
......
94 103
            appSettingsSection.Bind(appSettings);
95 104
            services.Configure<AppSettings>(appSettingsSection);
96 105

  
97
            services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
98
                .AddMicrosoftIdentityWebApp(configuration.GetSection("AzureAd"));
106
            services.AddAzureAdAuthentication(configuration);
99 107
            services.AddControllersWithViews()
100 108
                .AddMicrosoftIdentityUI();
101 109

  
102
            // Options with default policy causes infinite redirect
103
            services.AddAuthorization();
110
            services.AddCustomAuthorization();
104 111
            services.AddRazorPages();
105 112
            services.AddServerSideBlazor()
106 113
                .AddMicrosoftIdentityConsentHandler();
src/Core/Application/Leuze.Core.Application/Configuration/Extensions/CustomAuthenticationExtensions.cs
1
using Leuze.Core.Application.Authentication;
2
using Leuze.Core.Application.CQRS.Auth.Commands;
3
using Leuze.Core.Application.Identity;
4
using Leuze.Core.Domain.Domains.Users.Services.Abstractions;
5
using MediatR;
6
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
7
using Microsoft.AspNetCore.Identity;
8
using Microsoft.Extensions.Configuration;
9
using Microsoft.Extensions.DependencyInjection;
10
using Microsoft.Identity.Web;
11
using Serilog;
12
using System;
13
using System.Linq;
14
using System.Security.Claims;
15
using System.Threading.Tasks;
16

  
17
namespace Leuze.Core.Application.Configuration.Extensions
18
{
19
    /// <summary>
20
    /// 
21
    /// </summary>
22
    public static class CustomAuthenticationExtensions
23
    {
24
        /// <summary>
25
        /// 
26
        /// </summary>
27
        /// <param name="services"></param>
28
        /// <param name="configuration"></param>
29
        public static void AddAzureAdAuthentication(this IServiceCollection services, IConfiguration configuration)
30
        {
31
            services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
32
                .AddMicrosoftIdentityWebApp(options =>
33
                {
34
                    configuration.Bind("AzureAd", options);
35
                    options.Events = new OpenIdConnectEvents
36
                    {
37
                        OnRedirectToIdentityProvider = async ctxt =>
38
                        {
39
                            await Task.Yield();
40
                        },
41
                        OnAuthenticationFailed = async ctxt =>
42
                        {
43
                            await Task.Yield();
44
                        },
45
                        OnTicketReceived = async ctxt =>
46
                        {
47
                            if (ctxt.Principal?.Identity is ClaimsIdentity identity)
48
                            {
49
                                var manager = ctxt.HttpContext.RequestServices.GetRequiredService<SignInManager<ApplicationUser>>();
50
                                var mediator = ctxt.HttpContext.RequestServices.GetRequiredService<IMediator>();
51

  
52
                                var result = await mediator.Send(new VerifyAdUser.Command(identity.Name!, identity.Claims.Single(o => o.Type == "name").Value));
53

  
54
                                if (result.IsSuccess && result.Result is not null)
55
                                    await manager.SignInAsync(result.Result.User, true);
56
                            }
57
                            await Task.Yield();
58
                        },
59
                        OnRedirectToIdentityProviderForSignOut = async ctxt =>
60
                        {
61
                            var manager = ctxt.HttpContext.RequestServices.GetRequiredService<SignInManager<ApplicationUser>>();
62
                            await manager.SignOutAsync();
63
                            await Task.Yield();
64
                        }
65
                    };
66
                });
67

  
68
            services.AddScoped<IDomainUserProvider, DomainUserProvider>();
69
            services.AddScoped<IApplicationUserProvider, ApplicationUserProvider>();
70
        }
71

  
72
    }
73
}
src/Core/Application/Leuze.Core.Application/Configuration/Extensions/CustomAuthorizationExtensions.cs
1
using Leuze.Core.Application.Authorization;
2
using Microsoft.AspNetCore.Authorization;
3
using Microsoft.Extensions.DependencyInjection;
4

  
5
namespace Leuze.Core.Application.Configuration.Extensions
6
{
7
    /// <summary>
8
    /// 
9
    /// </summary>
10
    public static class CustomAuthorizationExtensions
11
    {
12

  
13
        /// <summary>
14
        ///     Configures authorization policies.
15
        /// </summary>
16
        /// <param name="services">The service collection.</param>
17
        public static void AddCustomAuthorization(this IServiceCollection services)
18
        {
19
            services.AddAuthorization();
20

  
21
            services.AddTransient<PermissionManager>();
22
            services.AddSingleton<IAuthorizationPolicyProvider, PermissionPolicyProvider>();
23
            services.AddScoped<IAuthorizationHandler, PermissionAuthorizationHandler>();
24
        }
25

  
26
    }
27
}
src/Core/Application/Leuze.Core.Application/Leuze.Core.Application.csproj
19 19
  </PropertyGroup>
20 20

  
21 21
  <ItemGroup>
22
    <Folder Include="Authorization\" />
23 22
    <Folder Include="CQRS\Roles\Queries\" />
24 23
  </ItemGroup>
25 24

  
......
38 37
    <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="5.0.5" />
39 38
    <PackageReference Include="Microsoft.Identity.Web" Version="1.8.2" />
40 39
    <PackageReference Include="Microsoft.Identity.Web.UI" Version="1.8.2" />
40
    <PackageReference Include="Serilog" Version="2.10.0" />
41 41
  </ItemGroup>
42 42

  
43 43
  <ItemGroup>
src/Core/Domain/Leuze.Core.Domain/Domains/Shared/ValueObjects/PersonFullName.cs
13 13
        /// <summary>
14 14
        ///     Creates a <see cref="PersonFullName"/> with required properties.
15 15
        /// </summary>
16
        /// <param name="firstName">The first name.</param>
17
        /// <param name="lastName">The last name.</param>
18
        public PersonFullName(string firstName, string lastName) => (FirstName, LastName) = (firstName, lastName);
16
        /// <param name="fullName">The full name.</param>
17
        public PersonFullName(string fullName) => (FullName) = (fullName);
19 18

  
20 19
        /// <summary>
21
        ///     The first name.
20
        ///     The full name.
22 21
        /// </summary>
23
        public string FirstName { get; private set; } = null!;
24

  
25
        /// <summary>
26
        ///     The last name.
27
        /// </summary>
28
        public string LastName { get; private set; } = null!;
22
        public string FullName { get; private set; } = null!;
29 23

  
30 24
        /// <summary>
31 25
        ///     Gets the full name of the person.
32 26
        /// </summary>
33 27
        /// <returns>The full name.</returns>
34
        public override string ToString() => $"{FirstName} {LastName}";
28
        public override string ToString() => $"{FullName}";
35 29

  
36 30
        /// <summary>
37 31
        ///     Gets a full name.
src/Core/Domain/Leuze.Core.Domain/Domains/Users/DTOs/UserDto.cs
1
using System;
2

  
3
namespace Leuze.Core.Domain.Domains.Users.DTOs
4
{
5
    /// <summary>
6
    /// 
7
    /// </summary>
8
    public record UserDto(Guid Id, string Name, string Email, bool IsAdUser);
9
}
src/Core/Domain/Leuze.Core.Domain/Domains/Users/DomainUser.cs
1 1
using Leuze.Core.Application.Identity;
2
using Leuze.Core.Domain.Domains.Shared.ValueObjects;
2 3
using System;
3 4

  
4 5
namespace Leuze.Core.Domain.Domains.Users
......
18 19

  
19 20
#pragma warning restore 8618
20 21

  
21
        private DomainUser(Guid userId) => (UserId) = (userId);
22

  
23 22
        /// <summary>
24 23
        /// 
25 24
        /// </summary>
26
        /// <param name="userId"></param>
27
        /// <returns></returns>
28
        public static DomainUser NewUser(Guid userId) => new(userId);
25
        /// <param name="user"></param>
26
        /// <param name="name"></param>
27
        /// <param name="email"></param>
28
        public DomainUser(ApplicationUser user, PersonFullName name, EmailAddress email)
29
            => (UserId, User, EmailAddress, Name) = (user.Id, user, email, name);
29 30

  
30 31

  
31 32
        /// <summary>
......
37 38
        /// 
38 39
        /// </summary>
39 40
        public ApplicationUser User { get; private set; } = null!;
41

  
42
        /// <summary>
43
        /// 
44
        /// </summary>
45
        public PersonFullName Name { get; private set; }
46

  
47
        /// <summary>
48
        /// 
49
        /// </summary>
50
        public EmailAddress EmailAddress { get; private set; }
51

  
52
        /// <summary>
53
        /// 
54
        /// </summary>
55
        /// <param name="name"></param>
56
        public void ChangeName(PersonFullName name) => Name = name;
40 57
    }
41 58
}
src/Core/Domain/Leuze.Core.Domain/Leuze.Core.Domain.csproj
28 28
    <ProjectReference Include="..\..\Application\Leuze.Core.Application.Identity\Leuze.Core.Application.Identity.csproj" />
29 29
  </ItemGroup>
30 30

  
31
  <ItemGroup>
32
    <Folder Include="Services\" />
33
  </ItemGroup>
34

  
31 35
</Project>
src/Core/Domain/Leuze.Core.Domain/Repositories/IDomainUserRepository.cs
1
using ExtCore.Data.Abstractions;
2
using Leuze.Core.Domain.Domains.Users;
3
using Leuze.Core.Domain.Domains.Users.DTOs;
4
using System;
5
using System.Collections.Generic;
6
using System.Threading.Tasks;
7

  
8
namespace Leuze.Core.Domain.Repositories
9
{
10
    /// <summary>
11
    /// 
12
    /// </summary>
13
    public interface IDomainUserRepository : IRepository
14
    {
15
        /// <summary>
16
        /// 
17
        /// </summary>
18
        /// <param name="id"></param>
19
        /// <returns></returns>
20
        Task<DomainUser> GetByIdAsync(Guid id);
21

  
22
        /// <summary>
23
        /// 
24
        /// </summary>
25
        /// <param name="domainUser"></param>
26
        /// <returns></returns>
27
        Task AddAsync(DomainUser domainUser);
28

  
29
        /// <summary>
30
        /// 
31
        /// </summary>
32
        /// <param name="domainUser"></param>
33
        /// <returns></returns>
34
        Task UpdateAsync(DomainUser domainUser);
35

  
36
        /// <summary>
37
        /// 
38
        /// </summary>
39
        /// <param name="pageNumber"></param>
40
        /// <param name="pageSize"></param>
41
        /// <returns></returns>
42
        Task<(List<UserDto> List, int Total)> GetFilteredListAsync(int pageNumber, int pageSize);
43

  
44
        /// <summary>
45
        /// 
46
        /// </summary>
47
        /// <param name="currentUserId"></param>
48
        /// <returns></returns>
49
        Task<DomainUser?> GetOptionalByIdAsync(Guid? currentUserId);
50
    }
51
}
src/Core/Domain/Leuze.Core.Domain/Repositories/IUserRepository.cs
1 1
using ExtCore.Data.Abstractions;
2
using Leuze.Core.Application.Identity;
3
using System;
4
using System.Threading.Tasks;
2 5

  
3 6
namespace Leuze.Core.Domain.Repositories
4 7
{
......
7 10
    /// </summary>
8 11
    public interface IUserRepository : IRepository
9 12
    {
13
        /// <summary>
14
        /// 
15
        /// </summary>
16
        /// <param name="entity"></param>
17
        /// <returns></returns>
18
        Task AddAsync(ApplicationUser entity);
19

  
20
        /// <summary>
21
        /// 
22
        /// </summary>
23
        /// <param name="email"></param>
24
        /// <returns></returns>
25
        Task<ApplicationUser> GetAdByEmailAsync(string email);
26

  
27
        /// <summary>
28
        /// 
29
        /// </summary>
30
        /// <param name="email"></param>
31
        /// <returns></returns>
32
        Task<bool> CanCreateByEmailAsync(string email);
33

  
34
        /// <summary>
35
        /// 
36
        /// </summary>
37
        /// <param name="id"></param>
38
        /// <param name="permission"></param>
39
        /// <returns></returns>
40
        Task<bool> HasPermissionAsync(Guid id, string permission);
41

  
42
        /// <summary>
43
        /// 
44
        /// </summary>
45
        /// <param name="id"></param>
46
        /// <returns></returns>
47
        Task<ApplicationUser> GetByIdAsync(Guid id);
10 48
    }
11 49
}
src/Core/Domain/Leuze.Core.Domain/Services/IActiveDirectory.cs
1
namespace Leuze.Core.Domain.Services
2
{
3
    /// <summary>
4
    /// 
5
    /// </summary>
6
    public interface IActiveDirectory
7
    {
8
    }
9
}
src/Core/Infrastructure/Leuze.Core.Infrastructure.ActiveDirectory/DependencyInjection.cs
1
using ExtCore.Infrastructure.Actions;
2
using Leuze.Core.Domain.Services;
3
using Leuze.Core.Infrastructure.ActiveDirectory.Services;
4
using Microsoft.AspNetCore.Builder;
5
using Microsoft.Extensions.DependencyInjection;
6
using System;
7

  
8
namespace Leuze.Core.Infrastructure.ActiveDirectory
9
{
10
    /// <summary>
11
    /// 
12
    /// </summary>
13
    public class ServicesConfiguration : IConfigureServicesAction
14
    {
15
        /// <summary>
16
        /// 
17
        /// </summary>
18
        public int Priority => 1000;
19

  
20
        /// <summary>
21
        /// 
22
        /// </summary>
23
        /// <param name="services"></param>
24
        /// <param name="serviceProvider"></param>
25
        public void Execute(IServiceCollection services, IServiceProvider serviceProvider)
26
        {
27
            services.AddTransient<IActiveDirectory, AdService>();
28
        }
29
    }
30

  
31
    /// <summary>
32
    /// 
33
    /// </summary>
34
    public class ApplicationConfiguration : IConfigureAction
35
    {
36
        /// <summary>
37
        /// 
38
        /// </summary>
39
        public int Priority => 11000;
40

  
41
        /// <summary>
42
        /// 
43
        /// </summary>
44
        /// <param name="applicationBuilder"></param>
45
        /// <param name="serviceProvider"></param>
46
        public void Execute(IApplicationBuilder applicationBuilder, IServiceProvider serviceProvider)
47
        {
48
        }
49
    }
50
}
src/Core/Infrastructure/Leuze.Core.Infrastructure.ActiveDirectory/Leuze.Core.Infrastructure.ActiveDirectory.csproj
1
<Project Sdk="Microsoft.NET.Sdk">
2

  
3
  <PropertyGroup>
4
    <AssemblyName>Leuze.Core.Infrastructure.ActiveDirectory</AssemblyName>
5
    <RootNamespace>Leuze.Core.Infrastructure.ActiveDirectory</RootNamespace>
6
    <Product></Product>
7
    <Description></Description>
8
  </PropertyGroup>
9

  
10
  <PropertyGroup>
11
    <TargetFramework>net5.0</TargetFramework>
12
    <Nullable>enable</Nullable>
13
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
14
  </PropertyGroup>
15

  
16
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
17
    <OutputPath>..\..\..\Presentation\Leuze.Modules\</OutputPath>
18
    <DocumentationFile>..\..\..\..\docs\Leuze.Core.Infrastructure.ActiveDirectory.xml</DocumentationFile>
19
  </PropertyGroup>
20

  
21
  <ItemGroup>
22
    <PackageReference Include="ExtCore.Infrastructure" Version="6.0.0" />
23
  </ItemGroup>
24
  
25
  <ItemGroup>
26
    <ProjectReference Include="..\..\Domain\Leuze.Core.Domain\Leuze.Core.Domain.csproj" />
27
  </ItemGroup>
28

  
29
</Project>
src/Core/Infrastructure/Leuze.Core.Infrastructure.ActiveDirectory/Services/AdService.cs
1
using Leuze.Core.Domain.Services;
... Rozdílový soubor je zkrácen, protože jeho délka přesahuje max. limit.

Také k dispozici: Unified diff