From 7497561d9c47872b61e2472b6848446ebb41d724 Mon Sep 17 00:00:00 2001 From: Umputun Date: Sun, 8 Mar 2020 15:24:56 -0500 Subject: [PATCH] set anonymose with admin names to blocked #605 --- backend/app/cmd/server.go | 17 +++++++++++ backend/app/cmd/server_test.go | 55 ++++++++++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/backend/app/cmd/server.go b/backend/app/cmd/server.go index 43c72da0..034271c3 100644 --- a/backend/app/cmd/server.go +++ b/backend/app/cmd/server.go @@ -244,6 +244,7 @@ type serverApp struct { avatarStore avatar.Store notifyService *notify.Service imageService *image.Service + authenticator *auth.Service terminated chan struct{} } @@ -456,6 +457,7 @@ func (s *ServerCommand) newServerApp() (*serverApp, error) { avatarStore: avatarStore, notifyService: notifyService, imageService: imageService, + authenticator: authenticator, terminated: make(chan struct{}), }, nil } @@ -863,6 +865,21 @@ func (s *ServerCommand) makeAuthenticator(ds *service.DataStore, avas avatar.Sto if err != nil { log.Printf("[WARN] can't read email for %s, %v", c.User.ID, err) } + + // don't allow anonymous with admin's name + if strings.HasPrefix(c.User.ID, "anonymous_") { + admins, err := admns.Admins(c.Audience) + if err != nil { + log.Printf("[WARN] can't get admins for %s, %v", c.Audience, err) + } + for _, a := range admins { + if strings.EqualFold(c.User.Name, a) { + c.User.SetBoolAttr("blocked", true) + break + } + } + } + return c }), AdminPasswd: s.AdminPasswd, diff --git a/backend/app/cmd/server_test.go b/backend/app/cmd/server_test.go index b8611988..52577722 100644 --- a/backend/app/cmd/server_test.go +++ b/backend/app/cmd/server_test.go @@ -114,27 +114,74 @@ func TestServerApp_AnonMode(t *testing.T) { assert.Equal(t, "pong", string(body)) // try to login with good name - resp, err = http.Get(fmt.Sprintf("http://localhost:%d/auth/anonymous/login?user=blah123&aud=remark42", port)) + resp, err = http.Get(fmt.Sprintf("http://localhost:%d/auth/anonymous/login?user=blah123&aud=remark", port)) require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, http.StatusOK, resp.StatusCode) + // try to add a comment as good anonymous + client := http.Client{Timeout: 10 * time.Second} + req, err := http.NewRequest("POST", fmt.Sprintf("http://localhost:%d/api/v1/comment", port), + strings.NewReader(`{"text": "test 123", "locator":{"url": "https://radio-t.com/blah1", "site": "remark"}}`)) + require.NoError(t, err) + + tkn, claims := getAuthFromCookie(t, app, resp) + require.NotEmpty(t, tkn) + req.Header.Add("X-JWT", tkn) + resp, err = client.Do(req) + require.NoError(t, err) + defer resp.Body.Close() + assert.Equal(t, http.StatusCreated, resp.StatusCode) + // try to login with bad name - resp, err = http.Get(fmt.Sprintf("http://localhost:%d/auth/anonymous/login?user=**blah123&aud=remark42", port)) + resp, err = http.Get(fmt.Sprintf("http://localhost:%d/auth/anonymous/login?user=**blah123&aud=remark", port)) require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, http.StatusForbidden, resp.StatusCode) // try to login with short name - resp, err = http.Get(fmt.Sprintf("http://localhost:%d/auth/anonymous/login?user=bl%20%20&aud=remark42", port)) + resp, err = http.Get(fmt.Sprintf("http://localhost:%d/auth/anonymous/login?user=bl%20%20&aud=remark", port)) require.NoError(t, err) defer resp.Body.Close() assert.Equal(t, http.StatusForbidden, resp.StatusCode) + // try to login with admin name + resp, err = http.Get(fmt.Sprintf("http://localhost:%d/auth/anonymous/login?user=umputun&aud=remark", port)) + require.NoError(t, err) + defer resp.Body.Close() + assert.Equal(t, http.StatusOK, resp.StatusCode) + + // try to add a comment as anonymous with admin name + client = http.Client{Timeout: 10 * time.Second} + req, err = http.NewRequest("POST", fmt.Sprintf("http://localhost:%d/api/v1/comment", port), + strings.NewReader(`{"text": "test 123", "locator":{"url": "https://radio-t.com/blah1", "site": "remark"}}`)) + require.NoError(t, err) + + tkn, claims = getAuthFromCookie(t, app, resp) + require.NotEmpty(t, tkn) + assert.True(t, claims.User.BoolAttr("blocked"), "should be blocked") + req.Header.Add("X-JWT", tkn) + resp, err = client.Do(req) + require.NoError(t, err) + defer resp.Body.Close() + assert.Equal(t, http.StatusUnauthorized, resp.StatusCode) + cancel() app.Wait() } +func getAuthFromCookie(t *testing.T, app *serverApp, resp *http.Response) (token string, claims token.Claims) { + var err error + for _, c := range resp.Cookies() { + if c.Name == "JWT" { + token = c.Value + claims, err = app.restSrv.Authenticator.TokenService().Parse(c.Value) + require.NoError(t, err) + } + } + return token, claims +} + func TestServerApp_WithSSL(t *testing.T) { opts := ServerCommand{} sslPort := chooseRandomUnusedPort() @@ -561,6 +608,8 @@ func prepServerApp(t *testing.T, fn func(o ServerCommand) ServerCommand) (*serve cmd.SMTP.Password = "test_password" cmd.SMTP.TimeOut = time.Second cmd.UpdateLimit = 10 + cmd.Admin.Type = "shared" + cmd.Admin.Shared.Admins = []string{"umputun", "bobuk"} cmd = fn(cmd) os.Remove(cmd.Store.Bolt.Path + "/remark.db")