mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2026-04-15 01:41:56 +00:00
Move open registration setting into remote plugins
...so that it's possible to enable or disable open registration on a per-remote basis. For example, the `DRONE_REGISTRATION_OPEN` environment variable now becomes `DRONE_GITHUB_OPEN` when using GitHub as a remote. The default for open registration in this commit is `false` (disabled), which matches the existing behaviour. This is useful if you need to support both public and private remotes, e.g. GitHub.com and GitHub Enterprise, where you trust all of the private users and want to allow open registration for those but would not want all GitHub.com users to run builds on your server. Tested with GitHub and GitLab.
This commit is contained in:
@@ -22,22 +22,11 @@ port=":80"
|
|||||||
driver="sqlite3"
|
driver="sqlite3"
|
||||||
datasource="/var/lib/drone/drone.sqlite"
|
datasource="/var/lib/drone/drone.sqlite"
|
||||||
|
|
||||||
|
|
||||||
#####################################################################
|
|
||||||
# Open Registration allows users to self-register for Drone.
|
|
||||||
# This is recommended if Drone is being hosted behind a
|
|
||||||
# firewall.
|
|
||||||
#
|
|
||||||
# When false, the system admin will need to manually add
|
|
||||||
# users to Drone through the admin screens.
|
|
||||||
#
|
|
||||||
# [registration]
|
|
||||||
# open=true
|
|
||||||
|
|
||||||
# [github]
|
# [github]
|
||||||
# client=""
|
# client=""
|
||||||
# secret=""
|
# secret=""
|
||||||
# orgs=[]
|
# orgs=[]
|
||||||
|
# open=false
|
||||||
|
|
||||||
# [github_enterprise]
|
# [github_enterprise]
|
||||||
# client=""
|
# client=""
|
||||||
@@ -46,18 +35,22 @@ datasource="/var/lib/drone/drone.sqlite"
|
|||||||
# url=""
|
# url=""
|
||||||
# orgs=[]
|
# orgs=[]
|
||||||
# private_mode=false
|
# private_mode=false
|
||||||
|
# open=false
|
||||||
|
|
||||||
# [bitbucket]
|
# [bitbucket]
|
||||||
# client=""
|
# client=""
|
||||||
# secret=""
|
# secret=""
|
||||||
|
# open=false
|
||||||
|
|
||||||
# [gitlab]
|
# [gitlab]
|
||||||
# url=""
|
# url=""
|
||||||
# skip_verify=false
|
# skip_verify=false
|
||||||
|
# open=false
|
||||||
|
|
||||||
# [gogs]
|
# [gogs]
|
||||||
# url=""
|
# url=""
|
||||||
# secret=""
|
# secret=""
|
||||||
|
# open=false
|
||||||
|
|
||||||
#####################################################################
|
#####################################################################
|
||||||
# SMTP configuration for Drone. This is required if you plan
|
# SMTP configuration for Drone. This is required if you plan
|
||||||
|
|||||||
@@ -27,19 +27,21 @@ type Bitbucket struct {
|
|||||||
API string
|
API string
|
||||||
Client string
|
Client string
|
||||||
Secret string
|
Secret string
|
||||||
|
Open bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(url, api, client, secret string) *Bitbucket {
|
func New(url, api, client, secret string, open bool) *Bitbucket {
|
||||||
return &Bitbucket{
|
return &Bitbucket{
|
||||||
URL: url,
|
URL: url,
|
||||||
API: api,
|
API: api,
|
||||||
Client: client,
|
Client: client,
|
||||||
Secret: secret,
|
Secret: secret,
|
||||||
|
Open: open,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDefault(client, secret string) *Bitbucket {
|
func NewDefault(client, secret string, open bool) *Bitbucket {
|
||||||
return New(DefaultURL, DefaultAPI, client, secret)
|
return New(DefaultURL, DefaultAPI, client, secret, open)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Authorize handles Bitbucket API Authorization
|
// Authorize handles Bitbucket API Authorization
|
||||||
@@ -269,3 +271,7 @@ func (r *Bitbucket) ParseHook(req *http.Request) (*model.Hook, error) {
|
|||||||
Message: hook.Commits[len(hook.Commits)-1].Message,
|
Message: hook.Commits[len(hook.Commits)-1].Message,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Bitbucket) OpenRegistration() bool {
|
||||||
|
return r.Open
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ var (
|
|||||||
// Bitbucket cloud configuration details
|
// Bitbucket cloud configuration details
|
||||||
bitbucketClient = config.String("bitbucket-client", "")
|
bitbucketClient = config.String("bitbucket-client", "")
|
||||||
bitbucketSecret = config.String("bitbucket-secret", "")
|
bitbucketSecret = config.String("bitbucket-secret", "")
|
||||||
|
bitbucketOpen = config.Bool("bitbucket-open", false)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Registers the Bitbucket plugin using the default
|
// Registers the Bitbucket plugin using the default
|
||||||
@@ -19,6 +20,6 @@ func Register() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
remote.Register(
|
remote.Register(
|
||||||
NewDefault(*bitbucketClient, *bitbucketSecret),
|
NewDefault(*bitbucketClient, *bitbucketSecret, *bitbucketOpen),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,9 +28,10 @@ type GitHub struct {
|
|||||||
Private bool
|
Private bool
|
||||||
SkipVerify bool
|
SkipVerify bool
|
||||||
Orgs []string
|
Orgs []string
|
||||||
|
Open bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(url, api, client, secret string, private, skipVerify bool, orgs []string) *GitHub {
|
func New(url, api, client, secret string, private, skipVerify bool, orgs []string, open bool) *GitHub {
|
||||||
var github = GitHub{
|
var github = GitHub{
|
||||||
URL: url,
|
URL: url,
|
||||||
API: api,
|
API: api,
|
||||||
@@ -39,6 +40,7 @@ func New(url, api, client, secret string, private, skipVerify bool, orgs []strin
|
|||||||
Private: private,
|
Private: private,
|
||||||
SkipVerify: skipVerify,
|
SkipVerify: skipVerify,
|
||||||
Orgs: orgs,
|
Orgs: orgs,
|
||||||
|
Open: open,
|
||||||
}
|
}
|
||||||
// the API must have a trailing slash
|
// the API must have a trailing slash
|
||||||
if !strings.HasSuffix(github.API, "/") {
|
if !strings.HasSuffix(github.API, "/") {
|
||||||
@@ -51,8 +53,8 @@ func New(url, api, client, secret string, private, skipVerify bool, orgs []strin
|
|||||||
return &github
|
return &github
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDefault(client, secret string, orgs []string) *GitHub {
|
func NewDefault(client, secret string, orgs []string, open bool) *GitHub {
|
||||||
return New(DefaultURL, DefaultAPI, client, secret, false, false, orgs)
|
return New(DefaultURL, DefaultAPI, client, secret, false, false, orgs, open)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Authorize handles GitHub API Authorization.
|
// Authorize handles GitHub API Authorization.
|
||||||
@@ -305,3 +307,7 @@ func (r *GitHub) ParsePullRequestHook(req *http.Request) (*model.Hook, error) {
|
|||||||
|
|
||||||
return &hook, nil
|
return &hook, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *GitHub) OpenRegistration() bool {
|
||||||
|
return r.Open
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ var (
|
|||||||
githubClient = config.String("github-client", "")
|
githubClient = config.String("github-client", "")
|
||||||
githubSecret = config.String("github-secret", "")
|
githubSecret = config.String("github-secret", "")
|
||||||
githubOrgs = config.Strings("github-orgs")
|
githubOrgs = config.Strings("github-orgs")
|
||||||
|
githubOpen = config.Bool("github-open", false)
|
||||||
|
|
||||||
// GitHub Enterprise configuration details
|
// GitHub Enterprise configuration details
|
||||||
githubEnterpriseURL = config.String("github-enterprise-url", "")
|
githubEnterpriseURL = config.String("github-enterprise-url", "")
|
||||||
@@ -19,6 +20,7 @@ var (
|
|||||||
githubEnterprisePrivate = config.Bool("github-enterprise-private-mode", true)
|
githubEnterprisePrivate = config.Bool("github-enterprise-private-mode", true)
|
||||||
githubEnterpriseSkipVerify = config.Bool("github-enterprise-skip-verify", false)
|
githubEnterpriseSkipVerify = config.Bool("github-enterprise-skip-verify", false)
|
||||||
githubEnterpriseOrgs = config.Strings("github-enterprise-orgs")
|
githubEnterpriseOrgs = config.Strings("github-enterprise-orgs")
|
||||||
|
githubEnterpriseOpen = config.Bool("github-enterprise-open", false)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Registers the GitHub plugins using the default
|
// Registers the GitHub plugins using the default
|
||||||
@@ -35,7 +37,7 @@ func registerGitHub() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
remote.Register(
|
remote.Register(
|
||||||
NewDefault(*githubClient, *githubSecret, *githubOrgs),
|
NewDefault(*githubClient, *githubSecret, *githubOrgs, *githubOpen),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,6 +58,7 @@ func registerGitHubEnterprise() {
|
|||||||
*githubEnterprisePrivate,
|
*githubEnterprisePrivate,
|
||||||
*githubEnterpriseSkipVerify,
|
*githubEnterpriseSkipVerify,
|
||||||
*githubEnterpriseOrgs,
|
*githubEnterpriseOrgs,
|
||||||
|
*githubEnterpriseOpen,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,12 +13,14 @@ import (
|
|||||||
type Gitlab struct {
|
type Gitlab struct {
|
||||||
url string
|
url string
|
||||||
SkipVerify bool
|
SkipVerify bool
|
||||||
|
Open bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(url string, skipVerify bool) *Gitlab {
|
func New(url string, skipVerify, open bool) *Gitlab {
|
||||||
return &Gitlab{
|
return &Gitlab{
|
||||||
url: url,
|
url: url,
|
||||||
SkipVerify: skipVerify,
|
SkipVerify: skipVerify,
|
||||||
|
Open: open,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,3 +193,7 @@ func (r *Gitlab) ParseHook(req *http.Request) (*model.Hook, error) {
|
|||||||
|
|
||||||
return hook, nil
|
return hook, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Gitlab) OpenRegistration() bool {
|
||||||
|
return r.Open
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ func Test_Github(t *testing.T) {
|
|||||||
var server = testdata.NewServer()
|
var server = testdata.NewServer()
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
var gitlab = New(server.URL, false)
|
var gitlab = New(server.URL, false, false)
|
||||||
var user = model.User{
|
var user = model.User{
|
||||||
Access: "e3b0c44298fc1c149afbf4c8996fb",
|
Access: "e3b0c44298fc1c149afbf4c8996fb",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
var (
|
var (
|
||||||
gitlabURL = config.String("gitlab-url", "")
|
gitlabURL = config.String("gitlab-url", "")
|
||||||
gitlabSkipVerify = config.Bool("gitlab-skip-verify", false)
|
gitlabSkipVerify = config.Bool("gitlab-skip-verify", false)
|
||||||
|
gitlabOpen = config.Bool("gitlab-open", false)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Registers the Gitlab plugin using the default
|
// Registers the Gitlab plugin using the default
|
||||||
@@ -21,6 +22,7 @@ func Register() {
|
|||||||
New(
|
New(
|
||||||
*gitlabURL,
|
*gitlabURL,
|
||||||
*gitlabSkipVerify,
|
*gitlabSkipVerify,
|
||||||
|
*gitlabOpen,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,11 @@ import (
|
|||||||
type Gogs struct {
|
type Gogs struct {
|
||||||
URL string
|
URL string
|
||||||
Secret string
|
Secret string
|
||||||
|
Open bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(url string, secret string) *Gogs {
|
func New(url string, secret string, open bool) *Gogs {
|
||||||
return &Gogs{URL: url, Secret: secret}
|
return &Gogs{URL: url, Secret: secret, Open: open}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Authorize handles Gogs authorization
|
// Authorize handles Gogs authorization
|
||||||
@@ -181,3 +182,7 @@ func (r *Gogs) ParseHook(req *http.Request) (*model.Hook, error) {
|
|||||||
Message: payload.Commits[0].Message,
|
Message: payload.Commits[0].Message,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Gogs) OpenRegistration() bool {
|
||||||
|
return r.Open
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
var (
|
var (
|
||||||
gogsUrl = config.String("gogs-url", "")
|
gogsUrl = config.String("gogs-url", "")
|
||||||
gogsSecret = config.String("gogs-secret", "")
|
gogsSecret = config.String("gogs-secret", "")
|
||||||
|
gogsOpen = config.Bool("gogs-open", false)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Registers the Gogs plugin using the default
|
// Registers the Gogs plugin using the default
|
||||||
@@ -18,6 +19,6 @@ func Register() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
remote.Register(
|
remote.Register(
|
||||||
New(*gogsUrl, *gogsSecret),
|
New(*gogsUrl, *gogsSecret, *gogsOpen),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,9 @@ type Remote interface {
|
|||||||
// 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.
|
||||||
ParseHook(r *http.Request) (*model.Hook, error)
|
ParseHook(r *http.Request) (*model.Hook, error)
|
||||||
|
|
||||||
|
// Registration returns true if open registration is allowed
|
||||||
|
OpenRegistration() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// List of registered plugins.
|
// List of registered plugins.
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import (
|
|||||||
|
|
||||||
func TestBlobstore(t *testing.T) {
|
func TestBlobstore(t *testing.T) {
|
||||||
caps := map[string]bool{}
|
caps := map[string]bool{}
|
||||||
caps[Registration] = true
|
|
||||||
|
|
||||||
ctx := NewContext(context.Background(), caps)
|
ctx := NewContext(context.Background(), caps)
|
||||||
|
|
||||||
@@ -17,7 +16,6 @@ func TestBlobstore(t *testing.T) {
|
|||||||
g.Describe("Capabilities", func() {
|
g.Describe("Capabilities", func() {
|
||||||
|
|
||||||
g.It("Should get capabilities from context", func() {
|
g.It("Should get capabilities from context", func() {
|
||||||
g.Assert(Enabled(ctx, Registration)).Equal(true)
|
|
||||||
g.Assert(Enabled(ctx, "Fake Key")).Equal(false)
|
g.Assert(Enabled(ctx, "Fake Key")).Equal(false)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/drone/drone/plugin/remote"
|
"github.com/drone/drone/plugin/remote"
|
||||||
"github.com/drone/drone/server/capability"
|
|
||||||
"github.com/drone/drone/server/datastore"
|
"github.com/drone/drone/server/datastore"
|
||||||
"github.com/drone/drone/server/session"
|
"github.com/drone/drone/server/session"
|
||||||
"github.com/drone/drone/server/sync"
|
"github.com/drone/drone/server/sync"
|
||||||
@@ -49,7 +48,7 @@ func GetLogin(c web.C, w http.ResponseWriter, r *http.Request) {
|
|||||||
// if self-registration is disabled we should
|
// if self-registration is disabled we should
|
||||||
// return a notAuthorized error. the only exception
|
// return a notAuthorized error. the only exception
|
||||||
// is if no users exist yet in the system we'll proceed.
|
// is if no users exist yet in the system we'll proceed.
|
||||||
if capability.Enabled(ctx, capability.Registration) == false {
|
if remote.OpenRegistration() == false {
|
||||||
users, err := datastore.GetUserList(ctx)
|
users, err := datastore.GetUserList(ctx)
|
||||||
if err != nil || len(users) != 0 {
|
if err != nil || len(users) != 0 {
|
||||||
log.Println("Unable to create account. Registration is closed")
|
log.Println("Unable to create account. Registration is closed")
|
||||||
|
|||||||
@@ -56,10 +56,6 @@ var (
|
|||||||
sslcrt = config.String("server-ssl-cert", "")
|
sslcrt = config.String("server-ssl-cert", "")
|
||||||
sslkey = config.String("server-ssl-key", "")
|
sslkey = config.String("server-ssl-key", "")
|
||||||
|
|
||||||
// Enable self-registration. When false, the system admin
|
|
||||||
// must grant user access.
|
|
||||||
open = config.Bool("registration-open", false)
|
|
||||||
|
|
||||||
workers *pool.Pool
|
workers *pool.Pool
|
||||||
worker *director.Director
|
worker *director.Director
|
||||||
pub *pubsub.PubSub
|
pub *pubsub.PubSub
|
||||||
@@ -105,7 +101,6 @@ func main() {
|
|||||||
gogs.Register()
|
gogs.Register()
|
||||||
|
|
||||||
caps = map[string]bool{}
|
caps = map[string]bool{}
|
||||||
caps[capability.Registration] = *open
|
|
||||||
|
|
||||||
// setup the database and cancel all pending
|
// setup the database and cancel all pending
|
||||||
// commits in the system.
|
// commits in the system.
|
||||||
|
|||||||
Reference in New Issue
Block a user