Skip to content

Commit

Permalink
api: multi user create api
Browse files Browse the repository at this point in the history
  • Loading branch information
GZTimeWalker committed Apr 18, 2023
1 parent 310f64d commit b4d9850
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 3 deletions.
46 changes: 46 additions & 0 deletions src/GZCTF/ClientApp/src/Api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,35 @@ export interface UserInfoModel {
emailConfirmed?: boolean | null
}

/** 批量用户创建(Admin) */
export interface UserCreateModel {
/**
* 用户名
* @minLength 3
* @maxLength 15
*/
userName: string
/**
* 密码
* @minLength 6
*/
password: string
/**
* 邮箱
* @format email
* @minLength 1
*/
email: string
/** 真实姓名 */
realName?: string | null
/** 学号 */
stdNumber?: string | null
/** 联系电话 */
phone?: string | null
/** 用户加入的队伍 */
teamName?: string | null
}

/** 列表响应 */
export interface ArrayResponseOfTeamInfoModel {
/** 数据 */
Expand Down Expand Up @@ -1964,6 +1993,23 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
options?: MutatorOptions
) => mutate<ArrayResponseOfUserInfoModel>([`/api/admin/users`, query], data, options),

/**
* @description 使用此接口批量添加用户,需要Admin权限
*
* @tags Admin
* @name AdminAddUsers
* @summary 批量添加用户
* @request POST:/api/admin/users
*/
adminAddUsers: (data: UserCreateModel[], params: RequestParams = {}) =>
this.request<void, RequestResponse>({
path: `/api/admin/users`,
method: 'POST',
body: data,
type: ContentType.Json,
...params,
}),

/**
* @description 使用此接口搜索用户,需要Admin权限
*
Expand Down
57 changes: 54 additions & 3 deletions src/GZCTF/Controllers/AdminController.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Linq;
using System.Net.Mime;
using System.Net.Mime;
using CTFServer.Extensions;
using CTFServer.Middlewares;
using CTFServer.Models.Internal;
Expand Down Expand Up @@ -123,6 +122,58 @@ from user in userManager.Users.OrderBy(e => e.Id).Skip(skip).Take(count)
select UserInfoModel.FromUserInfo(user)
).ToArrayAsync(token)).ToResponse(await userManager.Users.CountAsync(token)));

/// <summary>
/// 批量添加用户
/// </summary>
/// <remarks>
/// 使用此接口批量添加用户,需要Admin权限
/// </remarks>
/// <response code="200">成功添加</response>
/// <response code="401">未授权用户</response>
/// <response code="403">禁止访问</response>
[HttpPost("Users")]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<IActionResult> AddUsers([FromBody] List<UserCreateModel> model, CancellationToken token = default)
{
var trans = await teamRepository.BeginTransactionAsync(token);

try
{
var users = new List<(UserInfo, string?)>(model.Count);
foreach(var user in model)
{
var userInfo = user.ToUserInfo();
await userManager.CreateAsync(userInfo, user.Password);
users.Add((userInfo, user.TeamName));
}

var teams = new List<Team>();
foreach(var (user, teamName) in users)
{
if (teamName is null)
continue;

var team = teams.Find(team => team.Name == teamName);
if (team is null)
{
team = await teamRepository.CreateTeam(new(teamName), user, token);
teams.Add(team!);
}
else
{
team.Members.Add(user);
}
}

return Ok();
}
catch
{
await trans.RollbackAsync(token);
throw;
}
}

/// <summary>
/// 搜索用户
/// </summary>
Expand Down Expand Up @@ -281,7 +332,7 @@ public async Task<IActionResult> DeleteUser(string userid, CancellationToken tok
[ProducesResponseType(typeof(RequestResponse), StatusCodes.Status404NotFound)]
public async Task<IActionResult> DeleteTeam(int id, CancellationToken token = default)
{
var team = await teamRepository.GetTeamById(id);
var team = await teamRepository.GetTeamById(id, token);

if (team is null)
return NotFound(new RequestResponse("队伍未找到", 404));
Expand Down
62 changes: 62 additions & 0 deletions src/GZCTF/Models/Request/Admin/UserCreateModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System.ComponentModel.DataAnnotations;

namespace CTFServer.Models.Request.Admin;

/// <summary>
/// 批量用户创建(Admin)
/// </summary>
public class UserCreateModel
{
/// <summary>
/// 用户名
/// </summary>
[Required(ErrorMessage = "用户名是必需的")]
[MinLength(3, ErrorMessage = "用户名过短")]
[MaxLength(15, ErrorMessage = "用户名过长")]
public string UserName { get; set; } = string.Empty;

/// <summary>
/// 密码
/// </summary>
[Required(ErrorMessage = "密码是必需的")]
[MinLength(6)]
public string Password { get; set; } = string.Empty;

/// <summary>
/// 邮箱
/// </summary>
[Required(ErrorMessage = "邮箱是必需的")]
[EmailAddress(ErrorMessage = "邮箱地址无效")]
public string Email { get; set; } = string.Empty;

/// <summary>
/// 真实姓名
/// </summary>
public string? RealName { get; set; }

/// <summary>
/// 学号
/// </summary>
public string? StdNumber { get; set; }

/// <summary>
/// 联系电话
/// </summary>
public string? Phone { get; set; }

/// <summary>
/// 用户加入的队伍
/// </summary>
public string? TeamName { get; set; }

internal UserInfo ToUserInfo()
=> new()
{
Email = Email,
UserName = UserName,
RealName = RealName ?? "",
StdNumber = StdNumber ?? "",
PhoneNumber = Phone,
EmailConfirmed = true
};
}
5 changes: 5 additions & 0 deletions src/GZCTF/Models/Request/Info/TeamUpdateModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ namespace CTFServer.Models.Request.Info;
/// </summary>
public class TeamUpdateModel
{
public TeamUpdateModel(string teamName)
{
Name = teamName;
}

/// <summary>
/// 队伍名称
/// </summary>
Expand Down

0 comments on commit b4d9850

Please sign in to comment.