Beispiel #1
0
        /// <summary>
        /// 指定したコミットIDのコミット詳細を取得する。
        /// 対象リポジトリが存在しない場合はnullが返る。
        /// </summary>
        /// <param name="gitMap">Git情報</param>
        /// <param name="repositoryName">リポジトリ名</param>
        /// <param name="owner">オーナー名</param>
        /// <param name="commitId">コミットID</param>
        /// <returns>コミット詳細</returns>
        public async Task <Result <CommitModel, string> > GetCommitByIdAsync(UserTenantGitMap gitMap, string repositoryName, string owner, string commitId)
        {
            // API呼び出しパラメータ作成
            var projectId = await GetProjectIdAsync(gitMap, repositoryName, owner);

            if (projectId.IsSuccess == false)
            {
                return(Result <CommitModel, string> .CreateErrorResult(projectId.Error));
            }

            RequestParam param = CreateRequestParam(gitMap);

            param.ApiPath = $"/api/v4/projects/{projectId.Value}/repository/commits/{commitId}";

            // API 呼び出し
            Result <string, string> response = await this.SendGetRequestAsync(param);

            if (response.IsSuccess)
            {
                var result = JsonConvert.DeserializeObject <GetCommitModel>(response.Value);
                var commit = new CommitModel()
                {
                    CommitId      = result.id,
                    Comment       = result.message,
                    CommitAt      = result.committed_date.ToLocalFormatedString(),
                    CommitterName = result.committer_name
                };
                return(Result <CommitModel, string> .CreateResult(commit));
            }
            else
            {
                LogError(response.Error);
                return(Result <CommitModel, string> .CreateErrorResult(response.Error));
            }
        }
Beispiel #2
0
        /// <summary>
        /// git pullするためのURLを取得する。
        /// </summary>
        public GitEndpointModel GetPullUrl(long gitId, string repositoryName, string owner)
        {
            if (string.IsNullOrEmpty(repositoryName) || string.IsNullOrEmpty(owner))
            {
                return(null);
            }
            UserTenantGitMap map = GetCurrentGitMap(gitId);

            string url    = $"{map.Git.RepositoryUrl}/{owner}/{repositoryName}.git";
            var    result = new GitEndpointModel()
            {
                Url   = url,
                Token = map.GitToken
            };

            if (string.IsNullOrEmpty(map.GitToken))
            {
                result.FullUrl = url;
            }
            else
            {
                // http の場合、以下のようなフォーマットで git clone できる
                //  http://kqi:${token}@${host}/${owner}/${repositoryName}.git
                // ユーザ名がkqiになっているのは、空文字以外の任意文字列を入れないと認証失敗になる問題が発見されたため。
                UriBuilder builder = new UriBuilder(url);
                builder.UserName = "******";
                builder.Password = map.GitToken;
                result.FullUrl   = builder.Uri.ToString();
            }

            return(result);
        }
Beispiel #3
0
 public GitCredentialOutputModel(UserTenantGitMap map)
 {
     Id          = map.Git.Id;
     Name        = map.Git.Name;
     ServiceType = map.Git.ServiceType;
     Token       = map.GitToken;
 }
Beispiel #4
0
        /// <summary>
        /// 指定したコミットIDのコミット詳細を取得する。
        /// 対象リポジトリが存在しない場合はnullが返る。
        /// </summary>
        /// <param name="gitMap">Git情報</param>
        /// <param name="repositoryName">リポジトリ名</param>
        /// <param name="owner">オーナー名</param>
        /// <param name="commitId">コミットID</param>
        /// <returns>コミット詳細</returns>
        public async Task <Result <CommitModel, string> > GetCommitByIdAsync(UserTenantGitMap gitMap, string repositoryName, string owner, string commitId)
        {
            // API呼び出しパラメータ作成
            RequestParam param = CreateRequestParam(gitMap);

            param.ApiPath = $"/repos/{owner}/{repositoryName}/commits/{commitId}";

            // API 呼び出し
            Result <string, string> response = await this.SendGetRequestAsync(param);

            if (response.IsSuccess)
            {
                var result = JsonConvert.DeserializeObject <GetCommitModel>(response.Value);
                var commit = new CommitModel()
                {
                    CommitId      = result.sha,
                    Comment       = result.commit?.message,
                    CommitAt      = result.commit?.author?.date.ToLocalFormatedString(),
                    CommitterName = result.commit?.author?.name
                };
                return(Result <CommitModel, string> .CreateResult(commit));
            }
            else
            {
                return(Result <CommitModel, string> .CreateErrorResult(response.Error));
            }
        }
