CrazyIter_Bin 3 년 전
부모
커밋
62221cd02a

+ 3 - 3
TEAMModeBI/Controllers/LoginController.cs

@@ -242,7 +242,7 @@ namespace TEAMModeBI.Controllers
                                 depts.Add(temp.ToString());
                             }
 
-                            var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, teacher.id,teacher.name?.ToString(),teacher.picture?.ToString(),_option.JwtSecretKey, scope: Constant.ScopeTeacher, schoolID: school_code?.ToString(), standard: school_base.standard, roles:roles.ToArray(),permissions:permissions.ToArray(),ddDepts: depts.ToArray(),ddsub:ddbind.userid);
+                            var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, teacher.id,teacher.name?.ToString(),teacher.picture?.ToString(),_option.JwtSecretKey, scope: Constant.ScopeTeacher, Website: "BI", schoolID: school_code?.ToString(), standard: school_base.standard, roles:roles.ToArray(),permissions:permissions.ToArray(),ddDepts: depts.ToArray(),ddsub:ddbind.userid);
 
                             return Ok(new { state = 200, auth_token = auth_token, teacher = teacher, id_token = implicit_token.id_token, access_token = implicit_token.access_token, expires_in = implicit_token.expires_in, token_type = implicit_token.token_type });
                         }
@@ -379,7 +379,7 @@ namespace TEAMModeBI.Controllers
                     }
                     else return Ok(new { state = 1, message = "该账户未绑定钉钉信息!请扫码绑定信息!" });
 
-                    auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, teacher.id, teacher.name?.ToString(), teacher.picture?.ToString(), _option.JwtSecretKey, scope: Constant.ScopeTeacher, schoolID: school_code.ToString(), standard: school_base.standard, roles: roles.ToArray(), permissions: permissions.ToArray(), ddDepts: depts.ToArray(), ddsub: ddbind.userid);
+                    auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, teacher.id, teacher.name?.ToString(), teacher.picture?.ToString(), _option.JwtSecretKey, scope: Constant.ScopeTeacher, Website: "BI", schoolID: school_code.ToString(), standard: school_base.standard, roles: roles.ToArray(), permissions: permissions.ToArray(), ddDepts: depts.ToArray(), ddsub: ddbind.userid);
                 }
 
                 var (osblob_uri, osblob_sas) = roles.Contains("area") ? _azureStorage.GetBlobContainerSAS("teammodelos", BlobContainerSasPermissions.Write | BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List | BlobContainerSasPermissions.Delete) : _azureStorage.GetBlobContainerSAS("teammodelos", BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List);
@@ -638,7 +638,7 @@ namespace TEAMModeBI.Controllers
                         }
                         else return Ok(new { state = responseMessage.StatusCode });
                     }
-                    id_token = JwtAuthExtension.CreateAuthToken(_option.HostName, itemUser.tmdId?.ToString(), itemUser.tmdName?.ToString(), itemUser.picture?.ToString(), _option.JwtSecretKey, scope: $"assist", roles: roles?.ToArray(), permissions: permissions?.ToArray(), ddsub: itemUser.RowKey?.ToString());
+                    id_token = JwtAuthExtension.CreateAuthToken(_option.HostName, itemUser.tmdId?.ToString(), itemUser.tmdName?.ToString(), itemUser.picture?.ToString(), _option.JwtSecretKey,Website: "BI", scope: $"assist", roles: roles?.ToArray(), permissions: permissions?.ToArray(), ddsub: itemUser.RowKey?.ToString());
                 }
 
                 var (osblob_uri, osblob_sas) = roles.Contains("assist") ? _azureStorage.GetBlobContainerSAS("teammodelos", BlobContainerSasPermissions.Write | BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List | BlobContainerSasPermissions.Delete) : _azureStorage.GetBlobContainerSAS("teammodelos", BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List);

+ 40 - 1
TEAMModelOS.SDK/DI/AzureStorage/AzureStorageBlobExtensions.cs

@@ -17,6 +17,9 @@ using TEAMModelOS.SDK;
 using TEAMModelOS.SDK.Extension;
 using HTEXLib.COMM.Helpers;
 using System.Text.Encodings.Web;
+using TEAMModelOS.SDK.Models.Table;
+using Microsoft.AspNetCore.Http;
+using TEAMModelOS.Models;
 
 namespace TEAMModelOS.SDK.DI
 {
@@ -261,7 +264,43 @@ namespace TEAMModelOS.SDK.DI
                 return false;
             }
         }
