Added clone mode for gitlab, use token mode as default
This commit is contained in:
parent
cc86f525df
commit
e2cdde02bc
9 changed files with 75 additions and 50 deletions
|
@ -31,6 +31,7 @@ This section lists all connection options used in the connection string format.
|
||||||
* `open=false` allows users to self-register. Defaults to false for security reasons.
|
* `open=false` allows users to self-register. Defaults to false for security reasons.
|
||||||
* `orgs=drone,docker` restricts access to these GitLab organizations. **Optional**
|
* `orgs=drone,docker` restricts access to these GitLab organizations. **Optional**
|
||||||
* `skip_verify=false` skip ca verification if self-signed certificate. Defaults to false for security reasons.
|
* `skip_verify=false` skip ca verification if self-signed certificate. Defaults to false for security reasons.
|
||||||
|
* `clone_mode=token` a strategy for clone authorization, by default use repo token, but can be changed to `oauth` ( This is not secure, because your user token, with full access to your gitlab account will be written to .netrc, and it can be read by all who have access to project builds )
|
||||||
|
|
||||||
## Gitlab registration
|
## Gitlab registration
|
||||||
|
|
||||||
|
|
12
pkg/hash/hash.go
Normal file
12
pkg/hash/hash.go
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package hash
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
)
|
||||||
|
|
||||||
|
func New(text, salt string) string {
|
||||||
|
hasher := sha256.New()
|
||||||
|
hasher.Write([]byte(text + salt))
|
||||||
|
return hex.EncodeToString(hasher.Sum(nil))
|
||||||
|
}
|
|
@ -170,7 +170,7 @@ func (g *GitHub) Script(u *common.User, r *common.Repo, b *common.Build) ([]byte
|
||||||
|
|
||||||
// Netrc returns a .netrc file that can be used to clone
|
// Netrc returns a .netrc file that can be used to clone
|
||||||
// private repositories from a remote system.
|
// private repositories from a remote system.
|
||||||
func (g *GitHub) Netrc(u *common.User) (*common.Netrc, error) {
|
func (g *GitHub) Netrc(u *common.User, r *common.Repo) (*common.Netrc, error) {
|
||||||
url_, err := url.Parse(g.URL)
|
url_, err := url.Parse(g.URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
|
|
||||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client"
|
"github.com/drone/drone/Godeps/_workspace/src/github.com/Bugagazavr/go-gitlab-client"
|
||||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/hashicorp/golang-lru"
|
"github.com/drone/drone/Godeps/_workspace/src/github.com/hashicorp/golang-lru"
|
||||||
|
"github.com/drone/drone/pkg/hash"
|
||||||
"github.com/drone/drone/pkg/oauth2"
|
"github.com/drone/drone/pkg/oauth2"
|
||||||
"github.com/drone/drone/pkg/remote"
|
"github.com/drone/drone/pkg/remote"
|
||||||
common "github.com/drone/drone/pkg/types"
|
common "github.com/drone/drone/pkg/types"
|
||||||
|
@ -26,6 +27,7 @@ type Gitlab struct {
|
||||||
Client string
|
Client string
|
||||||
Secret string
|
Secret string
|
||||||
AllowedOrgs []string
|
AllowedOrgs []string
|
||||||
|
CloneMode string
|
||||||
Open bool
|
Open bool
|
||||||
PrivateMode bool
|
PrivateMode bool
|
||||||
SkipVerify bool
|
SkipVerify bool
|
||||||
|
@ -54,6 +56,13 @@ func NewDriver(config string) (remote.Remote, error) {
|
||||||
gitlab.SkipVerify, _ = strconv.ParseBool(params.Get("skip_verify"))
|
gitlab.SkipVerify, _ = strconv.ParseBool(params.Get("skip_verify"))
|
||||||
gitlab.Open, _ = strconv.ParseBool(params.Get("open"))
|
gitlab.Open, _ = strconv.ParseBool(params.Get("open"))
|
||||||
|
|
||||||
|
switch params.Get("clone_mode") {
|
||||||
|
case "oauth":
|
||||||
|
gitlab.CloneMode = "oauth"
|
||||||
|
default:
|
||||||
|
gitlab.CloneMode = "token"
|
||||||
|
}
|
||||||
|
|
||||||
// this is a temp workaround
|
// this is a temp workaround
|
||||||
gitlab.Search, _ = strconv.ParseBool(params.Get("search"))
|
gitlab.Search, _ = strconv.ParseBool(params.Get("search"))
|
||||||
|
|
||||||
|
@ -64,8 +73,8 @@ func NewDriver(config string) (remote.Remote, error) {
|
||||||
return &gitlab, err
|
return &gitlab, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Gitlab) Login(token, secret string) (*common.User, error) {
|
func (g *Gitlab) Login(token, secret string) (*common.User, error) {
|
||||||
client := NewClient(r.URL, token, r.SkipVerify)
|
client := NewClient(g.URL, token, g.SkipVerify)
|
||||||
var login, err = client.CurrentUser()
|
var login, err = client.CurrentUser()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -79,20 +88,20 @@ func (r *Gitlab) Login(token, secret string) (*common.User, error) {
|
||||||
if strings.HasPrefix(login.AvatarUrl, "http") {
|
if strings.HasPrefix(login.AvatarUrl, "http") {
|
||||||
user.Avatar = login.AvatarUrl
|
user.Avatar = login.AvatarUrl
|
||||||
} else {
|
} else {
|
||||||
user.Avatar = r.URL + "/" + login.AvatarUrl
|
user.Avatar = g.URL + "/" + login.AvatarUrl
|
||||||
}
|
}
|
||||||
return &user, nil
|
return &user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Orgs fetches the organizations for the given user.
|
// Orgs fetches the organizations for the given user.
|
||||||
func (r *Gitlab) Orgs(u *common.User) ([]string, error) {
|
func (g *Gitlab) Orgs(u *common.User) ([]string, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Repo fetches the named repository from the remote system.
|
// Repo fetches the named repository from the remote system.
|
||||||
func (r *Gitlab) Repo(u *common.User, owner, name string) (*common.Repo, error) {
|
func (g *Gitlab) Repo(u *common.User, owner, name string) (*common.Repo, error) {
|
||||||
client := NewClient(r.URL, u.Token, r.SkipVerify)
|
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||||
id, err := GetProjectId(r, client, owner, name)
|
id, err := GetProjectId(g, client, owner, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -113,7 +122,7 @@ func (r *Gitlab) Repo(u *common.User, owner, name string) (*common.Repo, error)
|
||||||
repo.Branch = repo_.DefaultBranch
|
repo.Branch = repo_.DefaultBranch
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.PrivateMode {
|
if g.PrivateMode {
|
||||||
repo.Private = true
|
repo.Private = true
|
||||||
} else {
|
} else {
|
||||||
repo.Private = !repo_.Public
|
repo.Private = !repo_.Public
|
||||||
|
@ -123,15 +132,15 @@ func (r *Gitlab) Repo(u *common.User, owner, name string) (*common.Repo, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perm fetches the named repository from the remote system.
|
// Perm fetches the named repository from the remote system.
|
||||||
func (r *Gitlab) Perm(u *common.User, owner, name string) (*common.Perm, error) {
|
func (g *Gitlab) Perm(u *common.User, owner, name string) (*common.Perm, error) {
|
||||||
key := fmt.Sprintf("%s/%s/%s", u.Login, owner, name)
|
key := fmt.Sprintf("%s/%s/%s", u.Login, owner, name)
|
||||||
val, ok := r.cache.Get(key)
|
val, ok := g.cache.Get(key)
|
||||||
if ok {
|
if ok {
|
||||||
return val.(*common.Perm), nil
|
return val.(*common.Perm), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
client := NewClient(r.URL, u.Token, r.SkipVerify)
|
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||||
id, err := GetProjectId(r, client, owner, name)
|
id, err := GetProjectId(g, client, owner, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -144,15 +153,15 @@ func (r *Gitlab) Perm(u *common.User, owner, name string) (*common.Perm, error)
|
||||||
m.Admin = IsAdmin(repo)
|
m.Admin = IsAdmin(repo)
|
||||||
m.Pull = IsRead(repo)
|
m.Pull = IsRead(repo)
|
||||||
m.Push = IsWrite(repo)
|
m.Push = IsWrite(repo)
|
||||||
r.cache.Add(key, m)
|
g.cache.Add(key, m)
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetScript fetches the build script (.drone.yml) from the remote
|
// GetScript fetches the build script (.drone.yml) from the remote
|
||||||
// repository and returns in string format.
|
// repository and returns in string format.
|
||||||
func (r *Gitlab) Script(user *common.User, repo *common.Repo, build *common.Build) ([]byte, error) {
|
func (g *Gitlab) Script(user *common.User, repo *common.Repo, build *common.Build) ([]byte, error) {
|
||||||
var client = NewClient(r.URL, user.Token, r.SkipVerify)
|
var client = NewClient(g.URL, user.Token, g.SkipVerify)
|
||||||
id, err := GetProjectId(r, client, repo.Owner, repo.Name)
|
id, err := GetProjectId(g, client, repo.Owner, repo.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -163,29 +172,36 @@ func (r *Gitlab) Script(user *common.User, repo *common.Repo, build *common.Buil
|
||||||
// NOTE Currently gitlab doesn't support status for commits and events,
|
// NOTE Currently gitlab doesn't support status for commits and events,
|
||||||
// also if we want get MR status in gitlab we need implement a special plugin for gitlab,
|
// also if we want get MR status in gitlab we need implement a special plugin for gitlab,
|
||||||
// gitlab uses API to fetch build status on client side. But for now we skip this.
|
// gitlab uses API to fetch build status on client side. But for now we skip this.
|
||||||
func (r *Gitlab) Status(u *common.User, repo *common.Repo, b *common.Build) error {
|
func (g *Gitlab) Status(u *common.User, repo *common.Repo, b *common.Build) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Netrc returns a .netrc file that can be used to clone
|
// Netrc returns a .netrc file that can be used to clone
|
||||||
// private repositories from a remote system.
|
// private repositories from a remote system.
|
||||||
func (r *Gitlab) Netrc(u *common.User) (*common.Netrc, error) {
|
func (g *Gitlab) Netrc(u *common.User, r *common.Repo) (*common.Netrc, error) {
|
||||||
url_, err := url.Parse(r.URL)
|
url_, err := url.Parse(g.URL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
netrc := &common.Netrc{}
|
netrc := &common.Netrc{}
|
||||||
netrc.Login = "oauth2"
|
|
||||||
netrc.Password = u.Token
|
switch g.CloneMode {
|
||||||
|
case "oauth":
|
||||||
|
netrc.Login = "oauth2"
|
||||||
|
netrc.Password = u.Token
|
||||||
|
case "token":
|
||||||
|
netrc.Login = "drone-ci-token"
|
||||||
|
netrc.Password = hash.New(r.FullName, r.Hash)
|
||||||
|
}
|
||||||
netrc.Machine = url_.Host
|
netrc.Machine = url_.Host
|
||||||
return netrc, nil
|
return netrc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activate activates a repository by adding a Post-commit hook and
|
// Activate activates a repository by adding a Post-commit hook and
|
||||||
// a Public Deploy key, if applicable.
|
// a Public Deploy key, if applicable.
|
||||||
func (r *Gitlab) Activate(user *common.User, repo *common.Repo, k *common.Keypair, link string) error {
|
func (g *Gitlab) Activate(user *common.User, repo *common.Repo, k *common.Keypair, link string) error {
|
||||||
var client = NewClient(r.URL, user.Token, r.SkipVerify)
|
var client = NewClient(g.URL, user.Token, g.SkipVerify)
|
||||||
id, err := GetProjectId(r, client, repo.Owner, repo.Name)
|
id, err := GetProjectId(g, client, repo.Owner, repo.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -197,7 +213,7 @@ func (r *Gitlab) Activate(user *common.User, repo *common.Repo, k *common.Keypai
|
||||||
|
|
||||||
droneUrl := fmt.Sprintf("%s://%s", uri.Scheme, uri.Host)
|
droneUrl := fmt.Sprintf("%s://%s", uri.Scheme, uri.Host)
|
||||||
droneToken := uri.Query().Get("access_token")
|
droneToken := uri.Query().Get("access_token")
|
||||||
ssl_verify := strconv.FormatBool(!r.SkipVerify)
|
ssl_verify := strconv.FormatBool(!g.SkipVerify)
|
||||||
|
|
||||||
return client.AddDroneService(id, map[string]string{
|
return client.AddDroneService(id, map[string]string{
|
||||||
"token": droneToken,
|
"token": droneToken,
|
||||||
|
@ -208,9 +224,9 @@ func (r *Gitlab) Activate(user *common.User, repo *common.Repo, k *common.Keypai
|
||||||
|
|
||||||
// Deactivate removes a repository by removing all the post-commit hooks
|
// Deactivate removes a repository by removing all the post-commit hooks
|
||||||
// which are equal to link and removing the SSH deploy key.
|
// which are equal to link and removing the SSH deploy key.
|
||||||
func (r *Gitlab) Deactivate(user *common.User, repo *common.Repo, link string) error {
|
func (g *Gitlab) Deactivate(user *common.User, repo *common.Repo, link string) error {
|
||||||
var client = NewClient(r.URL, user.Token, r.SkipVerify)
|
var client = NewClient(g.URL, user.Token, g.SkipVerify)
|
||||||
id, err := GetProjectId(r, client, repo.Owner, repo.Name)
|
id, err := GetProjectId(g, client, repo.Owner, repo.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -220,7 +236,7 @@ func (r *Gitlab) Deactivate(user *common.User, repo *common.Repo, link string) e
|
||||||
|
|
||||||
// ParseHook parses the post-commit hook from the Request body
|
// ParseHook parses the post-commit hook from the Request body
|
||||||
// and returns the required data in a standard format.
|
// and returns the required data in a standard format.
|
||||||
func (r *Gitlab) Hook(req *http.Request) (*common.Hook, error) {
|
func (g *Gitlab) Hook(req *http.Request) (*common.Hook, error) {
|
||||||
defer req.Body.Close()
|
defer req.Body.Close()
|
||||||
var payload, _ = ioutil.ReadAll(req.Body)
|
var payload, _ = ioutil.ReadAll(req.Body)
|
||||||
var parsed, err = gogitlab.ParseHook(payload)
|
var parsed, err = gogitlab.ParseHook(payload)
|
||||||
|
@ -341,16 +357,16 @@ func (g *Gitlab) Oauth2Transport(r *http.Request) *oauth2.Transport {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accessor method, to allowed remote organizations field.
|
// Accessor method, to allowed remote organizations field.
|
||||||
func (r *Gitlab) GetOrgs() []string {
|
func (g *Gitlab) GetOrgs() []string {
|
||||||
return r.AllowedOrgs
|
return g.AllowedOrgs
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accessor method, to open field.
|
// Accessor method, to open field.
|
||||||
func (r *Gitlab) GetOpen() bool {
|
func (g *Gitlab) GetOpen() bool {
|
||||||
return r.Open
|
return g.Open
|
||||||
}
|
}
|
||||||
|
|
||||||
// return default scope for GitHub
|
// return default scope for GitHub
|
||||||
func (r *Gitlab) Scope() string {
|
func (g *Gitlab) Scope() string {
|
||||||
return DefaultScope
|
return DefaultScope
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ type Remote interface {
|
||||||
|
|
||||||
// Netrc returns a .netrc file that can be used to clone
|
// Netrc returns a .netrc file that can be used to clone
|
||||||
// private repositories from a remote system.
|
// private repositories from a remote system.
|
||||||
Netrc(u *types.User) (*types.Netrc, error)
|
Netrc(u *types.User, r *types.Repo) (*types.Netrc, error)
|
||||||
|
|
||||||
// Activate activates a repository by creating the post-commit hook and
|
// Activate activates a repository by creating the post-commit hook and
|
||||||
// adding the SSH deploy key, if applicable.
|
// adding the SSH deploy key, if applicable.
|
||||||
|
|
|
@ -166,7 +166,7 @@ func RunBuild(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
netrc, err := remote.Netrc(user)
|
netrc, err := remote.Netrc(user, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Fail(500, err)
|
c.Fail(500, err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -5,6 +5,8 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/gin-gonic/gin"
|
"github.com/drone/drone/Godeps/_workspace/src/github.com/gin-gonic/gin"
|
||||||
|
|
||||||
|
"github.com/drone/drone/pkg/hash"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RedirectSha accepts a request to retvie a redirect
|
// RedirectSha accepts a request to retvie a redirect
|
||||||
|
@ -78,7 +80,7 @@ func GetPullRequest(c *gin.Context) {
|
||||||
repo := ToRepo(c)
|
repo := ToRepo(c)
|
||||||
|
|
||||||
// get the token and verify the hook is authorized
|
// get the token and verify the hook is authorized
|
||||||
if c.Request.FormValue("access_token") != hash(repo.FullName, repo.Hash) {
|
if c.Request.FormValue("access_token") != hash.New(repo.FullName, repo.Hash) {
|
||||||
c.AbortWithStatus(403)
|
c.AbortWithStatus(403)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -117,7 +119,7 @@ func GetCommit(c *gin.Context) {
|
||||||
sha := c.Params.ByName("sha")
|
sha := c.Params.ByName("sha")
|
||||||
|
|
||||||
// get the token and verify the hook is authorized
|
// get the token and verify the hook is authorized
|
||||||
if c.Request.FormValue("access_token") != hash(repo.FullName, repo.Hash) {
|
if c.Request.FormValue("access_token") != hash.New(repo.FullName, repo.Hash) {
|
||||||
c.AbortWithStatus(403)
|
c.AbortWithStatus(403)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
log "github.com/drone/drone/Godeps/_workspace/src/github.com/Sirupsen/logrus"
|
log "github.com/drone/drone/Godeps/_workspace/src/github.com/Sirupsen/logrus"
|
||||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/gin-gonic/gin"
|
"github.com/drone/drone/Godeps/_workspace/src/github.com/gin-gonic/gin"
|
||||||
|
"github.com/drone/drone/pkg/hash"
|
||||||
"github.com/drone/drone/pkg/queue"
|
"github.com/drone/drone/pkg/queue"
|
||||||
common "github.com/drone/drone/pkg/types"
|
common "github.com/drone/drone/pkg/types"
|
||||||
"github.com/drone/drone/pkg/yaml"
|
"github.com/drone/drone/pkg/yaml"
|
||||||
|
@ -56,7 +57,7 @@ func PostHook(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the token and verify the hook is authorized
|
// get the token and verify the hook is authorized
|
||||||
if c.Request.FormValue("access_token") != hash(repo.FullName, repo.Hash) {
|
if c.Request.FormValue("access_token") != hash.New(repo.FullName, repo.Hash) {
|
||||||
log.Errorf("invalid token sent with hook.")
|
log.Errorf("invalid token sent with hook.")
|
||||||
c.AbortWithStatus(403)
|
c.AbortWithStatus(403)
|
||||||
return
|
return
|
||||||
|
@ -128,7 +129,7 @@ func PostHook(c *gin.Context) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
netrc, err := remote.Netrc(user)
|
netrc, err := remote.Netrc(user, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failure to generate netrc for %s. %s", repo.FullName, err)
|
log.Errorf("failure to generate netrc for %s. %s", repo.FullName, err)
|
||||||
c.Fail(500, err)
|
c.Fail(500, err)
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/hex"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/gin-gonic/gin"
|
"github.com/drone/drone/Godeps/_workspace/src/github.com/gin-gonic/gin"
|
||||||
"github.com/drone/drone/Godeps/_workspace/src/github.com/gin-gonic/gin/binding"
|
"github.com/drone/drone/Godeps/_workspace/src/github.com/gin-gonic/gin/binding"
|
||||||
|
|
||||||
|
"github.com/drone/drone/pkg/hash"
|
||||||
"github.com/drone/drone/pkg/remote"
|
"github.com/drone/drone/pkg/remote"
|
||||||
common "github.com/drone/drone/pkg/types"
|
common "github.com/drone/drone/pkg/types"
|
||||||
"github.com/drone/drone/pkg/utils/httputil"
|
"github.com/drone/drone/pkg/utils/httputil"
|
||||||
|
@ -209,7 +208,7 @@ func PostRepo(c *gin.Context) {
|
||||||
link := fmt.Sprintf(
|
link := fmt.Sprintf(
|
||||||
"%s/api/hook?access_token=%s",
|
"%s/api/hook?access_token=%s",
|
||||||
httputil.GetURL(c.Request),
|
httputil.GetURL(c.Request),
|
||||||
hash(r.FullName, r.Hash),
|
hash.New(r.FullName, r.Hash),
|
||||||
)
|
)
|
||||||
|
|
||||||
// generate an RSA key and add to the repo
|
// generate an RSA key and add to the repo
|
||||||
|
@ -316,9 +315,3 @@ func perms(remote remote.Remote, u *common.User, r *common.Repo) *common.Perm {
|
||||||
}
|
}
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func hash(text, salt string) string {
|
|
||||||
hasher := sha256.New()
|
|
||||||
hasher.Write([]byte(text + salt))
|
|
||||||
return hex.EncodeToString(hasher.Sum(nil))
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue