123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- using Azure.Cosmos;
- using Azure.Storage.Blobs.Models;
- using Azure.Storage.Sas;
- using Microsoft.AspNetCore.Http;
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.Extensions.Options;
- using System;
- using System.Collections.Generic;
- using System.Dynamic;
- using System.IdentityModel.Tokens.Jwt;
- using System.IO;
- using System.Linq;
- using System.Text.Json;
- using System.Threading.Tasks;
- using TEAMModelOS.Models;
- using TEAMModelOS.SDK.Models;
- using TEAMModelOS.SDK.DI;
- using TEAMModelOS.SDK.Extension;
- using TEAMModelOS.Filter;
- using TEAMModelOS.SDK.Models.Cosmos;
- using HTEXLib.COMM.Helpers;
- using TEAMModelOS.SDK.Models.Service;
- using Microsoft.Extensions.Configuration;
- using System.Net.Http;
- using TEAMModelOS.SDK;
- using Microsoft.AspNetCore.Authorization;
- using System.Text;
- using static TEAMModelOS.SDK.Models.Teacher;
- namespace TEAMModelOS.Controllers
- {
- [ProducesResponseType(StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status400BadRequest)]
- //
- [Route("tmduser/init")]
- [ApiController]
- public class TmdUserController : ControllerBase
- {
- private readonly AzureCosmosFactory _azureCosmos;
- private readonly AzureStorageFactory _azureStorage;
- private readonly AzureRedisFactory _azureRedis;
- private readonly DingDing _dingDing;
- private readonly Option _option;
- private readonly IConfiguration _configuration;
- private readonly CoreAPIHttpService _coreAPIHttpService;
- private readonly IPSearcher _searcher;
- private readonly HttpTrigger _httpTrigger;
- public TmdUserController(CoreAPIHttpService coreAPIHttpService, AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage, DingDing dingDing, IOptionsSnapshot<Option> option, IConfiguration configuration, IPSearcher searcher, AzureRedisFactory azureRedis, HttpTrigger httpTrigger)
- {
- _azureCosmos = azureCosmos;
- _azureStorage = azureStorage;
- _dingDing = dingDing;
- _option = option?.Value;
- _configuration = configuration;
- _coreAPIHttpService = coreAPIHttpService;
- _searcher = searcher;
- _azureRedis = azureRedis;
- _httpTrigger = httpTrigger;
- }
- [ProducesDefaultResponseType]
- [HttpPost("get-school-info")]
- [Authorize(Roles = "IES")]
- public async Task<IActionResult> GetSchoolInfo(JsonElement request)
- {
- if (!request.TryGetProperty("id_token", out JsonElement id_token)) return BadRequest();
- if (!request.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
- var jwt = new JwtSecurityToken(id_token.GetString());
- if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.Ordinal)) return BadRequest();
- var id = jwt.Payload.Sub;
- var client = _azureCosmos.GetCosmosClient();
- //權限token
- jwt.Payload.TryGetValue("name", out object name);
- jwt.Payload.TryGetValue("picture", out object picture);
- return Ok();
- }
- [ProducesDefaultResponseType]
- [HttpPost("get-tmduser-info")]
-
- #if !DEBUG
- [Authorize(Roles = "IES")]
- #endif
- public async Task<IActionResult> GetTmdUserInfo(JsonElement request)
- {
- try
- {
- if (!request.TryGetProperty("id_token", out JsonElement id_token)) return BadRequest();
- var jwt = new JwtSecurityToken(id_token.GetString());
- if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.OrdinalIgnoreCase)) return BadRequest();
- var id = jwt.Payload.Sub;
- var Schoolid = jwt.Payload.Azp;
- jwt.Payload.TryGetValue("name", out object name);
- jwt.Payload.TryGetValue("picture", out object picture);
- (string ip, string region) = await LoginService.LoginIp(HttpContext, _searcher);
- List<object> schools = new List<object>();
- List<LoginInfo> loginInfos = new();
- string defaultschool = null;
- var client = _azureCosmos.GetCosmosClient();
- try
- {
- TmdUser tmdUser = await client.GetContainer("TEAMModelOS", "Student").ReadItemAsync<TmdUser>(id, new PartitionKey("Base"));
- tmdUser.name = $"{name}";
- tmdUser.picture = $"{picture}";
- if (tmdUser.schools.IsNotEmpty())
- {
- List<TmdUser.School> rm = new List<TmdUser.School>();
- foreach (var sc in tmdUser.schools)
- {
- dynamic schoolExtobj = new ExpandoObject();
- var schoolJson = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync($"{sc.schoolId}", new PartitionKey("Base"));
- if (schoolJson.Status == 200)
- {
- var school = await JsonDocument.ParseAsync(schoolJson.ContentStream);
- schoolExtobj.schoolId = sc.schoolId;
- schoolExtobj.name = school.RootElement.GetProperty("name");
- schoolExtobj.status = sc.status;
- schoolExtobj.time = sc.time;
- schoolExtobj.picture = school.RootElement.GetProperty("picture");
- sc.name = $"{school.RootElement.GetProperty("name")}";
- }
- else
- {
- rm.Add(sc);
- }
- }
- rm.ForEach(x => { tmdUser.schools.Remove(x); });
- tmdUser.defaultSchool = string.IsNullOrEmpty(tmdUser.defaultSchool) ? tmdUser.schools[0].schoolId : tmdUser.defaultSchool;
- }
- loginInfos = tmdUser.loginInfos;
- tmdUser.pk="Base";
- await client.GetContainer("TEAMModelOS", "Student").ReplaceItemAsync<TmdUser>(tmdUser, id, new PartitionKey("Base"));
- //預設學校ID
- defaultschool = tmdUser.defaultSchool;
- }
- catch (CosmosException ex)
- {
- if (ex.Status == 404)
- {
- //如果沒有,則初始化Teacher基本資料到Cosmos
- TmdUser teacher = new TmdUser
- {
- createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
- id = id,
- pk = "Base",
- code = "Base",
- name = name?.ToString(),
- picture = picture?.ToString(),
- defaultSchool = null,
- schools = new List<TmdUser.School>(),
- };
- var container = _azureStorage.GetBlobContainerClient(id);
- await container.CreateIfNotExistsAsync(PublicAccessType.None); //嘗試創建Teacher私有容器,如存在則不做任何事,保障容器一定存在
- teacher = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Student").CreateItemAsync<TmdUser>(teacher, new PartitionKey("Base"));
- }
- }
- int timezone = 8;
- if (HttpContext.Request.Headers.TryGetValue("Time-Zone", out var Time_Zone) && int.TryParse(Time_Zone, out int tz))
- {
- timezone=tz;
- }
-
- //換取AuthToken,提供給前端
- var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, Website: "IES", timezone: timezone, scope: Constant.ScopeTmdUser, roles: new[] { "student" }, expire: 1);
- //用户在线记录
- try
- {
- _ = _httpTrigger.RequestHttpTrigger(new { school = defaultschool, scope = $"{Constant.ScopeTmdUser}", id = $"{id}", ip = $"{ip}", expire = 1 }, _option.Location, "online-record");
- }
- catch { }
- if (!string.IsNullOrEmpty(defaultschool))
- {
- }
- var (blob_uri, blob_sas) = _azureStorage.GetBlobContainerSAS(id, BlobContainerSasPermissions.Write | BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List);
- blob_uri = blob_uri.Replace(id, "");
- blob_sas = "";
- await SystemService.RecordAccumulateData(_azureRedis, _dingDing, new SDK.Models.Dtos.Accumulate { client="web", count=1, id="ies", key="tmdstudent_login", name="醍摩豆账号登录", scope="ies", target="ies" });
- return Ok(new { location = _option.Location, auth_token, schools, defaultschool, blob_uri, blob_sas, status = 200 });
- }
- catch (CosmosException ex)
- {
- await _dingDing.SendBotMsg($"IES5,{_option.Location},Teacher/GetTeacherInfo()\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
- return BadRequest();
- }
- catch (Exception ex)
- {
- request.TryGetProperty("id_token", out JsonElement id_token);
- await _dingDing.SendBotMsg($"IES5,{_option.Location},Teacher/GetTeacherInfo()\n{ex.Message}\n{ex.StackTrace}\n{id_token}", GroupNames.醍摩豆服務運維群組);
- return BadRequest();
- }
- }
- private async Task<(string uri, string sas)> GetSchoolData(string shool)
- {
- // BLOB(學校,唯讀)
- var (blob_uri, blob_sas) = _azureStorage.GetBlobContainerSAS(shool, BlobContainerSasPermissions.Read);
- return (blob_uri, blob_sas);
- }
- [ProducesDefaultResponseType]
- [HttpPost("get-tmd-info")]
- #if !DEBUG
- [Authorize(Roles = "IES")]
- #endif
- public async Task<ActionResult> getTmdInfo(JsonElement request)
- {
- if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
- List<string> ids = id.ToObject<List<string>>();
- List<ufo> tmds = new List<ufo>();
- try
- {
- var content = new StringContent(ids.ToJsonString(), Encoding.UTF8, "application/json");
- string json = await _coreAPIHttpService.GetUserInfos(content);
- if (!string.IsNullOrWhiteSpace(json))
- {
- try
- {
- tmds = json.ToObject<List<ufo>>();
- }
- catch (Exception ex)
- {
- await _dingDing.SendBotMsg($"{_coreAPIHttpService.options.location}用户转换失败:{_coreAPIHttpService.options.coreUrl}{json}\n ", GroupNames.醍摩豆服務運維群組);
- }
- }
- }
- catch (Exception e)
- {
- await _dingDing.SendBotMsg($"IES5,{_option.Location},tmduser/init/getTmdInfo()\n{e.Message}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
- }
- return Ok(tmds);
- }
- }
- }
|