From 3e02e6ca3c9e816dcbc0fc78e782705101f0897c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=AF=85?= <2667210109@qq.com> Date: Sun, 29 Dec 2024 00:12:46 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- asg_form/Controllers/Dbset.cs | 2 - asg_form/Controllers/Events.cs | 1 - asg_form/Controllers/OAuthController.cs | 139 ++++++++++++++++++ .../Teamregistration/RegisterController.cs | 7 +- asg_form/Controllers/admin.cs | 100 +++++++------ asg_form/Controllers/chatgpt.cs | 1 - asg_form/Controllers/form_cs.cs | 1 - asg_form/Controllers/login.cs | 1 - asg_form/Controllers/schedule.cs | 1 - asg_form/Program.cs | 55 ++++--- asg_form/appsettings.json | 52 +++++++ asg_form/asg_form.csproj | 43 ++---- asg_form/qqbot.cs | 6 - 13 files changed, 298 insertions(+), 111 deletions(-) create mode 100644 asg_form/Controllers/OAuthController.cs diff --git a/asg_form/Controllers/Dbset.cs b/asg_form/Controllers/Dbset.cs index b6e0604..7c1844c 100644 --- a/asg_form/Controllers/Dbset.cs +++ b/asg_form/Controllers/Dbset.cs @@ -5,8 +5,6 @@ using asg_form.Controllers.Store; using asg_form.Controllers.Teamregistration; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.DataEncryption; -using Microsoft.EntityFrameworkCore.DataEncryption.Providers; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using System.Security.Cryptography; diff --git a/asg_form/Controllers/Events.cs b/asg_form/Controllers/Events.cs index eee3152..18c55bb 100644 --- a/asg_form/Controllers/Events.cs +++ b/asg_form/Controllers/Events.cs @@ -1,7 +1,6 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; -using NPOI.SS.Formula.Functions; using System.Reflection.Metadata; using System.Security.Claims; using static asg_form.Controllers.excel; diff --git a/asg_form/Controllers/OAuthController.cs b/asg_form/Controllers/OAuthController.cs new file mode 100644 index 0000000..a2e295c --- /dev/null +++ b/asg_form/Controllers/OAuthController.cs @@ -0,0 +1,139 @@ +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Tokens; +using MrHuo.OAuth.Github; +using MrHuo.OAuth.Microsoft; +using System.IdentityModel.Tokens.Jwt; +using System.Management; +using System.Security.Claims; +using System.Text; + +namespace asg_form.Controllers +{ + public class OAuthController : Controller + { + + private readonly RoleManager roleManager; + private readonly UserManager userManager; + + public OAuthController( + RoleManager roleManager, UserManager userManager) + { + + this.roleManager = roleManager; + this.userManager = userManager; + } + + + + + [HttpGet("oauth/setpassword")] + public async Task SetPasswordAsync(string username,string password, [FromServices] IOptions jwtOptions) + { + var user = await userManager.FindByNameAsync(username); + await userManager.AddPasswordAsync(user, password); + var claims = new List(); + claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())); + claims.Add(new Claim(ClaimTypes.Name, user.UserName)); + var roles = await userManager.GetRolesAsync(user); + foreach (string role in roles) + { + claims.Add(new Claim(ClaimTypes.Role, role)); + } + string jwtToken = BuildToken(claims, jwtOptions.Value); + return jwtToken; + } + + + [HttpGet("oauth/{type}")] + public IActionResult Index( + string type,string recall, + [FromServices] GithubOAuth githubOAuth, + [FromServices] MicrosoftOAuth microsoftOAuth + ) + { + var redirectUrl = ""; + switch (type.ToLower()) + { + case "github": + { + redirectUrl = githubOAuth.GetAuthorizeUrl(); + break; + } + case "microsoft": + { + redirectUrl = microsoftOAuth.GetAuthorizeUrl(); + break; + } + default: + return NotFound($"没有实现【{type}】登录方式!"); + } + return Redirect(redirectUrl); + } + + + private static string BuildToken(IEnumerable claims, JWTOptions options) + { + DateTime expires = DateTime.Now.AddSeconds(options.ExpireSeconds); + byte[] keyBytes = Encoding.UTF8.GetBytes(options.SigningKey); + var secKey = new SymmetricSecurityKey(keyBytes); + + var credentials = new SigningCredentials(secKey, + SecurityAlgorithms.HmacSha256Signature); + var tokenDescriptor = new JwtSecurityToken(expires: expires, + signingCredentials: credentials, claims: claims); + return new JwtSecurityTokenHandler().WriteToken(tokenDescriptor); + } + + [HttpGet("oauth/{type}callback")] + public async Task LoginCallback( + string type, + [FromServices] GithubOAuth githubOAuth, + [FromServices] IOptions jwtOptions, + [FromQuery] string code, + [FromQuery] string state) + { + try + { + switch (type.ToLower()) + { + case "github": + { + var authorizeResult = await githubOAuth.AuthorizeCallback(code, state); + if (!authorizeResult.IsSccess) + { + throw new Exception(authorizeResult.ErrorMessage); + } + var userinfo = await githubOAuth.GetUserInfoAsync(authorizeResult.AccessToken); + //如果该Gitgub用户不存在,则创建一个 + var user = new User() { Id=20,UserName = $"gh{userinfo.Name}", Email = userinfo.Email }; + if (user == null) + { + var user_new = await userManager.FindByNameAsync(userinfo.Name); + var r = await userManager.CreateAsync(user); + return Redirect($"https://commentary.idvasg.cn/oauth/next?username=gh{userinfo.Name}"); + } + var claims = new List(); + claims.Add(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())); + claims.Add(new Claim(ClaimTypes.Name, user.UserName)); + var roles = await userManager.GetRolesAsync(user); + foreach (string role in roles) + { + claims.Add(new Claim(ClaimTypes.Role, role)); + } + string jwtToken = BuildToken(claims, jwtOptions.Value); + return Redirect($"https://commentary.idvasg.cn/oauth/loginok?token={jwtToken}"); + + } + default: + throw new Exception($"没有实现【{type}】登录回调!"); + } + } + catch (Exception ex) + { + return Content(ex.Message); + } + } + } +} diff --git a/asg_form/Controllers/Teamregistration/RegisterController.cs b/asg_form/Controllers/Teamregistration/RegisterController.cs index a416cd2..07afdaf 100644 --- a/asg_form/Controllers/Teamregistration/RegisterController.cs +++ b/asg_form/Controllers/Teamregistration/RegisterController.cs @@ -65,12 +65,9 @@ namespace asg_form.Controllers.Teamregistration using (TestDbContext sub = new TestDbContext()) { - if (msg.userId == null) - { - return Ok(new error_mb { code = 400, message = "用户ID为空" }); - } + - if (sub.T_Comform.Find(msg.userId) != null) + if (msg.id == null&&sub.T_Comform.Find(msg.userId) != null) { return Ok(new error_mb { code = 400, message = "你已经提交过表单了,请不要重复提交" }); } diff --git a/asg_form/Controllers/admin.cs b/asg_form/Controllers/admin.cs index 30cdd59..7227137 100644 --- a/asg_form/Controllers/admin.cs +++ b/asg_form/Controllers/admin.cs @@ -9,20 +9,17 @@ using Newtonsoft.Json.Linq; using RestSharp; using static asg_form.blog; using static asg_form.Controllers.schedule; -using static NPOI.HSSF.Util.HSSFColor; using NLog; using System.Security.Authentication; using System.Text.Json; using Microsoft.AspNetCore.SignalR; using asg_form.Controllers.Hubs; -using NPOI.OpenXmlFormats.Spreadsheet; using Mirai.Net.Data.Shared; using MimeKit; using MailKit.Net.Smtp; using Mirai.Net.Utils.Scaffolds; using Mirai.Net.Sessions.Http.Managers; using asg_form.Controllers.Store; -using NPOI.SS.Formula.Functions; using static asg_form.Controllers.Store.Storehttp; using Flandre.Framework; using Flandre.Core.Common; @@ -302,47 +299,66 @@ namespace asg_form.Controllers - /// - /// 获取所有用户-支持分页(整合api:allperson_c) - /// - /// - /// - /// - /// - [Route("api/v2/admin/allperson")] - [HttpGet] - [Authorize] - public async Task> getalladmin_v2(string? keyword, short pageindex = 1, short pagesize = 10,string? offficum = null) - { - bool isAdmin = this.User.FindAll(ClaimTypes.Role).Any(a => a.Value == "admin"); - if (isAdmin) - { - var a = new all_record(); - if(keyword== null && offficum == null) - { - a.cout = userManager.Users.Count(); - a.msg = await userManager.Users.Paginate(pageindex, pagesize).Select(a => new { a.Id, a.Email, a.chinaname, a.UserName, a.Integral, a.officium,a.qqnumber,a.roleListName,a.roleListCode }).ToListAsync(); - } - if (keyword == null) - { - a.cout = userManager.Users.Count(); - a.msg = await userManager.Users.Paginate(pageindex, pagesize).Where(a=>a.officium==offficum).Select(a => new { a.Id, a.Email, a.chinaname, a.UserName, a.Integral, a.officium,a.qqnumber,a.roleListName,a.roleListCode}).ToListAsync(); - - } - else - { + /// +/// 获取所有用户-支持分页(整合api:allperson_c) +/// +/// 搜索关键字 +/// 页码,默认为1 +/// 每页大小,默认为10 +/// 部门筛选条件 +/// 返回分页后的用户列表及总数 +[Route("api/v2/admin/allperson")] +[HttpGet] +[Authorize] +public async Task> GetAdminUsersV2(string? keyword = null, short pageindex = 1, short pagesize = 10, string? officum = null) +{ + // 检查用户是否有管理员权限 + if (!this.User.HasClaim(ClaimTypes.Role, "admin")) + { + return BadRequest(new error_mb { code = 400, message = "无权访问" }); + } - a.cout = userManager.Users.Where(a => a.chinaname.Contains(keyword) || a.UserName == keyword || a.Email == keyword).Count(); - a.msg = await userManager.Users.Where(a => a.chinaname.Contains(keyword) || a.UserName == keyword || a.Email == keyword&&a.officium==offficum).Paginate(pageindex, pagesize).Select(a => new { a.Id, a.Email, a.chinaname, a.UserName, a.Integral, a.officium,a.qqnumber, a.roleListName, a.roleListCode }).ToListAsync(); - } - return Ok(a); - } - else - { - return BadRequest(new error_mb { code = 400, message = "无权访问" }); + var query = userManager.Users.AsQueryable(); - } - } + // 根据关键词和部门进行过滤 + if (!string.IsNullOrEmpty(keyword)) + { + query = query.Where(u => u.chinaname.Contains(keyword) || u.UserName == keyword || u.Email == keyword); + } + + if (!string.IsNullOrEmpty(officum)) + { + query = query.Where(u => u.officium == officum); + } + + // 获取总记录数 + int total = await query.CountAsync(); + + // 分页查询 + var paginatedUsers = await query.Paginate(pageindex, pagesize) + .Select(u => new + { + u.Id, + u.Email, + u.chinaname, + u.UserName, + u.Integral, + u.officium, + u.qqnumber, + u.roleListName, + u.roleListCode + }) + .ToListAsync(); + + // 构建返回结果 + var result = new all_record + { + cout = total, + msg = paginatedUsers + }; + + return Ok(result); +} public class post_user_v2 { diff --git a/asg_form/Controllers/chatgpt.cs b/asg_form/Controllers/chatgpt.cs index 2ce3f82..7046c4b 100644 --- a/asg_form/Controllers/chatgpt.cs +++ b/asg_form/Controllers/chatgpt.cs @@ -3,7 +3,6 @@ using ChatGPT.Net; using ChatGPT.Net.DTO.ChatGPT; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -using NPOI.SS.Formula.Functions; using static asg_form.Controllers.login; namespace asg_form.Controllers diff --git a/asg_form/Controllers/form_cs.cs b/asg_form/Controllers/form_cs.cs index a2594e3..b5ab351 100644 --- a/asg_form/Controllers/form_cs.cs +++ b/asg_form/Controllers/form_cs.cs @@ -11,7 +11,6 @@ using Microsoft.AspNetCore.SignalR; using Microsoft.EntityFrameworkCore; using Newtonsoft.Json.Linq; using NLog; -using NPOI.OpenXmlFormats.Spreadsheet; using RestSharp; using SixLabors.ImageSharp; using System.ComponentModel.DataAnnotations; diff --git a/asg_form/Controllers/login.cs b/asg_form/Controllers/login.cs index 48807e7..3ac9a5d 100644 --- a/asg_form/Controllers/login.cs +++ b/asg_form/Controllers/login.cs @@ -6,7 +6,6 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json.Linq; -using NPOI.SS.Formula.Functions; using OfficeOpenXml.Packaging.Ionic.Zlib; using RestSharp; using System.IdentityModel.Tokens.Jwt; diff --git a/asg_form/Controllers/schedule.cs b/asg_form/Controllers/schedule.cs index 67a3c27..695a98b 100644 --- a/asg_form/Controllers/schedule.cs +++ b/asg_form/Controllers/schedule.cs @@ -4,7 +4,6 @@ using Microsoft.AspNetCore.Authorization; using static asg_form.blog; using System.Security.Claims; using Microsoft.EntityFrameworkCore; -using NPOI.OpenXmlFormats.Spreadsheet; using Castle.Components.DictionaryAdapter; using Flandre.Core.Messaging; using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; diff --git a/asg_form/Program.cs b/asg_form/Program.cs index 22a6464..48dcd49 100644 --- a/asg_form/Program.cs +++ b/asg_form/Program.cs @@ -16,6 +16,9 @@ using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using Mirai.Net.Sessions; using Mirai.Net.Sessions.Http.Managers; +using MrHuo.OAuth; +using MrHuo.OAuth.Github; +using MrHuo.OAuth.Microsoft; using System; using System.Data; using System.Drawing; @@ -143,6 +146,9 @@ services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) IssuerSigningKey = secKey }; }); +services.AddSingleton(new GithubOAuth(OAuthConfig.LoadFrom(builder.Configuration, "oauth:github"))); +services.AddSingleton(new MicrosoftOAuth(OAuthConfig.LoadFrom(builder.Configuration, "oauth:microsoft"))); + builder.Services.AddApplicationInsightsTelemetry(); @@ -212,30 +218,39 @@ app.MapControllers(); //新开一个线程,显示当前时间 new Thread(o => { - - - - var builder1 = FlandreApp.CreateBuilder(new HostApplicationBuilderSettings + try { - Args = args, - ContentRootPath = AppDomain.CurrentDomain.BaseDirectory - }); + var builder1 = FlandreApp.CreateBuilder(new HostApplicationBuilderSettings + { + Args = args, + ContentRootPath = AppDomain.CurrentDomain.BaseDirectory + }); - // 安装一个适配器,并添加在这里。 - // builder.Adapters.Add(new YourAdapter()); - builder1.Adapters.AddOneBot(builder1.Configuration.GetSection("Adapters:OneBot")); - builder1.Plugins.Add(); - var app1 = builder1.Build(); - // 添加内置中间件。 - // 这些中间件保证 Flandre 的正常运转。你也可以加入自己的中间件,并灵活调整其顺序。 - app1.UseCommandSession(); - // app.UseMiddleware(async (ctx, next) => { /* ... */ }); - app1.UseCommandParser(); - app1.UseCommandInvoker(); - runbot.runbotr = app1.Bots.First(); - app1.Run(); + // 安装一个适配器,并添加在这里。 + // builder.Adapters.Add(new YourAdapter()); + builder1.Adapters.AddOneBot(builder1.Configuration.GetSection("Adapters:OneBot")); + builder1.Plugins.Add(); + var app1 = builder1.Build(); + // 添加内置中间件。 + // 这些中间件保证 Flandre 的正常运转。你也可以加入自己的中间件,并灵活调整其顺序。 + app1.UseCommandSession(); + // app.UseMiddleware(async (ctx, next) => { /* ... */ }); + app1.UseCommandParser(); + app1.UseCommandInvoker(); + runbot.runbotr = app1.Bots.First(); + app1.Run(); + } + catch(Exception ex) + { + //输出详细全部信息 + Console.WriteLine(ex.ToString()); + + } + + + }) diff --git a/asg_form/appsettings.json b/asg_form/appsettings.json index 56ab28a..cbf6873 100644 --- a/asg_form/appsettings.json +++ b/asg_form/appsettings.json @@ -39,5 +39,57 @@ } ] } + }, + "oauth": { + "qq": { + "app_id": "qq_app_id", + "app_key": "qq_app_key", + "redirect_uri": "https://oauthlogin.net/oauth/qqcallback", + "scope": "get_user_info" + }, + "github": { + "app_id": "Ov23liKQaqPOMKJCzdep", + "app_key": "37dc8fdc1a91f4f464fd05f46b158801ff9f9a61", + "scope": "repo" + }, + "microsoft": { + "client_id": "9206e9e3-4608-4501-85ae-88b42c7f2fe1", + "tenant_id": "7ed846b8-c314-431e-b72c-27562dc7bf04", + "client_secret": "E5O8Q~OPLX3AjKwQz.5hlo7SUDoIdOaurL6F8cWl", + "redirect_uri": "https://api.idvasg.cn/oauth/microsoftcallback", + "scope": "snsapi_userinfo" + }, + "huawei": { + "app_id": "huawei_app_id", + "app_key": "huawei_app_key", + "redirect_uri": "https://oauthlogin.net/oauth/huaweicallback", + "scope": "https://www.huawei.com/auth/account" + }, + "gitee": { + "app_id": "gitee_app_id", + "app_key": "gitee_app_key", + "redirect_uri": "http://oauthlogin.net/oauth/giteecallback", + "scope": "user_info" + }, + "baidu": { + "app_id": "baidu_app_id", + "app_key": "baidu_app_key", + "redirect_uri": "http://oauthlogin.net/oauth/baiducallback", + "scope": "basic" + }, + "alipay": { + "app_id": "alipay_app_id", + "app_key": "alipay_app_key", + "redirect_uri": "https://oauthlogin.net/oauth/alipaycallback", + "scope": "auth_user", + "private_key": "private_key", + "public_key": "public_key" + }, + "gitlab": { + "app_id": "gitlab_app_id", + "app_key": "gitlab_app_key", + "redirect_uri": "http://oauthlogin.net/oauth/gitlabcallback", + "scope": "read_user" + } } } diff --git a/asg_form/asg_form.csproj b/asg_form/asg_form.csproj index 0188af3..c27c89b 100644 --- a/asg_form/asg_form.csproj +++ b/asg_form/asg_form.csproj @@ -1,7 +1,7 @@  - net8.0 + net9.0 enable enable True @@ -15,6 +15,14 @@ mcr.microsoft.com/dotnet/aspnet:8.0 + + True + + + + True + + @@ -27,50 +35,27 @@ - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - + + + - - - - - - @@ -84,10 +69,6 @@ - - - - PreserveNewest diff --git a/asg_form/qqbot.cs b/asg_form/qqbot.cs index 7fc4756..6af0003 100644 --- a/asg_form/qqbot.cs +++ b/asg_form/qqbot.cs @@ -8,18 +8,13 @@ using System.Reactive.Linq; using Microsoft.EntityFrameworkCore; using Mirai.Net.Data.Events.Concretes.Bot; using static asg_form.Controllers.schedule; -using NPOI.OpenXmlFormats.Spreadsheet; using Manganese.Array; -using static NPOI.HSSF.Util.HSSFColor; using System.Drawing; using System.Drawing.Imaging; using Masuit.Tools.Hardware; using Masuit.Tools.Win32; using Masuit.Tools; using Microsoft.AspNetCore.Connections; -using NPOI.SS.Formula.Functions; -using Onebot.Protocol; -using Onebot.Protocol.Models.Messages; using Zack.EventBus; using Flandre.Framework.Common; using Flandre.Framework.Routing; @@ -27,7 +22,6 @@ using static asg_form.Controllers.InviteReferee; using System.Net.Http.Headers; using System.Net.Http; using System.Text; -using Azure.Identity; using Flandre.Core.Messaging; using Flandre.Core.Common; using Microsoft.OpenApi.Models;