Beispiel #5
0
        /// <summary>
        /// オーナー名&リポジトリ名から、プロジェクトIDを取得する。
        /// </summary>
        /// <remarks>
        /// GitLab APIではGitで一般的な{オーナー名}/{リポジトリ名}ではなく、プロジェクトIDという独自識別子でリポジトリを特定する。
        /// なので、この変換を行うためのAPI呼び出しが必要。
        /// ちなみに、逆にWebUIを参照する際はオーナー名が必要という仕様。
        /// </remarks>
        private async Task <Result <string, string> > GetProjectIdAsync(UserTenantGitMap gitMap, string repositoryName, string owner)
        {
            //検索上限が100件だが、リポジトリ名でフィルタ(部分一致)をかけて検索するので、そこまでの件数にはならない想定
            RequestParam param = CreateRequestParam(gitMap);

            param.ApiPath     = $"/api/v4/projects";
            param.QueryParams = new Dictionary <string, string>()
            {
                { "search", repositoryName },
                { "per_page", "100" }
            };
            var response = await SendGetRequestAsync(param);

            if (response.IsSuccess)
            {
                //一度GitLabの専用出力モデルに吐き出す
                var result = JsonConvert.DeserializeObject <IEnumerable <GetRepositoryModel> >(response.Value);
                //ロジック層に返すための版用モデルに変換
                var outModel = result.FirstOrDefault(r => r.path_with_namespace == $"{owner}/{repositoryName}");
                if (outModel == null)
                {
                    string message = $"Repository {owner}/{repositoryName} is not found.";
                    LogWarning(message);
                    return(Result <string, string> .CreateErrorResult(message));
                }
                return(Result <string, string> .CreateResult(outModel.id.ToString()));
            }
            else
            {
                LogError(response.Error);
                return(Result <string, string> .CreateErrorResult(response.Error));
            }
        }
Beispiel #6
0
        /// <summary>
        /// オーナー名&リポジトリ名から、プロジェクトIDを取得する。
        /// </summary>
        /// <remarks>
        /// GitLab APIではGitで一般的な{オーナー名}/{リポジトリ名}ではなく、プロジェクトIDという独自識別子でリポジトリを特定する。
        /// なので、この変換を行うためのAPI呼び出しが必要。
        /// ちなみに、逆にWebUIを参照する際はオーナー名が必要という仕様。
        /// </remarks>
        protected async override Task <Result <string, string> > GetProjectIdAsync(UserTenantGitMap gitMap, string repositoryName, string owner)
        {
            // オーナー名&リポジトリ名を指定して取得する
            RequestParam param = CreateRequestParam(gitMap);

            param.ApiPath = $"/api/v4/projects/{owner}%2F{repositoryName}";

            var response = await SendGetRequestAsync(param);

            if (response.IsSuccess)
            {
                //一度GitLabの専用出力モデルに吐き出す
                var result = JsonConvert.DeserializeObject <IEnumerable <GetRepositoryModel> >("[" + response.Value + "]");
                //ロジック層に返すための版用モデルに変換
                var outModel = result.First();
                if (outModel == null)
                {
                    string message = $"Repository {owner}/{repositoryName} is not found.";
                    LogWarning(message);
                    return(Result <string, string> .CreateErrorResult(message));
                }
                return(Result <string, string> .CreateResult(outModel.id.ToString()));
            }
            else
            {
                LogError(response.Error);
                return(Result <string, string> .CreateErrorResult(response.Error));
            }
        }
