mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-09-01 18:02:15 +00:00
Merge pull request #826 from mattbostock/per_plugin_registration
Per-remote open registration
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.
|
||||||
|
@@ -1,23 +0,0 @@
|
|||||||
package capability
|
|
||||||
|
|
||||||
import (
|
|
||||||
"code.google.com/p/go.net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Capability map[string]bool
|
|
||||||
|
|
||||||
// Get the capability value from the map.
|
|
||||||
func (c Capability) Get(key string) bool {
|
|
||||||
return c[key]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets the capability value in the map.
|
|
||||||
func (c Capability) Set(key string, value bool) {
|
|
||||||
c[key] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enabled returns true if the capability is
|
|
||||||
// enabled in the system.
|
|
||||||
func Enabled(c context.Context, key string) bool {
|
|
||||||
return FromContext(c).Get(key)
|
|
||||||
}
|
|
@@ -1,24 +0,0 @@
|
|||||||
package capability
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"code.google.com/p/go.net/context"
|
|
||||||
"github.com/franela/goblin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestBlobstore(t *testing.T) {
|
|
||||||
caps := map[string]bool{}
|
|
||||||
caps[Registration] = true
|
|
||||||
|
|
||||||
ctx := NewContext(context.Background(), caps)
|
|
||||||
|
|
||||||
g := goblin.Goblin(t)
|
|
||||||
g.Describe("Capabilities", func() {
|
|
||||||
|
|
||||||
g.It("Should get capabilities from context", func() {
|
|
||||||
g.Assert(Enabled(ctx, Registration)).Equal(true)
|
|
||||||
g.Assert(Enabled(ctx, "Fake Key")).Equal(false)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
@@ -1,5 +0,0 @@
|
|||||||
package capability
|
|
||||||
|
|
||||||
const (
|
|
||||||
Registration = "REGISTRATION"
|
|
||||||
)
|
|
@@ -1,32 +0,0 @@
|
|||||||
package capability
|
|
||||||
|
|
||||||
import (
|
|
||||||
"code.google.com/p/go.net/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
const reqkey = "capability"
|
|
||||||
|
|
||||||
// NewContext returns a Context whose Value method returns the
|
|
||||||
// application's Blobstore data.
|
|
||||||
func NewContext(parent context.Context, caps Capability) context.Context {
|
|
||||||
return &wrapper{parent, caps}
|
|
||||||
}
|
|
||||||
|
|
||||||
type wrapper struct {
|
|
||||||
context.Context
|
|
||||||
caps Capability
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value returns the named key from the context.
|
|
||||||
func (c *wrapper) Value(key interface{}) interface{} {
|
|
||||||
if key == reqkey {
|
|
||||||
return c.caps
|
|
||||||
}
|
|
||||||
return c.Context.Value(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromContext returns the capability map for the
|
|
||||||
// current context.
|
|
||||||
func FromContext(c context.Context) Capability {
|
|
||||||
return c.Value(reqkey).(Capability)
|
|
||||||
}
|
|
@@ -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")
|
||||||
|
@@ -26,7 +26,6 @@ import (
|
|||||||
"github.com/drone/drone/plugin/remote/gitlab"
|
"github.com/drone/drone/plugin/remote/gitlab"
|
||||||
"github.com/drone/drone/plugin/remote/gogs"
|
"github.com/drone/drone/plugin/remote/gogs"
|
||||||
"github.com/drone/drone/server/blobstore"
|
"github.com/drone/drone/server/blobstore"
|
||||||
"github.com/drone/drone/server/capability"
|
|
||||||
"github.com/drone/drone/server/datastore"
|
"github.com/drone/drone/server/datastore"
|
||||||
"github.com/drone/drone/server/datastore/database"
|
"github.com/drone/drone/server/datastore/database"
|
||||||
"github.com/drone/drone/server/worker/director"
|
"github.com/drone/drone/server/worker/director"
|
||||||
@@ -56,10 +55,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
|
||||||
@@ -70,8 +65,6 @@ var (
|
|||||||
nodes StringArr
|
nodes StringArr
|
||||||
|
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
|
|
||||||
caps map[string]bool
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -104,9 +97,6 @@ func main() {
|
|||||||
gitlab.Register()
|
gitlab.Register()
|
||||||
gogs.Register()
|
gogs.Register()
|
||||||
|
|
||||||
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.
|
||||||
db = database.MustConnect(*driver, *datasource)
|
db = database.MustConnect(*driver, *datasource)
|
||||||
@@ -170,7 +160,6 @@ func ContextMiddleware(c *web.C, h http.Handler) http.Handler {
|
|||||||
ctx = pool.NewContext(ctx, workers)
|
ctx = pool.NewContext(ctx, workers)
|
||||||
ctx = director.NewContext(ctx, worker)
|
ctx = director.NewContext(ctx, worker)
|
||||||
ctx = pubsub.NewContext(ctx, pub)
|
ctx = pubsub.NewContext(ctx, pub)
|
||||||
ctx = capability.NewContext(ctx, caps)
|
|
||||||
|
|
||||||
// add the context to the goji web context
|
// add the context to the goji web context
|
||||||
webcontext.Set(c, ctx)
|
webcontext.Set(c, ctx)
|
||||||
|
Reference in New Issue
Block a user