// GitLab のユーザーメンテナンス async Task Loop1_MainteUsersAsync(CancellationToken cancel = default) { long lastHookTick = -1; List <GitLabMainteClient.User> lastPendingUsers = new List <GitLabMainteClient.User>(); while (cancel.IsCancellationRequested == false) { // 新規申請中のユーザーが増えたらメールで知らせる try { // ユーザーの列挙 var users = await this.GitLabClient.EnumUsersAsync(cancel); var pendingUsers = users.Where(x => x.IsSystemUser() == false && x.state == "blocked_pending_approval").OrderBy(x => x.id); var newPendingUsers = pendingUsers.Where(u => lastPendingUsers.Where(a => a.id == u.id).Any() == false); StringWriter w = new StringWriter(); string url = this.Settings.GitLabClientSettings.GitLabBaseUrl._CombineUrl("/admin/users?filter=blocked_pending_approval").ToString(); string subject = $"{url._ParseUrl().Host} にユーザー {newPendingUsers.Select(x => ("[" + x.commit_email._NonNullTrim() + " " + x.name + " " + x.username + "]"))._Combine(" ,")} の参加申請がありました"; w.WriteLine(subject + "。"); w.WriteLine(); w.WriteLine($"GitLab のアドレス: {url}"); w.WriteLine(); w.WriteLine($"現在時刻: {DtOffsetNow._ToDtStr()}"); w.WriteLine(); w.WriteLine($"新しい申請中のユーザー ({newPendingUsers.Count()}):"); int num = 0; foreach (var user in newPendingUsers) { lastPendingUsers.Add(user._CloneDeep()); w.WriteLine("- " + user.name + " " + user.username + " " + user.commit_email); num++; } w.WriteLine(); w.WriteLine($"現在申請中のユーザー一覧 ({pendingUsers.Count()})"); foreach (var user in pendingUsers) { w.WriteLine("- " + user.name + " " + user.username + " " + user.commit_email); } w.WriteLine(); w.WriteLine($"GitLab のアドレス: {url}"); w.WriteLine(); w.WriteLine(); //Dbg.Where(); if (num >= 1) { await this.SendMailAsync(subject, w.ToString(), cancel); } } catch (Exception ex) { ex._Error(); } // すべてのユーザーをデフォルトグループに自動追加する try { await this.JoinAllUsersToSpecificGroupAsync(this.Settings.DefaultGroupsAllUsersWillJoin, cancel); } catch (Exception ex) { ex._Error(); } await TaskUtil.AwaitWithPollAsync(this.Settings.UsersListMainteIntervalMsecs, 500, () => { long currentHookTick = this.HookFiredTick; if (lastHookTick != currentHookTick) { lastHookTick = currentHookTick; return(true); } return(false); }, cancel, true); } }
public override async Task FlushAsync(bool halfFlush = false, CancellationToken cancel = default) { List <string> linesToSend; List <string> lines2ToSend; try { if (MyLocalIp == null) { MyLocalIp = await GetMyPrivateIpNativeUtil.GetMyPrivateIpAsync(IPVersion.IPv4); } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } if (MyIpInfo == null) { try { await using GetMyIpClient c = new GetMyIpClient(); MyIpInfo = await c.GetMyIpInfoAsync(IPVersion.IPv4, cancel); } catch { } } string globalInfo = "(Unknown)"; if (MyIpInfo != null) { if (MyIpInfo.GlobalFqdn._IsSamei(MyIpInfo.GlobalIpAddress.ToString())) { globalInfo = MyIpInfo.GlobalFqdn; } else { globalInfo = $"{MyIpInfo.GlobalFqdn} - {MyIpInfo.GlobalIpAddress}"; } } lock (this.Lock) { if (this.Lines.Count == 0 && this.Lines2.Count == 0) { return; } linesToSend = this.Lines; lines2ToSend = this.Lines2; this.Lines = new List <string>(); this.Lines2 = new List <string>(); } string cmdName = CoresLib.Report_CommandName; if (cmdName._IsEmpty()) { cmdName = "Unknown"; } string resultStr = CoresLib.Report_SimpleResult._OneLine(); if (resultStr._IsEmpty()) { resultStr = "Ok"; } StringWriter w = new StringWriter(); w.WriteLine($"Reported: {DtOffsetNow._ToDtStr()}"); w.WriteLine($"Program: {CoresLib.AppName} Built: {Env.BuildTimeStamp._ToDtStr()}"); w.WriteLine($"Hostname: {Env.DnsFqdnHostName}"); w.WriteLine($"Global: {globalInfo}, Local: {MyLocalIp}"); w.WriteLine($"Command: {cmdName}, Result: {(CoresLib.Report_HasError ? "*Error* - " : "OK - ")}{resultStr}"); if (lines2ToSend.Count >= 1) { w.WriteLine("====================="); w.WriteLine(); lines2ToSend.ForEach(x => w.WriteLine(x)); w.WriteLine(); } if (linesToSend.Count >= 1) { w.WriteLine("--------------------"); w.WriteLine(); linesToSend.ForEach(x => w.WriteLine(x)); w.WriteLine(); } w.WriteLine("--------------------"); EnvInfoSnapshot snapshot = new EnvInfoSnapshot(); snapshot.CommandLine = ""; w.WriteLine($"Program Details: {snapshot._GetObjectDump()}"); w.WriteLine(); string subject = $"Report - {cmdName}{(CoresLib.Report_HasError ? " *Error*" : "")} - {linesToSend.Count} lines - {Env.DnsHostName} - {MyLocalIp} ({globalInfo}): {resultStr._NormalizeSoftEther(true)._TruncStrEx(60)}"; var hostAndPort = this.Settings.SmtpServer._ParseHostnaneAndPort(Consts.Ports.Smtp); SmtpConfig cfg = new SmtpConfig(hostAndPort.Item1, hostAndPort.Item2, this.Settings.SmtpUseSsl, this.Settings.SmtpUsername, this.Settings.SmtpPassword); Console.WriteLine("Report Subject: " + subject); try { Console.WriteLine($"SMTP Log Sending to '{this.Settings.MailTo}' ..."); await TaskUtil.RetryAsync(async() => { await SmtpUtil.SendAsync(cfg, this.Settings.MailFrom, this.Settings.MailTo, subject, w.ToString(), false, cancel); return(0); }, 1000, 3, cancel : cancel, randomInterval : true); Console.WriteLine("SMTP Log Sent."); } catch (Exception ex) { Console.WriteLine("SMTP Log Send Error: " + ex.ToString()); } }
// 商用サービス開発者向け: サーバー情報の取得、アクティベーション、アクティベーション解除処理 public async Task <ThinControllerRpcServerObjectInfo?> Paid_GetOrSetServerObjectInfoAsync(string hostKey, bool?newState = null, string tag = "", CancellationToken cancel = default) { hostKey = hostKey._NonNullTrim()._NormalizeHexString(); // データベースエラー時は処理禁止 if (IsDatabaseConnected == false) { throw new VpnException(VpnError.ERR_TEMP_ERROR); } await using var db = await OpenDatabaseForWriteAsync(cancel); // この関数は同時に 1 ユーザーからしか実行されないようにする (高負荷防止のため) using var asyncLock = await RenamePcidAsyncLock.LockWithAwait(cancel); ThinControllerRpcServerObjectInfo?ret = null; await db.TranAsync(async() => { var machine = await db.EasySelectSingleAsync <ThinDbMachine>("select * from MACHINE where CERT_HASH = @CERT_HASH", new { CERT_HASH = hostKey, }, false, true, cancel); if (machine == null) { return(false); } var oldStatus = this.Controller.Paid_CalcServerLicenseStatus(machine.PCID, machine.JSON_ATTRIBUTES, machine.FIRST_CLIENT_DATE._AsDateTimeOffset(true, true)); if (newState.HasValue == false || newState.Value == oldStatus.IsCurrentActivated) { // 状態の変更なし ret = oldStatus; return(false); } bool activate = newState.Value; EasyJsonStrAttributes json = new EasyJsonStrAttributes(machine.JSON_ATTRIBUTES); json["Paid_IsCurrentActivated"] = activate._ToBoolStrLower(); if (activate) { json["Paid_ActivatedOnceInPast"] = true._ToBoolStrLower(); json["Paid_ActivatedDateTime"] = DtOffsetNow._ToDtStr(true); } else { json["Paid_DeactivatedDateTime"] = DtOffsetNow._ToDtStr(true); } json["Paid_Tag"] = tag; string newJsonStr = json.ToString(); var newStatus = this.Controller.Paid_CalcServerLicenseStatus(machine.PCID, newJsonStr, machine.FIRST_CLIENT_DATE._AsDateTimeOffset(true, true)); int i = await db.EasyExecuteAsync("update MACHINE set JSON_ATTRIBUTES = @JSON_ATTRIBUTES where CERT_HASH = @CERT_HASH", new { JSON_ATTRIBUTES = newJsonStr, CERT_HASH = machine.CERT_HASH, }); if (i != 1) { throw new CoresLibException("Database update error. i != 1."); } await this.AddApiLogAsync(db, activate ? "Activate" : "Deactivate", new { UniqueId = machine.CERT_HASH, Pcid = machine.PCID, OldStatus = oldStatus, NewStatus = newStatus, }); ret = newStatus; return(true); }); return(ret); }