Beispiel #7
0
        /// <summary>
        /// テナントにGitを紐づける。
        /// 結果として、作成したすべての<see cref="UserTenantGitMap"/>を返す。
        /// テナントの新規作成時であれば、<paramref name="isCreate"/>をTrueにする。
        /// </summary>
        public async Task <IEnumerable <UserTenantGitMap> > AttachGitToTenantAsync(Tenant tenant, Git git, bool isCreate)
        {
            if (git == null)
            {
                //指定がなければ何もしない
                return(null);
            }

            TenantGitMap map = new TenantGitMap()
            {
                Git = git
            };

            List <UserTenantGitMap> maps = null;

            if (isCreate == false) //テナント新規作成時はIDが0の状態なので、判定しない。ユーザも未参加なので何もしない。
            {
                map.TenantId = tenant.Id;

                //既に紐づいていたら何もしない
                bool exist = await ExistsModelAsync <TenantGitMap>(m => m.TenantId == tenant.Id && m.GitId == git.Id);

                if (exist)
                {
                    return(null);
                }

                maps = new List <UserTenantGitMap>();

                //テナントに紐づいているすべてのユーザを取得
                var userMaps = FindModelAll <UserTenantMap>(m => m.TenantId == tenant.Id);
                foreach (var userMap in userMaps)
                {
                    UserTenantGitMap utgMap = new UserTenantGitMap()
                    {
                        TenantGitMap = map,
                        UserId       = userMap.UserId,
                    };

                    //既に同じGitと紐づいていたら、その認証情報を使いまわす
                    var existMap = GetModelAll <UserTenantGitMap>().Include(m => m.TenantGitMap)
                                   .Where(m => m.UserId == userMap.UserId && m.TenantGitMap.GitId == git.Id).FirstOrDefault();
                    if (existMap != null)
                    {
                        utgMap.GitToken = existMap.GitToken;
                    }
                    AddModel <UserTenantGitMap>(utgMap);
                    maps.Add(utgMap);
                }
            }
            else
            {
                map.Tenant = tenant;
            }

            AddModel <TenantGitMap>(map);
            return(maps);
        }
Beispiel #8
0
        /// <summary>
        /// 指定したコミットIDのコミット詳細を取得する。
        /// 失敗した場合はnullを返す。
        /// </summary>
        /// <param name="gitId">Git ID</param>
        /// <param name="repositoryName">リポジトリ名</param>
        /// <param name="owner">オーナー名</param>
        /// <param name="commitId">コミットID</param>
        /// <returns>コミット詳細</returns>
        public async Task <Result <CommitModel, string> > GetCommitAsync(long gitId, string repositoryName, string owner, string commitId)
        {
            UserTenantGitMap map        = GetCurrentGitMap(gitId);
            IGitService      gitService = GetGitService(map?.Git);

            if (gitService != null)
            {
                return(await gitService.GetCommitByIdAsync(map, repositoryName, owner, commitId));
            }
            return(Result <CommitModel, string> .CreateErrorResult("The selected tenant isn't related to proper git service."));;
        }
Beispiel #9
0
        /// <summary>
        /// git pullするためのURLを取得する。
        /// </summary>
        /// <param name="gitId">Git ID</param>
        /// <param name="repositoryName">リポジトリ名</param>
        /// <param name="owner">オーナー名</param>
        /// <returns>git pullするためのURL</returns>
        public async Task <Result <GitEndpointModel, string> > GetPullUrlAsync(long gitId, string repositoryName, string owner, string extraToken)
        {
            if (string.IsNullOrEmpty(repositoryName) || string.IsNullOrEmpty(owner))
            {
                return(Result <GitEndpointModel, string> .CreateResult(null));
            }
            UserTenantGitMap map    = GetCurrentGitMap(gitId);
            string           gitUrl = map.Git.RepositoryUrl.TrimEnd('/');
            string           url    = $"{gitUrl}/{owner}/{repositoryName}.git";
            var orgToken            = map.GitToken;

            try
            {
                if (extraToken != null)
                {
                    map.GitToken = extraToken;
                }
                var result = new GitEndpointModel()
                {
                    Url   = url,
                    Token = map.GitToken
                };
                if (string.IsNullOrEmpty(map.GitToken))
                {
                    result.FullUrl = url;
                }
                else
                {
                    // http の場合、以下のようなフォーマットで git clone できる
                    //  http://${user}:${token}@${host}/${owner}/${repositoryName}.git
                    IGitService gitService     = GetGitService(map?.Git);
                    var         userNameResult = await gitService.GetUserNameByTokenAsync(map);

                    if (!userNameResult.IsSuccess)
                    {
                        return(Result <GitEndpointModel, string> .CreateErrorResult(userNameResult.Error));
                    }
                    if (userNameResult.Value == null)
                    {
                        return(Result <GitEndpointModel, string> .CreateErrorResult("invalid git service response"));
                    }

                    UriBuilder builder = new UriBuilder(url);
                    builder.UserName = userNameResult.Value;
                    builder.Password = map.GitToken;
                    result.FullUrl   = builder.Uri.ToString();
                }
                return(Result <GitEndpointModel, string> .CreateResult(result));
            }
            finally
            {
                map.GitToken = orgToken;
            }
        }