-
+        public static async Task SaveLog(this AzureStorageFactory azureStorage, string type, string msg,DingDing dingDing, string scope = null, string bizId = null, Option option = null, HttpContext httpContext = null)
+        {
+            OptLog log = new OptLog() { RowKey = Guid.NewGuid().ToString() };
+            try
+            {
+                object id = null, school = null, website = null ;
+                httpContext?.Items.TryGetValue("ID", out id);
+                httpContext?.Items.TryGetValue("School", out school);
+                httpContext?.Items.TryGetValue("Website", out website);
+                log.tmdId = id != null ? $"{id}" : log.tmdId;
+                string host = httpContext?.Request?.Host.Value;
+                log.school = school != null ? $"{school}" : log.school;
+                log.PartitionKey = type != null ? $"Log-{type}" : "Log-Default";
+                log.RowKey = bizId != null ? bizId : Guid.NewGuid().ToString();
+                log.platform = website!=null? $"{website}" : "Default";
+                log.msg = msg;
+                log.type = type;
+                log.scope = scope;
+                host = !string.IsNullOrWhiteSpace($"{host}") ? $"{host}" : option?.Location != null ? $"{host}" : "Default";
+                log.url =$"{host}{httpContext?.Request.Path}" ;
+                if (!string.IsNullOrWhiteSpace(msg) && msg.Length > 100)
+                {
+                    log.saveMod = 1;
+                   
+                    _ = azureStorage.UploadFileByContainer("0-public", log.ToJsonString(), "optlog", $"{log.RowKey}-{log.PartitionKey}.json");
+                    log.msg = null;
+                    await azureStorage.SaveOrUpdate<OptLog>(log);
+                }
+                else {
+                    await azureStorage.SaveOrUpdate<OptLog>(log);
+                }
+            }
+            catch (Exception ex)
+            {
+                _ = dingDing.SendBotMsg($"日志保存失败:{ex.Message},{ex.StackTrace},{log.ToJsonString()}", GroupNames.成都开发測試群組);
+            }
+        }
         /// <summary>
         /// 系统管理员 资源,题目关联,htex关联,学习活动学生上传文件关联,基本信息关联,教室平面图关联,评测冷数据关联
         /// "system": [ "res", "item", "htex", "task", "info", "room", "exam" ],

+ 3 - 2
TEAMModelOS.SDK/Extension/JwtAuthExtension.cs

