fix up git

This commit is contained in:
2026-06-30 15:06:12 +07:00
parent 11e5a76977
commit 38e22b3390
13 changed files with 883 additions and 18 deletions

View File

@@ -64,7 +64,7 @@ func GitHubAuthorizeURLHandler(db *gorm.DB) fiber.Handler {
"https://github.com/login/oauth/authorize?client_id=%s&redirect_uri=%s&scope=%s&state=%s",
url.QueryEscape(clientID),
url.QueryEscape(redirectURI),
url.QueryEscape("repo"),
url.QueryEscape("repo delete_repo"),
url.QueryEscape(state),
)
return c.JSON(fiber.Map{"authorizeUrl": authorizeURL})
@@ -192,10 +192,11 @@ func GitHubStatusHandler(db *gorm.DB) fiber.Handler {
return c.JSON(fiber.Map{"connected": false})
}
return c.JSON(fiber.Map{
"connected": true,
"githubLogin": row.GitHubLogin,
"connectedAt": row.ConnectedAt,
"scope": row.Scope,
"connected": true,
"githubLogin": row.GitHubLogin,
"connectedAt": row.ConnectedAt,
"scope": row.Scope,
"canDeleteRepos": githubScopeAllowsDelete(row.Scope),
})
}
}
@@ -209,6 +210,21 @@ func GitHubDisconnectHandler(db *gorm.DB) fiber.Handler {
}
}
func githubScopeAllowsDelete(scope string) bool {
scope = strings.ToLower(strings.TrimSpace(scope))
if scope == "" {
return false
}
for _, part := range strings.FieldsFunc(scope, func(r rune) bool {
return r == ' ' || r == ','
}) {
if part == "delete_repo" {
return true
}
}
return false
}
func githubGetUser(token string) (login string, err error) {
req, _ := http.NewRequest(http.MethodGet, "https://api.github.com/user", nil)
req.Header.Set("Authorization", "Bearer "+token)
@@ -399,3 +415,61 @@ func resolvePublishRepo(token, ghLogin string, room *models.ExamRoom) (owner, re
}
return owner, repo, branch, htmlURL, nil
}
func studentGitRepoNameCandidates(row submissionRow, room *models.ExamRoom) []string {
base := trimGitHubRepoName(strings.ToLower(studentSubmissionFolder(row.StudentCode, row.FullName)))
candidates := []string{
base,
fmt.Sprintf("%s-exam-%d", base, room.ID),
fmt.Sprintf("%s-%d", base, row.StudentRkID),
fmt.Sprintf("exam-%d-%d", room.ID, row.StudentRkID),
}
seen := map[string]bool{}
out := make([]string, 0, len(candidates))
for _, c := range candidates {
c = trimGitHubRepoName(c)
if seen[c] {
continue
}
seen[c] = true
out = append(out, c)
}
for i := 2; i <= 10; i++ {
c := trimGitHubRepoName(fmt.Sprintf("%s-%d", base, i))
if !seen[c] {
seen[c] = true
out = append(out, c)
}
}
return out
}
func githubEnsureRepoForStudent(token, owner string, room *models.ExamRoom, row *submissionRow) (repoName, htmlURL string, err error) {
if u := strings.TrimSpace(row.GitRepoURL); u != "" {
o, r, parseErr := parseGitHubRepo(u)
if parseErr == nil && strings.EqualFold(o, owner) {
if url, ok := githubGetRepo(token, owner, r); ok {
return r, url, nil
}
}
}
for _, candidate := range studentGitRepoNameCandidates(*row, room) {
if url, ok := githubGetRepo(token, owner, candidate); ok {
if u := strings.TrimSpace(row.GitRepoURL); u != "" {
if o, r, parseErr := parseGitHubRepo(u); parseErr == nil && strings.EqualFold(o, owner) && strings.EqualFold(r, candidate) {
return candidate, url, nil
}
}
continue
}
url, createErr := githubCreateRepo(token, owner, candidate, true)
if createErr == nil {
return candidate, url, nil
}
if isGitHubRepoNameTaken(createErr) {
continue
}
return "", "", createErr
}
return "", "", errors.New("không tạo được repo GitHub cho sinh viên")
}