Beispiel #10
0
 /// <summary>
 /// 共通で使うパラメータを生成
 /// </summary>
 private RequestParam CreateRequestParam(UserTenantGitMap gitMap)
 {
     return(new RequestParam()
     {
         BaseUrl = gitMap.Git.ApiUrl,
         UserAgent = "C#App",
         Headers = new Dictionary <string, string>()
         {
             { "Private-Token", gitMap.GitToken } //GitLabはトークンの形式がBearerではないので、ヘッダに独自で追加
         }
     });
 }
Beispiel #11
0
        /// <summary>
        /// 共通で使うパラメータを生成
        /// </summary>
        /// <param name="gitMap">Git情報</param>
        /// <returns>リクエストパラメータ</returns>
        private RequestParam CreateRequestParam(UserTenantGitMap gitMap)
        {
            RequestParam param = new RequestParam()
            {
                BaseUrl = gitMap.Git.ApiUrl,
                //Proxy = options.Proxy, // API Server からのアクセスは特にコード内では制御せず、OS設定に任せる
                Token     = gitMap.GitToken,
                UserAgent = "C#App"
            };

            return(param);
        }
Beispiel #12
0
        /// <summary>
        /// 共通で使うパラメータを生成
        /// </summary>
        /// <param name="gitMap">Git情報</param>
        /// <returns>リクエストパラメータ</returns>
        protected override RequestParam CreateRequestParam(UserTenantGitMap gitMap)
        {
            RequestParam param = new RequestParam()
            {
                BaseUrl   = gitMap.Git.ApiUrl.TrimEnd('/') + "/api/v3",
                Token     = gitMap.GitToken,
                UserAgent = "C#App",
                TokenType = "token",
            };

            return(param);
        }
Beispiel #13
0
        /// <summary>
        /// リポジトリ一覧を取得する。
        /// </summary>
        /// <param name="gitId">Git ID</param>
        /// <returns>リポジトリ一覧</returns>
        public async Task <Result <IEnumerable <RepositoryModel>, string> > GetAllRepositoriesAsync(long gitId)
        {
            UserTenantGitMap map        = GetCurrentGitMap(gitId);
            IGitService      gitService = GetGitService(map?.Git);

            if (gitService != null)
            {
                return(await gitService.GetAllRepositoriesAsync(map));
            }
            else
            {
                return(Result <IEnumerable <RepositoryModel>, string> .CreateErrorResult("The selected tenant isn't related to proper git service."));
            }
        }
Beispiel #14
0
        /// <summary>
        /// コミット一覧を取得する。
        /// </summary>
        /// <param name="gitId">Git ID</param>
        /// <param name="repositoryName">リポジトリ名</param>
        /// <param name="owner">オーナー名</param>
        /// <param name="branchName">ブランチ名</param>
        /// <returns>コミット一覧</returns>
        public async Task <Result <IEnumerable <CommitModel>, string> > GetAllCommitsAsync(long gitId, string repositoryName, string owner, string branchName)
        {
            UserTenantGitMap map        = GetCurrentGitMap(gitId);
            IGitService      gitService = GetGitService(map?.Git);

            if (gitService != null)
            {
                return(await gitService.GetAllCommitsAsync(map, repositoryName, owner, branchName));
            }
            else
            {
                return(Result <IEnumerable <CommitModel>, string> .CreateErrorResult("The selected tenant isn't related to proper git service."));
            }
        }
Beispiel #15
0
        /// <summary>
        /// コミット内容のTree表示を参照できるWebUI URLを取得する。
        /// ページがない場合nullが返る。
        /// </summary>
        public string GetTreeUiUrl(long gitId, string repositoryName, string owner, string commitId)
        {
            if (string.IsNullOrEmpty(repositoryName) || string.IsNullOrEmpty(owner) || string.IsNullOrEmpty(commitId))
            {
                return(null);
            }
            UserTenantGitMap map        = GetCurrentGitMap(gitId);
            IGitService      gitService = GetGitService(map?.Git);

            if (gitService != null)
            {
                //今のところ全GitサービスでURLが共通なので、サービス層ではなくロジック層で作って返す
                return($"{map.Git.RepositoryUrl}/{owner}/{repositoryName}/tree/{commitId}");
            }
            return(null);
        }
