// 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);
        }
    }
Beispiel #2
0
    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);
    }