public string Commit(CommitObject commits, [FromUri] string token) { string apikey = string.Empty; string result = string.Empty; CurrentUser = new UserDto(new User() { ProjectGroups = new List <ProjectGroupMembership>() { new ProjectGroupMembership() { ProjectGroupId = Countersoft.Gemini.Commons.Constants.GlobalGroupAdministrators, UserId = 0 } } }); UserContext.User = CurrentUser; PermissionsManager = PermissionsManager.Copy(CurrentUser); UserContext.PermissionsManager = PermissionsManager; if (Request.Headers.Authorization != null && Request.Headers.Authorization.Parameter != null) { var authDetails = Encoding.Default.GetString(Convert.FromBase64String(Request.Headers.Authorization.Parameter)).Split(':'); if (authDetails.Length == 2) { apikey = authDetails[0]; } } else if (token != null) { apikey = token; } if (apikey.Length == 0 || GeminiApp.Config.ApiKey.Length == 0 || !apikey.StartsWith(GeminiApp.Config.ApiKey, StringComparison.InvariantCultureIgnoreCase)) { string error; if (GeminiApp.Config.ApiKey.Length == 0) { error = "Web.config is missing API key"; } else { error = "Wrong API key: " + apikey; } GeminiApp.LogException(new Exception(error) { Source = SourceControlProvider.GitHub.ToString() }, false); return(error); } if (commits == null) { try { var body = Request.Content.ReadAsStringAsync(); body.Wait(); GeminiApp.LogException("Null CodeCommit", string.Concat("Null CodeCommit - ", body.Result), false); } catch { try { GeminiApp.LogException("Null CodeCommit", "Null CodeCommit - Empty!", false); } catch { } } return(string.Empty); } foreach (var commit in commits.commits) { Regex ex = new Regex("GEM:(?<issueid>[0-9]+)", RegexOptions.IgnoreCase); MatchCollection matches = ex.Matches(commit.message); if (matches.Count > 0) { var baseUrl = commits.repository.url.ReplaceIgnoreCase("https://github.com/", "https://api.github.com/"); List <string> filesModified = new List <string>(); var commitIndex = commit.url.IndexOf("commit"); if (commitIndex != -1) { var url = string.Concat(commit.url.Remove(commitIndex, commit.url.Length - commitIndex), "blob/master/"); for (int i = 0; i < commit.added.Length; i++) { filesModified.Add(string.Concat("{\"Filename\":\"", commit.added[i], "\", \"FileId\":\"", string.Empty, "\",\"PreviousFileRevisionId\":\"", string.Empty, "\" }")); } for (int i = 0; i < commit.modified.Length; i++) { filesModified.Add(string.Concat("{\"Filename\":\"", commit.modified[i], "\",\"FileId\":\"", string.Empty, "\",\"PreviousFileRevisionId\":\"", string.Empty, "\"}")); } for (int i = 0; i < commit.removed.Length; i++) { filesModified.Add(string.Concat("{\"Filename\":\"", commit.removed[i], "\",\"FileId\":\"", string.Empty, "\",\"PreviousFileRevisionId\":\"", string.Empty, "\"}")); } } CodeCommit codeCommit = new CodeCommit(); codeCommit.Provider = SourceControlProvider.GitHub; codeCommit.Comment = commit.message; codeCommit.Fullname = commit.author.name; codeCommit.Data = string.Concat("{\"RevisionId\":\"", commit.id, "\",\"PreviousRevisionId\":\"", string.Empty, "\",\"Files\":[", string.Join(",", filesModified.ToArray()), "],\"RepositoryName\":\"", commits.repository.name, "\",\"RepositoryUrl\":\"", baseUrl, "\",\"IsPrivate\":\"", commits.repository.PRIVATE, "\"}"); commit.message = ex.Replace(commit.message, string.Empty); List <int> issuesAlreadyProcessed = new List <int>(); foreach (Match match in matches) { var issue = IssueManager.Get(match.ToString().Remove(0, 4).ToInt()); if (issue != null && !issuesAlreadyProcessed.Contains(issue.Id)) { codeCommit.IssueId = issue.Id; GeminiContext.CodeCommits.Create(codeCommit); issuesAlreadyProcessed.Add(issue.Id); try { if (match.Index + match.Length + 1 + 5 <= codeCommit.Comment.Length) { var time = codeCommit.Comment.Substring(match.Index + match.Length + 1, 5); var timeEx = new System.Text.RegularExpressions.Regex("[0-9][0-9]:[0-9][0-9]"); var m = timeEx.Match(time); if (m.Success) { // Okay, log time! var timeTypes = MetaManager.TimeTypeGetAll(issue.Project.TemplateId); if (timeTypes.Count > 0) { // Let's try and find the user var user = commit.author.email.HasValue() ? Cache.Users.Find(u => u.Username.Equals(commit.author.email, StringComparison.InvariantCultureIgnoreCase) || u.Email.Equals(commit.author.email, StringComparison.InvariantCultureIgnoreCase) || u.Fullname.Equals(commit.author.email, StringComparison.InvariantCultureIgnoreCase)) : null; if (user == null) { user = commit.author.name.HasValue() ? Cache.Users.Find(u => u.Username.Equals(commit.author.name, StringComparison.InvariantCultureIgnoreCase) || u.Email.Equals(commit.author.name, StringComparison.InvariantCultureIgnoreCase) || u.Fullname.Equals(commit.author.name, StringComparison.InvariantCultureIgnoreCase)) : null; } var timeEntry = new IssueTimeTracking(); timeEntry.IssueId = issue.Id; timeEntry.ProjectId = issue.Entity.ProjectId; timeEntry.Comment = codeCommit.Comment.ToMax(1990); timeEntry.EntryDate = DateTime.Now; timeEntry.Hours = m.Value.Substring(0, 2).ToInt(); timeEntry.Minutes = m.Value.Substring(3, 2).ToInt(); timeEntry.TimeTypeId = timeTypes[0].Entity.Id; timeEntry.UserId = user == null ? Countersoft.Gemini.Commons.Constants.SystemAccountUserId : user.Id; TimeTrackingManager.Create(timeEntry); } } } } catch (Exception timeEx) { LogManager.LogError(timeEx, "GitHub - Time log"); } } } } } return(result); }
public List <CodeCommit> CodeCommit(string auth, string payload = "") { if (auth.IsEmpty()) { GeminiApp.LogException(new UnauthorizedAccessException() { Source = SourceControlProvider.Bitbucket.ToString() }, false); return(null); } var authDetails = Encoding.Default.GetString(Convert.FromBase64String(auth)).Split(':'); string apikey = string.Empty; if (authDetails.Length == 2) { apikey = authDetails[0]; } CurrentUser = new UserDto(new User() { ProjectGroups = new List <ProjectGroupMembership>() { new ProjectGroupMembership() { ProjectGroupId = Countersoft.Gemini.Commons.Constants.GlobalGroupAdministrators, UserId = 0 } } }); UserContext.User = CurrentUser; PermissionsManager = PermissionsManager.Copy(CurrentUser); UserContext.PermissionsManager = PermissionsManager; if (apikey.Length == 0 || GeminiApp.Config.ApiKey.Length == 0 || !apikey.StartsWith(GeminiApp.Config.ApiKey, StringComparison.InvariantCultureIgnoreCase)) { string error; if (GeminiApp.Config.ApiKey.Length == 0) { error = "Web.config is missing API key."; } else { error = string.Format("Wrong API key: {0}.", apikey); } GeminiApp.LogException(new Exception(error) { Source = SourceControlProvider.Bitbucket.ToString() }, false); return(null); } try { var body = Request.Content.ReadAsStringAsync(); body.Wait(); //GeminiApp.LogException("Null CodeCommit", string.Concat("Null CodeCommit - ", body.Result), false); } catch { try { GeminiApp.LogException("Null CodeCommit", "Null CodeCommit - Empty!", false); } catch { } } Payload commits = System.Web.HttpContext.Current.Request.Form["payload"].FromJson <Payload>(); if (commits == null) { return(null); } List <CodeCommit> allCommits = new List <CodeCommit>(); foreach (var commit in commits.commits) { Regex ex = new Regex("GEM:(?<issueid>[0-9]+)", RegexOptions.IgnoreCase); MatchCollection matches = ex.Matches(commit.message); List <int> issueAdded = new List <int>(); List <string> filesModified = new List <string>(); foreach (var file in commit.files) { FileCommitType type = FileCommitType.Created; if (file.type.Equals("modified", StringComparison.InvariantCultureIgnoreCase)) { type = FileCommitType.Modified; } else if (file.type.Equals("removed", StringComparison.InvariantCultureIgnoreCase)) { type = FileCommitType.Deleted; } filesModified.Add(string.Concat("{\"Filename\":\"", file.file, "\", \"FileId\":\"", string.Empty, "\",\"PreviousFileRevisionId\":\"", string.Empty, "\", \"Type\":\"", type.ToString(), "\" }")); } var data = commit.ToJson(); if (matches.Count > 0) { foreach (Match match in matches) { IssueDto issue = IssueManager.Get(match.ToString().Remove(0, 4).ToInt()); if (issue != null) { if (!issueAdded.Contains(issue.Id)) { CodeCommit newCodeCommit = new CodeCommit(); newCodeCommit.Provider = SourceControlProvider.Bitbucket; newCodeCommit.Comment = commit.message; newCodeCommit.Fullname = commit.author; newCodeCommit.Data = string.Concat("{\"RevisionId\":\"", commit.raw_node, "\",\"PreviousRevisionId\":\"", commit.parents[0], "\",\"Files\":[", string.Join(",", filesModified.ToArray()), "],\"RepositoryName\":\"", commits.repository.name, "\",\"RepositoryUrl\":\"", String.Concat(commits.canon_url, commits.repository.absolute_url), "\",\"IsPrivate\":\"", commits.repository.is_private, "\"}");; newCodeCommit.IssueId = issue.Id; allCommits.Add(GeminiContext.CodeCommits.Create(newCodeCommit)); issueAdded.Add(issue.Id); try { if (match.Index + match.Length + 1 + 5 <= commit.message.Length) { var time = commit.message.Substring(match.Index + match.Length + 1, 5); var timeEx = new System.Text.RegularExpressions.Regex("[0-9][0-9]:[0-9][0-9]"); var m = timeEx.Match(time); if (m.Success) { // Okay, log time! var timeTypes = MetaManager.TimeTypeGetAll(issue.Project.TemplateId); if (timeTypes.Count > 0) { // Let's try and find the user var user = commit.author.HasValue() ? Cache.Users.Find(u => u.Username.Equals(commit.author, StringComparison.InvariantCultureIgnoreCase) || u.Email.Equals(commit.author, StringComparison.InvariantCultureIgnoreCase) || u.Fullname.Equals(commit.author, StringComparison.InvariantCultureIgnoreCase)) : null; var timeEntry = new IssueTimeTracking(); timeEntry.IssueId = issue.Id; timeEntry.ProjectId = issue.Entity.ProjectId; timeEntry.Comment = commit.message.ToMax(1990); timeEntry.EntryDate = DateTime.Now; timeEntry.Hours = m.Value.Substring(0, 2).ToInt(); timeEntry.Minutes = m.Value.Substring(3, 2).ToInt(); timeEntry.TimeTypeId = timeTypes[0].Entity.Id; timeEntry.UserId = user == null ? Countersoft.Gemini.Commons.Constants.SystemAccountUserId : user.Id; TimeTrackingManager.Create(timeEntry); } } } } catch (Exception timeEx) { LogManager.LogError(timeEx, "BitBucket - Time log"); } } } else { GeminiApp.LogException(new Exception(string.Concat("Item ID ", match.ToString().Remove(0, 4).ToInt(), " could not be found.")) { Source = "Commit Failed" }, false); } } } } return(allCommits); }