Beispiel #16
0
        /// <summary>
        /// 指定したブランチ名のHEADリビジョンに一致するコミットIDを取得する。
        /// 失敗した場合はnullを返す。
        /// </summary>
        /// <param name="gitId">Git ID</param>
        /// <param name="repositoryName">リポジトリ名</param>
        /// <param name="owner">オーナー名</param>
        /// <param name="branchName">ブランチ名</param>
        /// <returns>コミットID</returns>
        public async Task <string> GetCommitIdAsync(long gitId, string repositoryName, string owner, string branchName)
        {
            UserTenantGitMap map        = GetCurrentGitMap(gitId);
            IGitService      gitService = GetGitService(map?.Git);

            if (gitService != null)
            {
                var commit = await gitService.GetCommitAsync(map, repositoryName, owner, branchName);

                if (commit.IsSuccess)
                {
                    return(commit.Value.CommitId);
                }
            }
            return(null);
        }
Beispiel #17
0
        public async Task <Result <string, string> > GetUserNameByTokenAsync(UserTenantGitMap gitMap)
        {
            // API呼び出しパラメータ作成
            RequestParam param = CreateRequestParam(gitMap);

            param.ApiPath = $"/api/v4/user";

            // API 呼び出し
            Result <string, string> response = await this.SendGetRequestAsync(param);

            if (response.IsSuccess)
            {
                var result = JsonConvert.DeserializeObject <GetUserModel>(response.Value);

                return(Result <string, string> .CreateResult(result.username));
            }
            else
            {
                return(Result <string, string> .CreateErrorResult(response.Error));
            }
        }
Beispiel #18
0
        /// <summary>
        /// コミット一覧を取得する。
        /// 対象リポジトリが存在しない場合はnullが返る。
        /// </summary>
        /// <param name="gitMap">Git情報</param>
        /// <param name="repositoryName">リポジトリ名</param>
        /// <param name="owner">オーナー名</param>
        /// <param name="branchName">ブランチ名</param>
        /// <returns>コミット一覧</returns>
        public async Task <Result <IEnumerable <CommitModel>, string> > GetAllCommitsAsync(UserTenantGitMap gitMap, string repositoryName, string owner, string branchName)
        {
            // API呼び出しパラメータ作成
            RequestParam param = CreateRequestParam(gitMap);

            param.ApiPath = $"/repos/{owner}/{repositoryName}/commits";
            if (string.IsNullOrEmpty(branchName) == false)
            {
                param.QueryParams = new Dictionary <string, string>
                {
                    { "sha", branchName }
                };
            }

            // API 呼び出し
            Result <string, string> response = await this.SendGetRequestAsync(param);

            if (response.IsSuccess)
            {
                var result = JsonConvert.DeserializeObject <IEnumerable <GetCommitModel> >(response.Value);
                return(Result <IEnumerable <CommitModel>, string> .CreateResult(
                           result.Select(e => new CommitModel()
                {
                    CommitId = e.sha,
                    Comment = e.commit?.message,
                    CommitAt = e.commit?.author?.date.ToLocalFormatedString(),
                    CommitterName = e.commit?.author?.name
                })));
            }
            else
            {
                return(Result <IEnumerable <CommitModel>, string> .CreateErrorResult(response.Error));
            }
        }
Beispiel #19
0
        /// <summary>
        /// リポジトリ一覧を取得する。
        /// </summary>
        /// <returns>リポジトリ一覧</returns>
        public async override Task <Result <IEnumerable <RepositoryModel>, string> > GetAllRepositoriesAsync(UserTenantGitMap gitMap)
        {
            await Task.CompletedTask;

            // GitLab.comはトークンに関係なく、Publicリポジトリ(10,000件を超える)も取得するので一覧は取得しない
            // ユーザに手入力で設定させるため空のリストを返す
            return(Result <IEnumerable <RepositoryModel>, string> .CreateResult(new List <RepositoryModel>()));
        }
