1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
|
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Timeline.Entities;
using Timeline.Services.Exceptions;
namespace Timeline.Services
{
public enum UserPermission
{
/// <summary>
/// This permission allows to manage user (creating, deleting or modifying).
/// </summary>
UserManagement,
/// <summary>
/// This permission allows to view and modify all timelines.
/// </summary>
AllTimelineManagement,
/// <summary>
/// This permission allow to add or remove highlight timelines.
/// </summary>
HighlightTimelineManangement
}
/// <summary>
/// Represents a user's permissions.
/// </summary>
public class UserPermissions : IEnumerable<UserPermission>
{
public static UserPermissions AllPermissions { get; } = new UserPermissions(Enum.GetValues<UserPermission>());
/// <summary>
/// Create an instance containing given permissions.
/// </summary>
/// <param name="permissions">Permission list.</param>
public UserPermissions(params UserPermission[] permissions) : this(permissions as IEnumerable<UserPermission>)
{
}
/// <summary>
/// Create an instance containing given permissions.
/// </summary>
/// <param name="permissions">Permission list.</param>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="permissions"/> is null.</exception>
public UserPermissions(IEnumerable<UserPermission> permissions)
{
if (permissions == null) throw new ArgumentNullException(nameof(permissions));
_permissions = new HashSet<UserPermission>(permissions);
}
private readonly HashSet<UserPermission> _permissions = new();
/// <summary>
/// Check if a permission is contained in the list.
/// </summary>
/// <param name="permission">The permission to check.</param>
/// <returns>True if contains. Otherwise false.</returns>
public bool Contains(UserPermission permission)
{
return _permissions.Contains(permission);
}
/// <summary>
/// To a serializable string list.
/// </summary>
/// <returns>A string list.</returns>
public List<string> ToStringList()
{
return _permissions.Select(p => p.ToString()).ToList();
}
/// <summary>
/// Convert a string list to user permissions.
/// </summary>
/// <param name="list">The string list.</param>
/// <returns>An instance.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="list"/> is null.</exception>
/// <exception cref="ArgumentException">Thrown when there is unknown permission name.</exception>
public static UserPermissions FromStringList(IEnumerable<string> list)
{
List<UserPermission> permissions = new();
foreach (var value in list)
{
if (Enum.TryParse<UserPermission>(value, false, out var result))
{
permissions.Add(result);
}
else
{
throw new ArgumentException("Unknown permission name.", nameof(list));
}
}
return new UserPermissions(permissions);
}
public IEnumerator<UserPermission> GetEnumerator()
{
return _permissions.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)_permissions).GetEnumerator();
}
}
public interface IUserPermissionService
{
/// <summary>
/// Get permissions of a user.
/// </summary>
/// <param name="userId">The id of the user.</param>
/// <param name="checkUserExistence">Whether check the user's existence.</param>
/// <returns>The permission list.</returns>
/// <exception cref="UserNotExistException">Thrown when <paramref name="checkUserExistence"/> is true and user does not exist.</exception>
Task<UserPermissions> GetPermissionsOfUserAsync(long userId, bool checkUserExistence = true);
/// <summary>
/// Add a permission to user.
/// </summary>
/// <param name="userId">The id of the user.</param>
/// <param name="permission">The new permission.</param>
/// <exception cref="UserNotExistException">Thrown when user does not exist.</exception>
Task AddPermissionToUserAsync(long userId, UserPermission permission);
/// <summary>
/// Remove a permission from user.
/// </summary>
/// <param name="userId">The id of the user.</param>
/// <param name="permission">The permission.</param>
/// <param name="checkUserExistence">Whether check the user's existence.</param>
/// <exception cref="UserNotExistException">Thrown when <paramref name="checkUserExistence"/> is true and user does not exist.</exception>
Task RemovePermissionFromUserAsync(long userId, UserPermission permission, bool checkUserExistence = true);
}
public class UserPermissionService : IUserPermissionService
{
private readonly DatabaseContext _database;
public UserPermissionService(DatabaseContext database)
{
_database = database;
}
private async Task CheckUserExistence(long userId, bool checkUserExistence)
{
if (checkUserExistence)
{
var existence = await _database.Users.AnyAsync(u => u.Id == userId);
if (!existence)
{
throw new UserNotExistException(userId);
}
}
}
public async Task<UserPermissions> GetPermissionsOfUserAsync(long userId, bool checkUserExistence = true)
{
if (userId == 1) // The init administrator account.
{
return UserPermissions.AllPermissions;
}
await CheckUserExistence(userId, checkUserExistence);
var permissionNameList = await _database.UserPermission.Where(e => e.UserId == userId).Select(e => e.Permission).ToListAsync();
return UserPermissions.FromStringList(permissionNameList);
}
public async Task AddPermissionToUserAsync(long userId, UserPermission permission)
{
if (userId == 1) // The init administrator account.
return;
await CheckUserExistence(userId, true);
var alreadyHas = await _database.UserPermission
.AnyAsync(e => e.UserId == userId && e.Permission == permission.ToString());
if (alreadyHas) return;
_database.UserPermission.Add(new UserPermissionEntity { UserId = userId, Permission = permission.ToString() });
await _database.SaveChangesAsync();
}
public async Task RemovePermissionFromUserAsync(long userId, UserPermission permission, bool checkUserExistence = true)
{
if (userId == 1) // The init administrator account.
return;
await CheckUserExistence(userId, checkUserExistence);
var entity = await _database.UserPermission
.Where(e => e.UserId == userId && e.Permission == permission.ToString())
.SingleOrDefaultAsync();
if (entity == null) return;
_database.UserPermission.Remove(entity);
await _database.SaveChangesAsync();
}
}
}
|