@@ -14,7 +14,7 @@ namespace TEAMModelOS.SDK.Extension
 {
     public static class JwtAuthExtension
     {
-        public static string CreateAuthToken(string issuer, string id, string name, string picture, string salt, string scope, string schoolID = "", string standard = "", string[] roles = null, string[] permissions = null, int expire = 1, string[] ddDepts = null, string ddsub = null)
+        public static string CreateAuthToken(string issuer, string id, string name, string picture, string salt, string scope,string Website, string schoolID = "", string standard = "", string[] roles = null, string[] permissions = null, int expire = 1, string[] ddDepts = null, string ddsub = null)
         {
             // 設定要加入到 JWT Token 中的聲明資訊(Claims)  
             var payload = new JwtPayload {
@@ -29,7 +29,8 @@ namespace TEAMModelOS.SDK.Extension
                 { "standard",standard} ,//登入者的能力点标准
                 { "scope",scope},  //登入者的入口类型。 (teacher 教师端登录的醍摩豆ID、tmduser学生端登录的醍摩豆ID、student学生端登录校内账号的学生ID) 
                 { "dddepts",ddDepts},  //登陆者的钉钉部门id
-                {"ddsub",ddsub }   //登陆者的钉钉用户id
+                { "ddsub",ddsub } ,  //登陆者的钉钉用户id
+                { JwtRegisteredClaimNames.Website,Website}, // 學校簡碼,如果有的話
             };
 
             // 建立一組對稱式加密的金鑰,主要用於 JWT 簽章之用

+ 47 - 1
TEAMModelOS.SDK/Models/Table/OperateLog.cs

@@ -6,7 +6,7 @@ using Microsoft.Azure.Cosmos.Table;
 
 namespace TEAMModelOS.SDK.Models.Table
 {
-    [TableName(Name = "OperateLogs")]
+    [TableName(Name = "OperateLog")]
     public class OperateLog : TableEntity
     {
         /// <summary>
@@ -59,6 +59,52 @@ namespace TEAMModelOS.SDK.Models.Table
         /// </summary>
         public string owner { get; set; }
 
+        /// <summary>
+        /// 学校编码
+        /// </summary>
+        public string school { get; set; }
+    }
+    [TableName(Name = "OptLog")]
+    public class OptLog : TableEntity
+    {
+        /// <summary>
+        /// 日志平台:BI 、 IES5
+        /// </summary>
+        public string platform { get; set; }
+
+        /// <summary>
+        /// 醍摩豆ID
+        /// </summary>
+        public string tmdId { get; set; }
+
+        /// <summary>
+        /// 操作描述
+        /// </summary>
+        public string msg { get; set; }
 
+        /// <summary>
+        /// 日志类型: school-update school-del    名词-动词组合方式
+        /// </summary>
+        public string type { get; set; }
+
+        /// <summary>
+        /// 访问接口
+        /// </summary>
+        public string url { get; set; }
+
+        /// <summary>
+        /// 使用范围  private school
+        /// </summary>
+        public string scope { get; set; }
+
+        /// <summary>
+        /// 学校编码
+        /// </summary>
+        public string school { get; set; }
+        /// <summary>
+        /// 保存模式。0 Table ,1 增加保存在Blob 
+        /// </summary>
+        public int saveMod { get; set; } = 0;
+        public long time { get; set; }= DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
     }
 }

+ 2 - 2
TEAMModelOS/Controllers/School/StudentController.cs

@@ -2630,7 +2630,7 @@ namespace TEAMModelOS.Controllers
                         var (blob_uri, blob_sas) = _azureStorage.GetBlobContainerSAS(school_code.GetString().ToLower(), BlobContainerSasPermissions.Read);
 
                         //換取AuthToken,提供給前端
-                        var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id.GetString(), name.GetString(), picture.GetString(), _option.JwtSecretKey,scope: Constant.ScopeStudent, schoolID: school_code.GetString(), roles: new[] { "student" });
+                        var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id.GetString(), name.GetString(), picture.GetString(), _option.JwtSecretKey,scope: Constant.ScopeStudent, Website: "IES", schoolID: school_code.GetString(), roles: new[] { "student" });
                         var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
                         var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
                         var token = await CoreTokenExtensions.CreateAccessToken(clientID, clientSecret, _option.Location.Replace("-Dep","").Replace("-Test",""));
@@ -2770,7 +2770,7 @@ namespace TEAMModelOS.Controllers
                             }
                         }
                         //換取AuthToken,提供給前端
-                        var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id.GetString(), name.GetString(), picture.GetString(), _option.JwtSecretKey, scope: Constant.ScopeStudent, schoolID: school_code.GetString(), roles: new[] { "student" });
+                        var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id.GetString(), name.GetString(), picture.GetString(), _option.JwtSecretKey, Website: "IES", scope: Constant.ScopeStudent, schoolID: school_code.GetString(), roles: new[] { "student" });
                         //其他訊息
                         dynamic school = new ExpandoObject();
                         //回傳

+ 1 - 1
TEAMModelOS/Controllers/School/TmdUserController.cs

@@ -133,7 +133,7 @@ namespace TEAMModelOS.Controllers
                     }
                 }
                 //換取AuthToken,提供給前端
-                var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey,   scope: Constant.ScopeTmdUser, roles: new[] { "student" });
+                var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, Website: "IES", scope: Constant.ScopeTmdUser, roles: new[] { "student" });
                 if (!string.IsNullOrEmpty(defaultschool)) { 
 
                 }

+ 1 - 1
TEAMModelOS/Controllers/Teacher/InitController.cs

@@ -425,7 +425,7 @@ namespace TEAMModelOS.Controllers
                     roles.Add("area");
                 }
                 //TODO JJ,更新Token时,在取得学校资讯时,没有传入schoolId
-                var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, scope: Constant.ScopeTeacher, schoolID: school_code.ToString(), standard: school_base.standard, roles: roles.ToArray(), permissions: permissions.ToArray());
+                var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, Website: "IES", scope: Constant.ScopeTeacher, schoolID: school_code.ToString(), standard: school_base.standard, roles: roles.ToArray(), permissions: permissions.ToArray());
 
                 //取得班级
                 List<object> school_classes = new List<object>();

+ 15 - 0
TEAMModelOS/Controllers/XTest/TestController.cs

@@ -23,6 +23,7 @@ using System.Text;
 using System.Text.Json;
 using System.Text.RegularExpressions;
 using System.Threading.Tasks;