Beispiel #20
0
        /// <summary>
        /// リポジトリ一覧を取得する。
        /// 特に範囲は限定せず、<see cref="Git.Token"/>の権限で参照可能なすべてのリポジトリが対象となる。
        /// </summary>
        /// <param name="gitMap">Git情報</param>
        /// <returns>リポジトリ一覧</returns>
        public async Task <Result <IEnumerable <RepositoryModel>, string> > GetAllRepositoriesAsync(UserTenantGitMap gitMap)
        {
            if (string.IsNullOrEmpty(gitMap.GitToken))
            {
                //トークンが設定されていない場合、GitHubのリポジトリ一覧は取得できない
                //なので空の結果を返す

                return(Result <IEnumerable <RepositoryModel>, string> .CreateResult(new List <RepositoryModel>()));
            }

            // API呼び出しパラメータ作成
            RequestParam param = CreateRequestParam(gitMap);

            param.ApiPath = $"/user/repos";

            // API 呼び出し
            Result <string, string> response = await this.SendGetRequestAsync(param);

            if (response.IsSuccess)
            {
                var result = JsonConvert.DeserializeObject <IEnumerable <GetRepositoryModel> >(response.Value);
                return(Result <IEnumerable <RepositoryModel>, string> .CreateResult(
                           result.Select(e => new RepositoryModel()
                {
                    Owner = e.owner.login,         //GitHubではAPI実行にそのリポジトリのオーナー名が必要なので、それをKeyに入れる
                    Name = e.name,
                    FullName = e.full_name,
                }).OrderBy(e => e.FullName)));
            }
            else
            {
                return(Result <IEnumerable <RepositoryModel>, string> .CreateErrorResult(response.Error));
            }
        }
Beispiel #21
0
        /// <summary>
        /// リポジトリ一覧を取得する。
        /// 特に範囲は限定せず、<see cref="Git.Token"/>の権限で参照可能なすべてのリポジトリが対象となる。
        /// </summary>
        /// <returns>リポジトリ一覧</returns>
        public async Task <Result <IEnumerable <RepositoryModel>, string> > GetAllRepositoriesAsync(UserTenantGitMap gitMap)
        {
            var response = await SendGetFullPageRequestsAsync <GetRepositoryModel>("/api/v4/projects", gitMap, new Dictionary <string, string>());

            if (response.IsSuccess)
            {
                //ロジック層に返すための版用モデルに変換
                var outModel = response.Value.Select(e => new RepositoryModel()
                {
                    Name     = e.path, // e.nameは表示そのまま(スペースが入りうる)なので、pathからとる
                    FullName = e.path_with_namespace,
                    Owner    = e.RepositoryOwner,
                }).OrderBy(e => e.FullName);
                return(Result <IEnumerable <RepositoryModel>, string> .CreateResult(outModel));
            }
            else
            {
                LogError(response.Error);
                return(Result <IEnumerable <RepositoryModel>, string> .CreateErrorResult(response.Error));
            }
        }
Beispiel #22
0
        /// <summary>
        /// GitLabは一度に100件しか結果を返してくれない。
        /// なので必要な数だけページングしながら結果を書き集めてくる。
        /// 引数の<paramref name="queryParams"/>は中で都度書き換えられるので注意。
        /// </summary>
        private async Task <Result <List <T>, string> > SendGetFullPageRequestsAsync <T>(string apiPath, UserTenantGitMap gitMap, Dictionary <string, string> queryParams)
        {
            RequestParam param = CreateRequestParam(gitMap);

            param.ApiPath     = apiPath;
            param.QueryParams = queryParams;
            queryParams.Add("per_page", "10");
            queryParams.Add("page", "0"); //ダミーの数字を入れておく

            //ページ番号は1から始まるので、その手前で初期化
            int page = 0;

            List <T> outModel = new List <T>();

            do
            {
                page++;
                queryParams["page"] = page.ToString();

                var response = await SendRequestAsync(HttpMethod.Get, param);

                if (response.IsSuccessStatusCode)
                {
                    string content = await response.Content.ReadAsStringAsync();

                    //一度GitLabの専用出力モデルに吐き出す
                    var result = JsonConvert.DeserializeObject <List <T> >(content);
                    //結果をマージ
                    outModel.AddRange(result);

                    int totalPages = int.Parse(response.Headers.First(h => h.Key == "X-Total-Pages").Value.First());
                    if (totalPages <= page)
                    {
                        return(Result <List <T>, string> .CreateResult(outModel));
                    }
                }
                else
                {
                    //一度でも失敗したらエラー
                    string errorMessage = await GetResultFromHttpResponseAsync(response, true);

                    LogError(errorMessage);
                    return(Result <List <T>, string> .CreateErrorResult(errorMessage));
                }
            }while (true);
        }
