*: add remote source option to disable registration/login

* Make the new fields RegistrationEnabled/LoginEnabled in types.RemoteSource
bool pointers (since they are new fields that don't exist in previously saved
remote sources) and default them to true if null when unmarshaling (or existing
remotesources will have registration and login disabled)

* Add options to cmd remotesource create/update to set the registration/login
disabled.
This commit is contained in:
Simone Gotti 2019-07-05 13:33:29 +02:00
parent e7864d0d84
commit ee5c829653
6 changed files with 78 additions and 6 deletions

View File

@ -20,6 +20,7 @@ import (
"agola.io/agola/internal/gitsources/github" "agola.io/agola/internal/gitsources/github"
"agola.io/agola/internal/services/gateway/api" "agola.io/agola/internal/services/gateway/api"
"agola.io/agola/internal/services/types" "agola.io/agola/internal/services/types"
"agola.io/agola/internal/util"
"github.com/spf13/cobra" "github.com/spf13/cobra"
errors "golang.org/x/xerrors" errors "golang.org/x/xerrors"
@ -45,6 +46,8 @@ type remoteSourceCreateOptions struct {
oauth2ClientSecret string oauth2ClientSecret string
sshHostKey string sshHostKey string
skipSSHHostKeyCheck bool skipSSHHostKeyCheck bool
registrationEnabled bool
loginEnabled bool
} }
var remoteSourceCreateOpts remoteSourceCreateOptions var remoteSourceCreateOpts remoteSourceCreateOptions
@ -61,6 +64,8 @@ func init() {
flags.StringVar(&remoteSourceCreateOpts.oauth2ClientSecret, "secret", "", "remotesource oauth2 secret") flags.StringVar(&remoteSourceCreateOpts.oauth2ClientSecret, "secret", "", "remotesource oauth2 secret")
flags.StringVar(&remoteSourceCreateOpts.sshHostKey, "ssh-host-key", "", "remotesource ssh public host key") flags.StringVar(&remoteSourceCreateOpts.sshHostKey, "ssh-host-key", "", "remotesource ssh public host key")
flags.BoolVarP(&remoteSourceCreateOpts.skipSSHHostKeyCheck, "skip-ssh-host-key-check", "s", false, "skip ssh host key check") flags.BoolVarP(&remoteSourceCreateOpts.skipSSHHostKeyCheck, "skip-ssh-host-key-check", "s", false, "skip ssh host key check")
flags.BoolVar(&remoteSourceCreateOpts.registrationEnabled, "registration-enabled", true, "enabled/disable user registration with this remote source")
flags.BoolVar(&remoteSourceCreateOpts.loginEnabled, "login-enabled", true, "enabled/disable user login with this remote source")
if err := cmdRemoteSourceCreate.MarkFlagRequired("name"); err != nil { if err := cmdRemoteSourceCreate.MarkFlagRequired("name"); err != nil {
log.Fatal(err) log.Fatal(err)
@ -98,6 +103,8 @@ func remoteSourceCreate(cmd *cobra.Command, args []string) error {
Oauth2ClientSecret: remoteSourceCreateOpts.oauth2ClientSecret, Oauth2ClientSecret: remoteSourceCreateOpts.oauth2ClientSecret,
SSHHostKey: remoteSourceCreateOpts.sshHostKey, SSHHostKey: remoteSourceCreateOpts.sshHostKey,
SkipSSHHostKeyCheck: remoteSourceCreateOpts.skipSSHHostKeyCheck, SkipSSHHostKeyCheck: remoteSourceCreateOpts.skipSSHHostKeyCheck,
RegistrationEnabled: util.BoolP(remoteSourceCreateOpts.registrationEnabled),
LoginEnabled: util.BoolP(remoteSourceCreateOpts.loginEnabled),
} }
log.Infof("creating remotesource") log.Infof("creating remotesource")

View File

@ -43,6 +43,8 @@ type remoteSourceUpdateOptions struct {
oauth2ClientSecret string oauth2ClientSecret string
sshHostKey string sshHostKey string
skipSSHHostKeyCheck bool skipSSHHostKeyCheck bool
registrationEnabled bool
loginEnabled bool
} }
var remoteSourceUpdateOpts remoteSourceUpdateOptions var remoteSourceUpdateOpts remoteSourceUpdateOptions
@ -58,6 +60,8 @@ func init() {
flags.StringVar(&remoteSourceUpdateOpts.oauth2ClientSecret, "secret", "", "remotesource oauth2 secret") flags.StringVar(&remoteSourceUpdateOpts.oauth2ClientSecret, "secret", "", "remotesource oauth2 secret")
flags.StringVar(&remoteSourceUpdateOpts.sshHostKey, "ssh-host-key", "", "remotesource ssh public host key") flags.StringVar(&remoteSourceUpdateOpts.sshHostKey, "ssh-host-key", "", "remotesource ssh public host key")
flags.BoolVarP(&remoteSourceUpdateOpts.skipSSHHostKeyCheck, "skip-ssh-host-key-check", "s", false, "skip ssh host key check") flags.BoolVarP(&remoteSourceUpdateOpts.skipSSHHostKeyCheck, "skip-ssh-host-key-check", "s", false, "skip ssh host key check")
flags.BoolVar(&remoteSourceUpdateOpts.registrationEnabled, "registration-enabled", false, "enabled/disable user registration with this remote source")
flags.BoolVar(&remoteSourceUpdateOpts.loginEnabled, "login-enabled", false, "enabled/disable user login with this remote source")
if err := cmdRemoteSourceUpdate.MarkFlagRequired("ref"); err != nil { if err := cmdRemoteSourceUpdate.MarkFlagRequired("ref"); err != nil {
log.Fatal(err) log.Fatal(err)
@ -93,6 +97,12 @@ func remoteSourceUpdate(cmd *cobra.Command, args []string) error {
if flags.Changed("skip-ssh-host-key-check") { if flags.Changed("skip-ssh-host-key-check") {
req.SkipSSHHostKeyCheck = &remoteSourceUpdateOpts.skipSSHHostKeyCheck req.SkipSSHHostKeyCheck = &remoteSourceUpdateOpts.skipSSHHostKeyCheck
} }
if flags.Changed("registration-enabled") {
req.RegistrationEnabled = &remoteSourceUpdateOpts.registrationEnabled
}
if flags.Changed("login-enabled") {
req.LoginEnabled = &remoteSourceUpdateOpts.loginEnabled
}
log.Infof("updating remotesource") log.Infof("updating remotesource")
remoteSource, _, err := gwclient.UpdateRemoteSource(context.TODO(), remoteSourceUpdateOpts.ref, req) remoteSource, _, err := gwclient.UpdateRemoteSource(context.TODO(), remoteSourceUpdateOpts.ref, req)

View File

@ -55,6 +55,8 @@ type CreateRemoteSourceRequest struct {
Oauth2ClientSecret string Oauth2ClientSecret string
SSHHostKey string SSHHostKey string
SkipSSHHostKeyCheck bool SkipSSHHostKeyCheck bool
RegistrationEnabled *bool
LoginEnabled *bool
} }
func (h *ActionHandler) CreateRemoteSource(ctx context.Context, req *CreateRemoteSourceRequest) (*types.RemoteSource, error) { func (h *ActionHandler) CreateRemoteSource(ctx context.Context, req *CreateRemoteSourceRequest) (*types.RemoteSource, error) {
@ -103,6 +105,8 @@ func (h *ActionHandler) CreateRemoteSource(ctx context.Context, req *CreateRemot
Oauth2ClientSecret: req.Oauth2ClientSecret, Oauth2ClientSecret: req.Oauth2ClientSecret,
SSHHostKey: req.SSHHostKey, SSHHostKey: req.SSHHostKey,
SkipSSHHostKeyCheck: req.SkipSSHHostKeyCheck, SkipSSHHostKeyCheck: req.SkipSSHHostKeyCheck,
RegistrationEnabled: req.RegistrationEnabled,
LoginEnabled: req.LoginEnabled,
} }
h.log.Infof("creating remotesource") h.log.Infof("creating remotesource")
@ -125,6 +129,8 @@ type UpdateRemoteSourceRequest struct {
Oauth2ClientSecret *string Oauth2ClientSecret *string
SSHHostKey *string SSHHostKey *string
SkipSSHHostKeyCheck *bool SkipSSHHostKeyCheck *bool
RegistrationEnabled *bool
LoginEnabled *bool
} }
func (h *ActionHandler) UpdateRemoteSource(ctx context.Context, req *UpdateRemoteSourceRequest) (*types.RemoteSource, error) { func (h *ActionHandler) UpdateRemoteSource(ctx context.Context, req *UpdateRemoteSourceRequest) (*types.RemoteSource, error) {
@ -158,6 +164,12 @@ func (h *ActionHandler) UpdateRemoteSource(ctx context.Context, req *UpdateRemot
if req.SkipSSHHostKeyCheck != nil { if req.SkipSSHHostKeyCheck != nil {
rs.SkipSSHHostKeyCheck = *req.SkipSSHHostKeyCheck rs.SkipSSHHostKeyCheck = *req.SkipSSHHostKeyCheck
} }
if req.RegistrationEnabled != nil {
rs.RegistrationEnabled = req.RegistrationEnabled
}
if req.LoginEnabled != nil {
rs.LoginEnabled = req.LoginEnabled
}
h.log.Infof("updating remotesource") h.log.Infof("updating remotesource")
rs, resp, err = h.configstoreClient.UpdateRemoteSource(ctx, req.RemoteSourceRef, rs) rs, resp, err = h.configstoreClient.UpdateRemoteSource(ctx, req.RemoteSourceRef, rs)

View File

@ -311,6 +311,9 @@ func (h *ActionHandler) RegisterUser(ctx context.Context, req *RegisterUserReque
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get remote source %q: %w", req.RemoteSourceName, ErrFromRemote(resp, err)) return nil, errors.Errorf("failed to get remote source %q: %w", req.RemoteSourceName, ErrFromRemote(resp, err))
} }
if !*rs.RegistrationEnabled {
return nil, util.NewErrBadRequest(errors.Errorf("remote source user registration is disabled"))
}
accessToken, err := common.GetAccessToken(rs, req.UserAccessToken, req.Oauth2AccessToken) accessToken, err := common.GetAccessToken(rs, req.UserAccessToken, req.Oauth2AccessToken)
if err != nil { if err != nil {
@ -370,6 +373,9 @@ func (h *ActionHandler) LoginUser(ctx context.Context, req *LoginUserRequest) (*
if err != nil { if err != nil {
return nil, errors.Errorf("failed to get remote source %q: %w", req.RemoteSourceName, ErrFromRemote(resp, err)) return nil, errors.Errorf("failed to get remote source %q: %w", req.RemoteSourceName, ErrFromRemote(resp, err))
} }
if !*rs.LoginEnabled {
return nil, util.NewErrBadRequest(errors.Errorf("remote source user login is disabled"))
}
accessToken, err := common.GetAccessToken(rs, req.UserAccessToken, req.Oauth2AccessToken) accessToken, err := common.GetAccessToken(rs, req.UserAccessToken, req.Oauth2AccessToken)
if err != nil { if err != nil {

View File

@ -38,6 +38,8 @@ type CreateRemoteSourceRequest struct {
Oauth2ClientSecret string `json:"oauth_2_client_secret"` Oauth2ClientSecret string `json:"oauth_2_client_secret"`
SSHHostKey string `json:"ssh_host_key"` SSHHostKey string `json:"ssh_host_key"`
SkipSSHHostKeyCheck bool `json:"skip_ssh_host_key_check"` SkipSSHHostKeyCheck bool `json:"skip_ssh_host_key_check"`
RegistrationEnabled *bool `json:"registration_enabled"`
LoginEnabled *bool `json:"login_enabled"`
} }
type CreateRemoteSourceHandler struct { type CreateRemoteSourceHandler struct {
@ -69,6 +71,8 @@ func (h *CreateRemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
Oauth2ClientSecret: req.Oauth2ClientSecret, Oauth2ClientSecret: req.Oauth2ClientSecret,
SSHHostKey: req.SSHHostKey, SSHHostKey: req.SSHHostKey,
SkipSSHHostKeyCheck: req.SkipSSHHostKeyCheck, SkipSSHHostKeyCheck: req.SkipSSHHostKeyCheck,
RegistrationEnabled: req.RegistrationEnabled,
LoginEnabled: req.LoginEnabled,
} }
rs, err := h.ah.CreateRemoteSource(ctx, creq) rs, err := h.ah.CreateRemoteSource(ctx, creq)
if httpError(w, err) { if httpError(w, err) {
@ -90,6 +94,8 @@ type UpdateRemoteSourceRequest struct {
Oauth2ClientSecret *string `json:"oauth_2_client_secret"` Oauth2ClientSecret *string `json:"oauth_2_client_secret"`
SSHHostKey *string `json:"ssh_host_key"` SSHHostKey *string `json:"ssh_host_key"`
SkipSSHHostKeyCheck *bool `json:"skip_ssh_host_key_check"` SkipSSHHostKeyCheck *bool `json:"skip_ssh_host_key_check"`
RegistrationEnabled *bool `json:"registration_enabled"`
LoginEnabled *bool `json:"login_enabled"`
} }
type UpdateRemoteSourceHandler struct { type UpdateRemoteSourceHandler struct {
@ -123,6 +129,8 @@ func (h *UpdateRemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
Oauth2ClientSecret: req.Oauth2ClientSecret, Oauth2ClientSecret: req.Oauth2ClientSecret,
SSHHostKey: req.SSHHostKey, SSHHostKey: req.SSHHostKey,
SkipSSHHostKeyCheck: req.SkipSSHHostKeyCheck, SkipSSHHostKeyCheck: req.SkipSSHHostKeyCheck,
RegistrationEnabled: req.RegistrationEnabled,
LoginEnabled: req.LoginEnabled,
} }
rs, err := h.ah.UpdateRemoteSource(ctx, creq) rs, err := h.ah.UpdateRemoteSource(ctx, creq)
if httpError(w, err) { if httpError(w, err) {
@ -137,16 +145,20 @@ func (h *UpdateRemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Req
} }
type RemoteSourceResponse struct { type RemoteSourceResponse struct {
ID string `json:"id"` ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`
AuthType string `json:"auth_type"` AuthType string `json:"auth_type"`
RegistrationEnabled bool `json:"registration_enabled"`
LoginEnabled bool `json:"login_enabled"`
} }
func createRemoteSourceResponse(r *types.RemoteSource) *RemoteSourceResponse { func createRemoteSourceResponse(r *types.RemoteSource) *RemoteSourceResponse {
rs := &RemoteSourceResponse{ rs := &RemoteSourceResponse{
ID: r.ID, ID: r.ID,
Name: r.Name, Name: r.Name,
AuthType: string(r.AuthType), AuthType: string(r.AuthType),
RegistrationEnabled: *r.RegistrationEnabled,
LoginEnabled: *r.LoginEnabled,
} }
return rs return rs
} }

View File

@ -15,9 +15,12 @@
package types package types
import ( import (
"encoding/json"
"fmt" "fmt"
"regexp" "regexp"
"time" "time"
"agola.io/agola/internal/util"
) )
// Configstore types // Configstore types
@ -175,6 +178,28 @@ type RemoteSource struct {
SSHHostKey string `json:"ssh_host_key,omitempty"` // Public ssh host key of the remote source SSHHostKey string `json:"ssh_host_key,omitempty"` // Public ssh host key of the remote source
SkipSSHHostKeyCheck bool `json:"skip_ssh_host_key_check,omitempty"` SkipSSHHostKeyCheck bool `json:"skip_ssh_host_key_check,omitempty"`
RegistrationEnabled *bool `json:"registration_enabled,omitempty"`
LoginEnabled *bool `json:"login_enabled,omitempty"`
}
func (rs *RemoteSource) UnmarshalJSON(b []byte) error {
type remoteSource RemoteSource
trs := (*remoteSource)(rs)
if err := json.Unmarshal(b, &trs); err != nil {
return err
}
if trs.RegistrationEnabled == nil {
trs.RegistrationEnabled = util.BoolP(true)
}
if trs.LoginEnabled == nil {
trs.LoginEnabled = util.BoolP(true)
}
return nil
} }
func SourceSupportedAuthTypes(rsType RemoteSourceType) []RemoteSourceAuthType { func SourceSupportedAuthTypes(rsType RemoteSourceType) []RemoteSourceAuthType {