forked from metalogical/BigFiles
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* update gitee auth * update auth * fix
- Loading branch information
Showing
7 changed files
with
208 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package auth | ||
|
||
import ( | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
"io" | ||
"net/http" | ||
"strings" | ||
) | ||
|
||
type Client struct { | ||
} | ||
|
||
// getParsedResponse gets response data from gitee | ||
func getParsedResponse(method, path string, header http.Header, body io.Reader, obj interface{}) error { | ||
req, err := http.NewRequest(method, path, body) | ||
if err != nil { | ||
panic(err) | ||
} | ||
req.Header = header | ||
fmt.Println(strings.Split(path, "?")[0]) | ||
response, err := http.DefaultClient.Do(req) | ||
if err != nil { | ||
panic(err) | ||
} | ||
defer response.Body.Close() | ||
if response.StatusCode/100 != 2 { | ||
if response.StatusCode == http.StatusNotFound { | ||
return errors.New("repository not found") | ||
} else if response.StatusCode == http.StatusUnauthorized { | ||
return errors.New("unauthorized") | ||
} | ||
return errors.New("error occurred accessing gitee") | ||
} | ||
data, err := io.ReadAll(response.Body) | ||
if err != nil { | ||
panic(err) | ||
} | ||
err = json.Unmarshal(data, &obj) | ||
if err != nil { | ||
panic(err) | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,98 +1,158 @@ | ||
package auth | ||
|
||
import ( | ||
"encoding/json" | ||
"errors" | ||
"io" | ||
"fmt" | ||
"net/http" | ||
"net/url" | ||
"os" | ||
"strings" | ||
) | ||
|
||
var ( | ||
allowedRepos = []string{"openeuler", "src-openeuler"} | ||
uploadPermissions = []string{"admin", "developer"} | ||
downloadPermissions = []string{"admin", "developer", "read"} | ||
) | ||
|
||
type giteeUser struct { | ||
Login string `json:"login"` | ||
// Permission string `json:"permission"` | ||
Login string `json:"login"` | ||
Permission string `json:"permission"` | ||
} | ||
|
||
type UserInRepo struct { | ||
Repo string | ||
Owner string | ||
Token string | ||
Username string | ||
Password string | ||
Operation string | ||
} | ||
|
||
type parent struct { | ||
Fullname string `json:"full_name"` | ||
} | ||
|
||
type Repo struct { | ||
Parent parent `json:"parent"` | ||
Fullname string `json:"full_name"` | ||
} | ||
|
||
type AccessToken struct { | ||
Token string `json:"access_token"` | ||
} | ||
|
||
func GiteeAuth() func(string, string) error { | ||
return func(username, password string) error { | ||
token, err := getToken(username, password) | ||
if err != nil { | ||
func GiteeAuth() func(UserInRepo) error { | ||
return func(userInRepo UserInRepo) error { | ||
if userInRepo.Password != "" { | ||
token, err := getToken(userInRepo.Username, userInRepo.Password) | ||
if err != nil { | ||
userInRepo.Token = userInRepo.Password | ||
} else { | ||
userInRepo.Token = token | ||
} | ||
} | ||
|
||
if err := CheckRepoOwner(userInRepo); err != nil { | ||
return err | ||
} | ||
|
||
return verifyUser(username, token) | ||
return verifyUser(userInRepo) | ||
} | ||
} | ||
|
||
// CheckRepoOwner checks whether the owner of a repo is allowed to use lfs server | ||
func CheckRepoOwner(userInRepo UserInRepo) error { | ||
path := fmt.Sprintf( | ||
"https://gitee.com/api/v5/repos/%s/%s", | ||
userInRepo.Owner, | ||
userInRepo.Repo, | ||
) | ||
if userInRepo.Token != "" { | ||
path += fmt.Sprintf("?access_token=%s", userInRepo.Token) | ||
} | ||
headers := http.Header{"Content-Type": []string{"application/json;charset=UTF-8"}} | ||
repo := new(Repo) | ||
err := getParsedResponse("GET", path, headers, nil, &repo) | ||
if err != nil { | ||
return err | ||
} | ||
for _, allowedRepo := range allowedRepos { | ||
if strings.Split(repo.Fullname, "/")[0] == allowedRepo { | ||
return nil | ||
} | ||
} | ||
|
||
if repo.Parent.Fullname != "" { | ||
for _, allowedRepo := range allowedRepos { | ||
if strings.Split(repo.Parent.Fullname, "/")[0] == allowedRepo { | ||
return nil | ||
} | ||
} | ||
} | ||
|
||
return errors.New("your repository does not appear to have permission to use this lfs service") | ||
} | ||
|
||
// getToken gets access_token by username and password | ||
func getToken(username, password string) (string, error) { | ||
clientId := os.Getenv("CLIENT_ID") | ||
clientSecret := os.Getenv("CLIENT_SECRET") | ||
form := url.Values{} | ||
form.Add("scope", "user_info") | ||
form.Add("scope", "user_info projects") | ||
form.Add("grant_type", "password") | ||
form.Add("username", username) | ||
form.Add("password", password) | ||
form.Add("client_id", clientId) | ||
form.Add("client_secret", clientSecret) | ||
|
||
path := "https://gitee.com/oauth/token" | ||
response, err := http.Post(path, "application/x-www-form-urlencoded", strings.NewReader(form.Encode())) | ||
headers := http.Header{"Content-Type": []string{"application/x-www-form-urlencoded"}} | ||
accessToken := new(AccessToken) | ||
err := getParsedResponse("POST", path, headers, strings.NewReader(form.Encode()), &accessToken) | ||
if err != nil { | ||
panic(err) | ||
return "", err | ||
} | ||
defer response.Body.Close() | ||
|
||
if response.StatusCode != http.StatusOK { | ||
return "", errors.New("invalid credentials") | ||
} | ||
body, err := io.ReadAll(response.Body) | ||
if err != nil { | ||
panic(err) | ||
} | ||
var accessToken AccessToken | ||
err = json.Unmarshal(body, &accessToken) | ||
if err != nil { | ||
panic(err) | ||
} | ||
return accessToken.Token, nil | ||
} | ||
|
||
// verifyUser verifies user info by access_token | ||
func verifyUser(username, token string) error { | ||
path := "https://gitee.com/api/v5/user?access_token=" + token | ||
req, err := http.NewRequest("GET", path, nil) | ||
if err != nil { | ||
panic(err) | ||
} | ||
req.Header.Set("Content-Type", "application/json;charset=UTF-8") | ||
|
||
response, err := http.DefaultClient.Do(req) | ||
if err != nil { | ||
panic(err) | ||
} | ||
defer response.Body.Close() | ||
if response.StatusCode != http.StatusOK { | ||
return errors.New("invalid credentials") | ||
// verifyUser verifies user permission in repo by access_token and operation | ||
func verifyUser(userInRepo UserInRepo) error { | ||
path := fmt.Sprintf( | ||
"https://gitee.com/api/v5/repos/%s/%s/collaborators/%s/permission", | ||
userInRepo.Owner, | ||
userInRepo.Repo, | ||
userInRepo.Username, | ||
) | ||
if userInRepo.Token != "" { | ||
path += fmt.Sprintf("?access_token=%s", userInRepo.Token) | ||
} | ||
body, err := io.ReadAll(response.Body) | ||
headers := http.Header{"Content-Type": []string{"application/json;charset=UTF-8"}} | ||
giteeUser := new(giteeUser) | ||
err := getParsedResponse("GET", path, headers, nil, &giteeUser) | ||
if err != nil { | ||
panic(err) | ||
return err | ||
} | ||
var giteeUser giteeUser | ||
err = json.Unmarshal(body, &giteeUser) | ||
if err != nil { | ||
panic(err) | ||
|
||
if giteeUser.Login != userInRepo.Username { | ||
return errors.New("username does not match") | ||
} | ||
if giteeUser.Login == username { | ||
return nil | ||
if userInRepo.Operation == "upload" { | ||
for _, v := range uploadPermissions { | ||
if giteeUser.Permission == v { | ||
return nil | ||
} | ||
} | ||
return errors.New("user has no permission uploading to the repository") | ||
} else if userInRepo.Operation == "download" { | ||
for _, v := range downloadPermissions { | ||
if giteeUser.Permission == v { | ||
return nil | ||
} | ||
} | ||
return errors.New("user has no permission downloading in the repository") | ||
} else { | ||
return errors.New("username does not match") | ||
return errors.New("unknow operation") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.