Beispiel #23
0
        /// <summary>
        /// コミット一覧を取得する。
        /// 対象リポジトリが存在しない場合はnullが返る。
        /// すべて取ってくると件数が多すぎると想定されるため、最大100件固定。
        /// </summary>
        /// <param name="gitMap">Git情報</param>
        /// <param name="repositoryName">リポジトリ名</param>
        /// <param name="owner">オーナー名</param>
        /// <param name="branchName">ブランチ名</param>
        /// <returns>コミット一覧</returns>
        public async Task <Result <IEnumerable <CommitModel>, string> > GetAllCommitsAsync(UserTenantGitMap gitMap, string repositoryName, string owner, string branchName)
        {
            var projectId = await GetProjectIdAsync(gitMap, repositoryName, owner);

            if (projectId.IsSuccess == false)
            {
                //プロジェクトIDがない=ブランチが一つもない=という事なので、nullを返却
                return(Result <IEnumerable <CommitModel>, string> .CreateResult(null));
            }

            RequestParam param = CreateRequestParam(gitMap);

            param.ApiPath = $"/api/v4/projects/{projectId.Value}/repository/commits";
            if (string.IsNullOrEmpty(branchName) == false)
            {
                param.QueryParams = new Dictionary <string, string>
                {
                    { "ref_name", branchName },
                    { "per_page", "100" } //指定しない場合は20件になるので、100件まで拡張
                };
            }

            var response = await SendGetRequestAsync(param);

            if (response.IsSuccess)
            {
                var result = JsonConvert.DeserializeObject <IEnumerable <GetCommitModel> >(response.Value);
                return(Result <IEnumerable <CommitModel>, string> .CreateResult(
                           result.Select(e => new CommitModel()
                {
                    CommitId = e.id,
                    Comment = e.message,
                    CommitAt = e.committed_date.ToLocalFormatedString(),
                    CommitterName = e.committer_name
                })));
            }
            else
            {
                LogError(response.Error);
                return(Result <IEnumerable <CommitModel>, string> .CreateErrorResult(response.Error));
            }
        }
Beispiel #24
0
        /// <summary>
        /// ブランチ一覧を取得する。
        /// 対象リポジトリが存在しない場合はnullが返る。
        /// </summary>
        /// <param name="gitMap">Git情報</param>
        /// <param name="repositoryName">リポジトリ名</param>
        /// <param name="owner">オーナー名</param>
        /// <returns>ブランチ一覧</returns>
        public async Task <Result <IEnumerable <BranchModel>, string> > GetAllBranchesAsync(UserTenantGitMap gitMap, string repositoryName, string owner)
        {
            var projectId = await GetProjectIdAsync(gitMap, repositoryName, owner);

            if (projectId.IsSuccess == false)
            {
                //プロジェクトIDがない=ブランチが一つもない=という事なので、nullを返却
                return(Result <IEnumerable <BranchModel>, string> .CreateResult(null));
            }
            RequestParam param   = CreateRequestParam(gitMap);
            string       apiPath = $"/api/v4/projects/{projectId.Value}/repository/branches";

            var response = await SendGetFullPageRequestsAsync <GetBranchModel>(apiPath, gitMap, new Dictionary <string, string>());

            if (response.IsSuccess)
            {
                return(Result <IEnumerable <BranchModel>, string> .CreateResult(
                           response.Value.Select(e => new BranchModel()
                {
                    BranchName = e.name,
                    CommitId = e.commit?.id
                })));
            }
            else
            {
                LogError(response.Error);
                return(Result <IEnumerable <BranchModel>, string> .CreateErrorResult(response.Error));
            }
        }
