From 9e3f06972babc3d11b5c9cfb0f369c1a62293ff9 Mon Sep 17 00:00:00 2001 From: noah Date: Wed, 22 Sep 2021 22:06:37 +0900 Subject: [PATCH 1/6] Fix the type of payload --- vo/config.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vo/config.go b/vo/config.go index f1508b13..6f06c02f 100644 --- a/vo/config.go +++ b/vo/config.go @@ -18,12 +18,12 @@ type ( Name string `json:"name" yaml:"name"` // Github parameters of deployment. - Task *string `json:"task" yaml:"task"` - Description *string `json:"description" yaml:"description"` - AutoMerge *bool `json:"auto_merge" yaml:"auto_merge"` - RequiredContexts *[]string `json:"required_contexts,omitempty" yaml:"required_contexts"` - Payload *string `json:"payload" yaml:"payload"` - ProductionEnvironment *bool `json:"production_environment" yaml:"production_environment"` + Task *string `json:"task" yaml:"task"` + Description *string `json:"description" yaml:"description"` + AutoMerge *bool `json:"auto_merge" yaml:"auto_merge"` + RequiredContexts *[]string `json:"required_contexts,omitempty" yaml:"required_contexts"` + Payload interface{} `json:"payload" yaml:"payload"` + ProductionEnvironment *bool `json:"production_environment" yaml:"production_environment"` // Approval is the configuration of Approval, // It is disabled when it is empty. From ed2bdf9779b499655554511021669ee57a11e38b Mon Sep 17 00:00:00 2001 From: noah Date: Wed, 22 Sep 2021 22:07:00 +0900 Subject: [PATCH 2/6] Fix doc for deploy.yml --- docs/references/deploy.yml.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/references/deploy.yml.md b/docs/references/deploy.yml.md index c93a7c13..e1797043 100644 --- a/docs/references/deploy.yml.md +++ b/docs/references/deploy.yml.md @@ -10,6 +10,7 @@ Field |Type |Required |Description `description` |*string* |`false` |This field is the short description of the deployment. `auto_merge` |*boolean* |`false` |This field is used to ensure that the requested ref is not behind the repository's default branch. If you deploy with the commit or the tag you need to set `false`. For rollback, Gitploy set the field `false`. `required_contexts` |*[]string* |`false` |This field allows you to specify a subset of contexts that must be success. +`payload` |*object* or *string* |`false` |This field is JSON payload with extra information about the deployment. `production_environment` |*boolean* |`false` |This field specifies whether this runtime environment is production or not. `approval` |*[Approval](#approval)* |`false` |This field configures approval. From 87b5067dbb0abe7e280ff66eadbfa2a29ba13c58 Mon Sep 17 00:00:00 2001 From: noah Date: Wed, 22 Sep 2021 22:20:19 +0900 Subject: [PATCH 3/6] Fix to prevent logic when it hits the limit --- internal/server/web/index.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/server/web/index.go b/internal/server/web/index.go index 02d45dd3..a5e9d860 100644 --- a/internal/server/web/index.go +++ b/internal/server/web/index.go @@ -124,8 +124,8 @@ func (w *Web) Signin(c *gin.Context) { return } - if lic.IsOverLimit() { - w.log.Error("There are no more seats.", zap.Error(err)) + if lic.MemberCount >= lic.MemberLimit { + w.log.Warn("There are no more seats. It prevents to over the limit.", zap.Error(err)) c.String(http.StatusPaymentRequired, "There are no more seats.") return } From 35b3722355021f680a568b483dbc79150039299a Mon Sep 17 00:00:00 2001 From: noah Date: Wed, 22 Sep 2021 22:44:53 +0900 Subject: [PATCH 4/6] Update to check login that is in members --- cmd/server/config.go | 1 + cmd/server/main.go | 15 ++++++++------- internal/interactor/interactor.go | 29 ++++++++++++++++------------- internal/interactor/user.go | 15 +++++++++++++++ internal/interactor/user_test.go | 13 +++++++++++++ internal/server/web/index.go | 20 ++++++++++++++------ internal/server/web/interface.go | 1 + 7 files changed, 68 insertions(+), 26 deletions(-) diff --git a/cmd/server/config.go b/cmd/server/config.go index 3b5d626b..49d1a619 100644 --- a/cmd/server/config.go +++ b/cmd/server/config.go @@ -25,6 +25,7 @@ type ( ServerProxyProto string `default:"https" split_words:"true"` OrganizationEntries []string `split_words:"true"` + MemberEntries []string `split_words:"true"` AdminUsers []string `split_words:"true"` License string `split_words:"true"` diff --git a/cmd/server/main.go b/cmd/server/main.go index 800a2048..03d9005c 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -133,13 +133,14 @@ func newChatConfig(c *Config) *server.ChatConfig { func NewInteractor(c *Config) server.Interactor { return interactor.NewInteractor( &interactor.InteractorConfig{ - ServerHost: c.ServerHost, - ServerProto: c.ServerProto, - OrgEntries: c.OrganizationEntries, - AdminUsers: c.AdminUsers, - LicenseKey: c.License, - Store: newStore(c), - SCM: newSCM(c), + ServerHost: c.ServerHost, + ServerProto: c.ServerProto, + OrgEntries: c.OrganizationEntries, + MemberEntries: c.MemberEntries, + AdminUsers: c.AdminUsers, + LicenseKey: c.License, + Store: newStore(c), + SCM: newSCM(c), }, ) } diff --git a/internal/interactor/interactor.go b/internal/interactor/interactor.go index e2c3b052..44ab7a5d 100644 --- a/internal/interactor/interactor.go +++ b/internal/interactor/interactor.go @@ -11,7 +11,8 @@ type ( ServerHost string ServerProto string - orgEntries []string + orgEntries []string + memberEntries []string // Admin Users admins []string @@ -32,8 +33,9 @@ type ( ServerHost string ServerProto string - OrgEntries []string - AdminUsers []string + OrgEntries []string + MemberEntries []string + AdminUsers []string LicenseKey string @@ -44,16 +46,17 @@ type ( func NewInteractor(c *InteractorConfig) *Interactor { i := &Interactor{ - ServerHost: c.ServerHost, - ServerProto: c.ServerProto, - orgEntries: c.OrgEntries, - admins: c.AdminUsers, - licenseKey: c.LicenseKey, - Store: c.Store, - SCM: c.SCM, - stopCh: make(chan struct{}), - events: evbus.New(), - log: zap.L().Named("interactor"), + ServerHost: c.ServerHost, + ServerProto: c.ServerProto, + orgEntries: c.OrgEntries, + memberEntries: c.MemberEntries, + admins: c.AdminUsers, + licenseKey: c.LicenseKey, + Store: c.Store, + SCM: c.SCM, + stopCh: make(chan struct{}), + events: evbus.New(), + log: zap.L().Named("interactor"), } go func() { diff --git a/internal/interactor/user.go b/internal/interactor/user.go index 292195bd..91b38493 100644 --- a/internal/interactor/user.go +++ b/internal/interactor/user.go @@ -19,3 +19,18 @@ func (i *Interactor) IsAdminUser(ctx context.Context, login string) bool { return false } + +func (i *Interactor) IsEntryMember(ctx context.Context, login string) bool { + if i.memberEntries == nil { + return true + } + + for _, m := range i.memberEntries { + if login == m { + return true + } + } + + return false + +} diff --git a/internal/interactor/user_test.go b/internal/interactor/user_test.go index 5a263c39..c0ddac2e 100644 --- a/internal/interactor/user_test.go +++ b/internal/interactor/user_test.go @@ -17,3 +17,16 @@ func TestInteractor_IsAdminUser(t *testing.T) { } }) } + +func TestInteractor_IsEntryMember(t *testing.T) { + t.Run("Return false when the user's login is not includes.", func(t *testing.T) { + i := &Interactor{ + memberEntries: []string{"octocat"}, + } + + want := false + if ret := i.IsEntryMember(context.Background(), "coco"); ret != want { + t.Fatalf("IsEntryMember = %v, wanted %v", ret, want) + } + }) +} diff --git a/internal/server/web/index.go b/internal/server/web/index.go index a5e9d860..70878cbe 100644 --- a/internal/server/web/index.go +++ b/internal/server/web/index.go @@ -84,14 +84,14 @@ func (w *Web) Signin(c *gin.Context) { t, err := w.c.Exchange(c, code) if err != nil { - w.log.Error("failed to exchange the code.", zap.Error(err)) - c.String(http.StatusInternalServerError, "There is an issue to exchange the code.") + w.log.Error("It has failed to exchange the code.", zap.Error(err)) + c.String(http.StatusUnauthorized, "There is an issue to exchange the code.") return } if !t.Valid() { w.log.Error("invalid token.", zap.Error(err)) - c.String(http.StatusInternalServerError, "It's a invalid token.") + c.String(http.StatusUnauthorized, "It's a invalid token.") return } @@ -104,6 +104,15 @@ func (w *Web) Signin(c *gin.Context) { return } + // Check the login of user who is member and admin. + if !w.i.IsEntryMember(ctx, ru.Login) { + w.log.Warn("This login is not member.", zap.String("login", ru.Login)) + c.String(http.StatusUnauthorized, "This login is not member. You should ask to the administrator.") + return + } + + admin := w.i.IsAdminUser(ctx, ru.Login) + // Synchronize from the remote user. It synchronizes // user information and save generated OAuth token. u := &ent.User{ @@ -113,7 +122,7 @@ func (w *Web) Signin(c *gin.Context) { Token: t.AccessToken, Refresh: t.RefreshToken, Expiry: t.Expiry, - Admin: w.i.IsAdminUser(ctx, ru.Login), + Admin: admin, } if _, err = w.i.FindUserByID(ctx, u.ID); ent.IsNotFound(err) { @@ -125,12 +134,11 @@ func (w *Web) Signin(c *gin.Context) { } if lic.MemberCount >= lic.MemberLimit { - w.log.Warn("There are no more seats. It prevents to over the limit.", zap.Error(err)) + w.log.Warn("There are no more seats. It prevents to over the limit.", zap.Int("member_count", lic.MemberCount), zap.Int("member_limit", lic.MemberLimit)) c.String(http.StatusPaymentRequired, "There are no more seats.") return } - w.log.Debug("Check the count of member.", zap.Int("member_count", lic.MemberCount), zap.Int("member_limit", lic.MemberLimit)) u, _ = w.i.CreateUser(ctx, u) } else if err != nil { w.log.Error("It failed to save the user.", zap.Error(err)) diff --git a/internal/server/web/interface.go b/internal/server/web/interface.go index f7f07a55..7b9afff9 100644 --- a/internal/server/web/interface.go +++ b/internal/server/web/interface.go @@ -11,6 +11,7 @@ type ( Interactor interface { FindUserByID(ctx context.Context, id string) (*ent.User, error) IsAdminUser(ctx context.Context, login string) bool + IsEntryMember(ctx context.Context, login string) bool CreateUser(ctx context.Context, u *ent.User) (*ent.User, error) UpdateUser(ctx context.Context, u *ent.User) (*ent.User, error) // Fetch the user information from SCM. From e364932b7e35f6d72d90dc5671505d6451998661 Mon Sep 17 00:00:00 2001 From: noah Date: Wed, 22 Sep 2021 23:19:07 +0900 Subject: [PATCH 5/6] Update to match with orgs --- internal/interactor/interface.go | 3 ++- internal/interactor/mock/pkg.go | 43 +++++++++++++++++++++----------- internal/interactor/user.go | 17 ++++++++----- internal/interactor/user_test.go | 37 ++++++++++++++++++++++++++- internal/pkg/github/web.go | 20 ++++++++++++++- internal/server/web/index.go | 15 ++++++++--- internal/server/web/interface.go | 2 ++ 7 files changed, 111 insertions(+), 26 deletions(-) diff --git a/internal/interactor/interface.go b/internal/interactor/interface.go index b7c1fa98..9216fcc5 100644 --- a/internal/interactor/interface.go +++ b/internal/interactor/interface.go @@ -73,7 +73,8 @@ type ( } SCM interface { - GetUser(ctx context.Context, token string) (*vo.RemoteUser, error) + GetRemoteUserByToken(ctx context.Context, token string) (*vo.RemoteUser, error) + ListRemoteOrgsByToken(ctx context.Context, token string) ([]string, error) ListRemoteRepos(ctx context.Context, u *ent.User) ([]*vo.RemoteRepo, error) diff --git a/internal/interactor/mock/pkg.go b/internal/interactor/mock/pkg.go index d90079f0..856514fa 100644 --- a/internal/interactor/mock/pkg.go +++ b/internal/interactor/mock/pkg.go @@ -911,34 +911,34 @@ func (mr *MockSCMMockRecorder) GetRateLimit(ctx, u interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRateLimit", reflect.TypeOf((*MockSCM)(nil).GetRateLimit), ctx, u) } -// GetTag mocks base method. -func (m *MockSCM) GetTag(ctx context.Context, u *ent.User, r *ent.Repo, tag string) (*vo.Tag, error) { +// GetRemoteUserByToken mocks base method. +func (m *MockSCM) GetRemoteUserByToken(ctx context.Context, token string) (*vo.RemoteUser, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTag", ctx, u, r, tag) - ret0, _ := ret[0].(*vo.Tag) + ret := m.ctrl.Call(m, "GetRemoteUserByToken", ctx, token) + ret0, _ := ret[0].(*vo.RemoteUser) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetTag indicates an expected call of GetTag. -func (mr *MockSCMMockRecorder) GetTag(ctx, u, r, tag interface{}) *gomock.Call { +// GetRemoteUserByToken indicates an expected call of GetRemoteUserByToken. +func (mr *MockSCMMockRecorder) GetRemoteUserByToken(ctx, token interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTag", reflect.TypeOf((*MockSCM)(nil).GetTag), ctx, u, r, tag) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRemoteUserByToken", reflect.TypeOf((*MockSCM)(nil).GetRemoteUserByToken), ctx, token) } -// GetUser mocks base method. -func (m *MockSCM) GetUser(ctx context.Context, token string) (*vo.RemoteUser, error) { +// GetTag mocks base method. +func (m *MockSCM) GetTag(ctx context.Context, u *ent.User, r *ent.Repo, tag string) (*vo.Tag, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetUser", ctx, token) - ret0, _ := ret[0].(*vo.RemoteUser) + ret := m.ctrl.Call(m, "GetTag", ctx, u, r, tag) + ret0, _ := ret[0].(*vo.Tag) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetUser indicates an expected call of GetUser. -func (mr *MockSCMMockRecorder) GetUser(ctx, token interface{}) *gomock.Call { +// GetTag indicates an expected call of GetTag. +func (mr *MockSCMMockRecorder) GetTag(ctx, u, r, tag interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUser", reflect.TypeOf((*MockSCM)(nil).GetUser), ctx, token) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTag", reflect.TypeOf((*MockSCM)(nil).GetTag), ctx, u, r, tag) } // ListBranches mocks base method. @@ -986,6 +986,21 @@ func (mr *MockSCMMockRecorder) ListCommits(ctx, u, r, branch, page, perPage inte return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListCommits", reflect.TypeOf((*MockSCM)(nil).ListCommits), ctx, u, r, branch, page, perPage) } +// ListRemoteOrgsByToken mocks base method. +func (m *MockSCM) ListRemoteOrgsByToken(ctx context.Context, token string) ([]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListRemoteOrgsByToken", ctx, token) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ListRemoteOrgsByToken indicates an expected call of ListRemoteOrgsByToken. +func (mr *MockSCMMockRecorder) ListRemoteOrgsByToken(ctx, token interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListRemoteOrgsByToken", reflect.TypeOf((*MockSCM)(nil).ListRemoteOrgsByToken), ctx, token) +} + // ListRemoteRepos mocks base method. func (m *MockSCM) ListRemoteRepos(ctx context.Context, u *ent.User) ([]*vo.RemoteRepo, error) { m.ctrl.T.Helper() diff --git a/internal/interactor/user.go b/internal/interactor/user.go index 91b38493..db8d85fc 100644 --- a/internal/interactor/user.go +++ b/internal/interactor/user.go @@ -2,14 +2,8 @@ package interactor import ( "context" - - "github.com/gitploy-io/gitploy/vo" ) -func (i *Interactor) GetRemoteUserByToken(ctx context.Context, token string) (*vo.RemoteUser, error) { - return i.SCM.GetUser(ctx, token) -} - func (i *Interactor) IsAdminUser(ctx context.Context, login string) bool { for _, admin := range i.admins { if login == admin { @@ -32,5 +26,16 @@ func (i *Interactor) IsEntryMember(ctx context.Context, login string) bool { } return false +} +func (i *Interactor) IsOrgMember(ctx context.Context, orgs []string) bool { + for _, o := range orgs { + for _, entry := range i.memberEntries { + if o == entry { + return true + } + } + } + + return false } diff --git a/internal/interactor/user_test.go b/internal/interactor/user_test.go index c0ddac2e..5913dc96 100644 --- a/internal/interactor/user_test.go +++ b/internal/interactor/user_test.go @@ -19,7 +19,7 @@ func TestInteractor_IsAdminUser(t *testing.T) { } func TestInteractor_IsEntryMember(t *testing.T) { - t.Run("Return false when the user's login is not includes.", func(t *testing.T) { + t.Run("Return false when the user's login is not included.", func(t *testing.T) { i := &Interactor{ memberEntries: []string{"octocat"}, } @@ -29,4 +29,39 @@ func TestInteractor_IsEntryMember(t *testing.T) { t.Fatalf("IsEntryMember = %v, wanted %v", ret, want) } }) + + t.Run("Return true when the user's login is included.", func(t *testing.T) { + i := &Interactor{ + memberEntries: []string{"octocat"}, + } + + want := true + if ret := i.IsEntryMember(context.Background(), "octocat"); ret != want { + t.Fatalf("IsEntryMember = %v, wanted %v", ret, want) + } + }) +} + +func TestInteractor_IsOrgMember(t *testing.T) { + t.Run("Return false when the org is not included.", func(t *testing.T) { + i := &Interactor{ + memberEntries: []string{"gitploy-io"}, + } + + want := false + if ret := i.IsOrgMember(context.Background(), []string{"github"}); ret != want { + t.Fatalf("IsEntryMember = %v, wanted %v", ret, want) + } + }) + + t.Run("Return true when the org is included.", func(t *testing.T) { + i := &Interactor{ + memberEntries: []string{"gitploy-io"}, + } + + want := true + if ret := i.IsOrgMember(context.Background(), []string{"gitploy-io"}); ret != want { + t.Fatalf("IsEntryMember = %v, wanted %v", ret, want) + } + }) } diff --git a/internal/pkg/github/web.go b/internal/pkg/github/web.go index d7c91fe7..c487d813 100644 --- a/internal/pkg/github/web.go +++ b/internal/pkg/github/web.go @@ -4,9 +4,10 @@ import ( "context" "github.com/gitploy-io/gitploy/vo" + "github.com/google/go-github/v32/github" ) -func (g *Github) GetUser(ctx context.Context, token string) (*vo.RemoteUser, error) { +func (g *Github) GetRemoteUserByToken(ctx context.Context, token string) (*vo.RemoteUser, error) { c := g.Client(ctx, token) u, _, err := c.Users.Get(ctx, "") @@ -16,3 +17,20 @@ func (g *Github) GetUser(ctx context.Context, token string) (*vo.RemoteUser, err return mapGithubUserToUser(u), err } + +func (g *Github) ListRemoteOrgsByToken(ctx context.Context, token string) ([]string, error) { + // TODO: List all orgs. + orgs, _, err := g.Client(ctx, token). + Organizations. + List(ctx, "", &github.ListOptions{}) + if err != nil { + return nil, err + } + + ret := []string{} + for _, o := range orgs { + ret = append(ret, *o.Login) + } + + return ret, nil +} diff --git a/internal/server/web/index.go b/internal/server/web/index.go index 70878cbe..0e25e93e 100644 --- a/internal/server/web/index.go +++ b/internal/server/web/index.go @@ -99,13 +99,22 @@ func (w *Web) Signin(c *gin.Context) { ru, err := w.i.GetRemoteUserByToken(ctx, t.AccessToken) if err != nil { - w.log.Error("failed to fetch a user from SCM.", zap.Error(err)) - c.String(http.StatusInternalServerError, "It has failed to fetch a user from SCM.") + w.log.Error("It has failed to get the remote user.", zap.Error(err)) + c.String(http.StatusInternalServerError, "It has failed to get the remote user.") return } + w.log.Debug("Get user's login.", zap.String("login", ru.Login)) + + orgs, err := w.i.ListRemoteOrgsByToken(ctx, t.AccessToken) + if err != nil { + w.log.Error("It has failed to list remote orgs.", zap.Error(err)) + c.String(http.StatusInternalServerError, "It has failed to list remote orgs.") + return + } + w.log.Debug("List remote orgs.", zap.Strings("orgs", orgs)) // Check the login of user who is member and admin. - if !w.i.IsEntryMember(ctx, ru.Login) { + if !(w.i.IsEntryMember(ctx, ru.Login) || w.i.IsOrgMember(ctx, orgs)) { w.log.Warn("This login is not member.", zap.String("login", ru.Login)) c.String(http.StatusUnauthorized, "This login is not member. You should ask to the administrator.") return diff --git a/internal/server/web/interface.go b/internal/server/web/interface.go index 7b9afff9..f9ff3525 100644 --- a/internal/server/web/interface.go +++ b/internal/server/web/interface.go @@ -12,11 +12,13 @@ type ( FindUserByID(ctx context.Context, id string) (*ent.User, error) IsAdminUser(ctx context.Context, login string) bool IsEntryMember(ctx context.Context, login string) bool + IsOrgMember(ctx context.Context, orgs []string) bool CreateUser(ctx context.Context, u *ent.User) (*ent.User, error) UpdateUser(ctx context.Context, u *ent.User) (*ent.User, error) // Fetch the user information from SCM. // It has the id, login, avatar and so on. GetRemoteUserByToken(ctx context.Context, token string) (*vo.RemoteUser, error) + ListRemoteOrgsByToken(ctx context.Context, token string) ([]string, error) FindUserByHash(ctx context.Context, hash string) (*ent.User, error) GetLicense(ctx context.Context) (*vo.License, error) } From 82e62647c2cd58fc11a9900ce57ca678fba23b57 Mon Sep 17 00:00:00 2001 From: noah Date: Wed, 22 Sep 2021 23:24:04 +0900 Subject: [PATCH 6/6] Add doc --- docs/references/GITPLOY_MEMBER_ENTRIES.md | 7 +++++++ docs/references/configurations.md | 1 + internal/server/web/index.go | 4 ++-- 3 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 docs/references/GITPLOY_MEMBER_ENTRIES.md diff --git a/docs/references/GITPLOY_MEMBER_ENTRIES.md b/docs/references/GITPLOY_MEMBER_ENTRIES.md new file mode 100644 index 00000000..33c19228 --- /dev/null +++ b/docs/references/GITPLOY_MEMBER_ENTRIES.md @@ -0,0 +1,7 @@ +# GITPLOY_MEMBER_ENTRIES + +Optional comma-separated list of accounts, used to limit to users in this list, or users that are members of organizations included in this list. + +``` +GITPLOY_MEMBER_ENTRIES=octocat,gitploy-io +``` diff --git a/docs/references/configurations.md b/docs/references/configurations.md index 6d009bcf..e8f55517 100644 --- a/docs/references/configurations.md +++ b/docs/references/configurations.md @@ -8,6 +8,7 @@ Index of server configuration settings: * [GITPLOY_PROXY_SERVER_PROTO](./GITPLOY_PROXY_SERVER_PROTO.md) * [GITPLOY_WEBHOOK_SECRET](./GITPLOY_WEBHOOK_SECRET.md) * [GITPLOY_ORGANIZATION_ENTRIES](./GITPLOY_ORGANIZATION_ENTRIES.md) +* [GITPLOY_MEMBER_ENTRIES](./GITPLOY_MEMBER_ENTRIES.md) * [GITPLOY_ADMIN_USERS](./GITPLOY_ADMIN_USERS.md) * [GITPLOY_GITHUB_CLIENT_ID](./GITPLOY_GITHUB_CLIENT_ID.md) * [GITPLOY_GITHUB_CLIENT_SECRET](./GITPLOY_GITHUB_CLIENT_SECRET.md) diff --git a/internal/server/web/index.go b/internal/server/web/index.go index 0e25e93e..dc524ada 100644 --- a/internal/server/web/index.go +++ b/internal/server/web/index.go @@ -115,8 +115,8 @@ func (w *Web) Signin(c *gin.Context) { // Check the login of user who is member and admin. if !(w.i.IsEntryMember(ctx, ru.Login) || w.i.IsOrgMember(ctx, orgs)) { - w.log.Warn("This login is not member.", zap.String("login", ru.Login)) - c.String(http.StatusUnauthorized, "This login is not member. You should ask to the administrator.") + w.log.Warn("This login not a member of an approved organization.", zap.String("login", ru.Login)) + c.String(http.StatusUnauthorized, "You are not a member of an approved organization.") return }