+using TEAMModelOS.Filter;
 using TEAMModelOS.Models;
 using TEAMModelOS.SDK;
 using TEAMModelOS.SDK.DI;
@@ -592,6 +593,20 @@ namespace TEAMModelOS.Controllers
             List<ScTeacher> teachers = await _azureStorage.FindListByDict<ScTeacher>(new Dictionary<string, object> { { "PartitionKey", "ScTeacher" }, { "areaId", $"{areaId}" } });
             return Ok(teachers.Select(x =>new  {x.areaId,x.PXID,x.TID,x.TeacherName,x.tmdid,x.SchoolName,x.DisName }));
         }
+
+        /// 删除
+        /// </summary>
+        /// <param name="request"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [AuthToken(Roles = "admin,teacher")]
+        [HttpPost("get-save-log")]
+        public async Task<IActionResult> SaveLog(JsonElement request)
+        {
+            School school = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>("hbcn", new PartitionKey("Base"));
+            _=  _azureStorage.SaveLog("find-school", school.ToJsonString(),httpContext:HttpContext,dingDing:_dingDing,scope:"school");
+            return Ok(school);
+        }
     }
 
 }

+ 3 - 1
TEAMModelOS/Filter/AuthTokenAttribute.cs

@@ -38,7 +38,7 @@ namespace TEAMModelOS.Filter
             public void OnResourceExecuting(ResourceExecutingContext context)
             {
                 bool pass = false;
-                string id = string.Empty, name = string.Empty, picture = string.Empty, school = string.Empty, standard = string.Empty,scope=string.Empty;
+                string id = string.Empty, name = string.Empty, picture = string.Empty, school = string.Empty, standard = string.Empty,scope=string.Empty,  website=string.Empty;
                 List<string> _role = new List<string>();
                 var authtoken = context.HttpContext.GetXAuth("AuthToken");
                 if (!string.IsNullOrWhiteSpace(authtoken) && JwtAuthExtension.ValidateAuthToken(authtoken, _option.JwtSecretKey))
@@ -50,6 +50,7 @@ namespace TEAMModelOS.Filter
                     picture = jwt.Claims.FirstOrDefault(claim => claim.Type.Equals("picture"))?.Value;
                     standard = jwt.Claims.FirstOrDefault(claim => claim.Type.Equals("standard"))?.Value;
                     scope = jwt.Claims.FirstOrDefault(claim => claim.Type.Equals("scope"))?.Value;
+                    website = jwt.Claims.FirstOrDefault(claim => claim.Type.Equals("website"))?.Value;
                     if (!string.IsNullOrWhiteSpace(_roles))
                     {
                         var roles = jwt.Claims.Where(c => c.Type.Equals("roles"));
@@ -86,6 +87,7 @@ namespace TEAMModelOS.Filter
                     context.HttpContext.Items.Add("Standard", standard);
                     context.HttpContext.Items.Add("Roles", _role);
                     context.HttpContext.Items.Add("Scope", scope);
+                    context.HttpContext.Items.Add("Website", website);
                 }
                 else
                     context.Result = new BadRequestResult();

+ 1 - 2
TEAMModelOS/Services/Common/TeacherService.cs

@@ -252,12 +252,11 @@ namespace TEAMModelOS.Services
                 }
             }
             //換取AuthToken,提供給前端
-            var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, scope: Constant.ScopeTeacher, standard: areaa != null ? areaa.standard : "", roles: roles.ToArray());
+            var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, Website: "IES", scope: Constant.ScopeTeacher, standard: areaa != null ? areaa.standard : "", roles: roles.ToArray());
             //取得Teacher Blob 容器位置及SAS 
             await _azureStorage.GetBlobContainerClient(id).CreateIfNotExistsAsync(PublicAccessType.None); //嘗試創建Teacher私有容器,如存在則不做任何事,保障容器一定存在
             var (blob_uri, blob_sas) = _azureStorage.GetBlobContainerSAS(id, BlobContainerSasPermissions.Write | BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List | BlobContainerSasPermissions.Delete);
             var (osblob_uri, osblob_sas) = roles.Contains("area") ? _azureStorage.GetBlobContainerSAS("teammodelos", BlobContainerSasPermissions.Write | BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List | BlobContainerSasPermissions.Delete) : _azureStorage.GetBlobContainerSAS("teammodelos", BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List);
-
             return new TeacherInfo {
                 auth_token = auth_token,
                 blob_uri = blob_uri,