Beispiel #25
0
        /// <summary>
        /// ブランチ一覧を取得する。
        /// 対象リポジトリが存在しない場合はnullが返る。
        /// </summary>
        /// <param name="gitMap">Git情報</param>
        /// <param name="repositoryName">リポジトリ名</param>
        /// <param name="owner">オーナー名</param>
        /// <returns>ブランチ一覧</returns>
        public async Task <Result <IEnumerable <BranchModel>, string> > GetAllBranchesAsync(UserTenantGitMap gitMap, string repositoryName, string owner)
        {
            // API呼び出しパラメータ作成
            RequestParam param = CreateRequestParam(gitMap);

            param.ApiPath = $"/repos/{owner}/{repositoryName}/branches";

            // API 呼び出し
            Result <string, string> response = await this.SendGetRequestAsync(param);

            if (response.IsSuccess)
            {
                var result = JsonConvert.DeserializeObject <IEnumerable <GetBranchModel> >(response.Value);
                return(Result <IEnumerable <BranchModel>, string> .CreateResult(
                           result.Select(e => new BranchModel()
                {
                    BranchName = e.name,
                    CommitId = e.commit?.sha
                })));
            }
            else
            {
                return(Result <IEnumerable <BranchModel>, string> .CreateErrorResult(response.Error));
            }
        }
        /// <summary>
        /// ユーザをテナントに所属させる。
        /// ユーザIDやテナントIDの存在チェックは行わない。
        /// 結果として、作成したすべての<see cref="UserTenantRegistryMap"/>を返す。
        /// </summary>
        /// <param name="user">対象ユーザ</param>
        /// <param name="tenantId">対象テナントID</param>
        /// <param name="roles">テナントロール</param>
        /// <exception cref="ArgumentException"><paramref name="roles"/>にシステムロールが含まれていたり、別テナント用のロールが含まれていた場合</exception>
        public IEnumerable <UserTenantRegistryMap> AttachTenant(User user, long tenantId, IEnumerable <Role> roles)
        {
            var tenantMap = new UserTenantMap()
            {
                TenantId = tenantId,
                User     = user
            };

            AddModel <UserTenantMap>(tenantMap);
            if (roles != null)
            {
                foreach (var role in roles)
                {
                    if (role == null)
                    {
                        continue;
                    }
                    if (role.IsSystemRole)
                    {
                        //Adminロールを特定テナントに所属させようとしている
                        throw new UnauthorizedAccessException($"The tenant role {role.Name} is not assigned to a user as a system role.");
                    }
                    var roleMap = new UserRoleMap()
                    {
                        RoleId    = role.Id,
                        TenantMap = tenantMap,
                        User      = user
                    };
                    AddModel <UserRoleMap>(roleMap);
                }
            }

            //まずはGitの登録
            //テナントに紐づいているすべてのGitを取得
            var GitMaps = FindModelAll <TenantGitMap>(m => m.TenantId == tenantId).Include(m => m.Git);

            foreach (var GitMap in GitMaps)
            {
                UserTenantGitMap utrMap = new UserTenantGitMap()
                {
                    TenantGitMap = GitMap,
                    UserId       = user.Id
                };

                // 既存の認証情報存在チェック
                var existMap = GetModelAll <UserTenantGitMap>()
                               .Where(m => m.UserId == user.Id && m.TenantGitMapId == GitMap.Id).FirstOrDefault();
                if (existMap != null)
                {
                    // 既存の認証情報が存在する場合、再設定する
                    utrMap.GitToken = existMap.GitToken;
                }
                else
                {
                    // UserTenantGitMap において userId と TenantGitMapId のペアが存在しなければ、エントリ新規追加のためログに出力する
                    LogDebug($"UserTenantGitMap エントリの新規追加 : UserId={user.Id}, TenantGitMapId={GitMap.Id}, TenantId={tenantId}, GitId={GitMap.GitId}");
                }

                AddModel <UserTenantGitMap>(utrMap);
            }

            //続いてレジストリの登録
            //レジストリ登録はクラスタ管理サービスへも影響するので、作成したMapを全て返す

            List <UserTenantRegistryMap> maps = new List <UserTenantRegistryMap>();

            //テナントに紐づいているすべてのレジストリを取得
            var registryMaps = FindModelAll <TenantRegistryMap>(m => m.TenantId == tenantId).Include(m => m.Registry);

            foreach (var registryMap in registryMaps)
            {
                UserTenantRegistryMap utrMap = new UserTenantRegistryMap()
                {
                    TenantRegistryMap = registryMap,
                    UserId            = user.Id
                };

                // 既存の認証情報存在チェック
                var existMap = GetModelAll <UserTenantRegistryMap>()
                               .Where(m => m.UserId == user.Id && m.TenantRegistryMapId == registryMap.Id).FirstOrDefault();
                if (existMap != null)
                {
                    // 既存の認証情報が存在する場合、再設定する
                    utrMap.RegistryUserName = existMap.RegistryUserName;
                    utrMap.RegistryPassword = existMap.RegistryPassword;
                }

                AddModel <UserTenantRegistryMap>(utrMap);
                maps.Add(utrMap);
            }
            return(maps);
        }