API: send Login actions (#27249)

* API: first version to send events about login actions

* API: improve login actions events

* Login: update auth test with new behavior

* Login: update auth test for auth module

* Login OAuth: improve functions structure

* API: make struct public to use for saml

* API: add send login log tests for grafana and ldap login

* API: remove log from tests

* Login API: fix test linting

* Update pkg/api/login_oauth.go

Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com>

* Login API: refactor using defer

Co-authored-by: Emil Tullstedt <emil.tullstedt@grafana.com>
This commit is contained in:
Agnès Toulet
2020-09-04 14:54:59 +02:00
committed by GitHub
parent a54df0c3cd
commit a9daaadd50
7 changed files with 295 additions and 37 deletions

View File

@ -1,6 +1,7 @@
package api
import (
"context"
"encoding/hex"
"errors"
"fmt"
@ -21,6 +22,7 @@ import (
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func mockSetIndexViewData() {
@ -553,3 +555,110 @@ func setupAuthProxyLoginTest(enableLoginToken bool) *scenarioContext {
return sc
}
type loginLogTestReceiver struct {
cmd *models.SendLoginLogCommand
}
func (r *loginLogTestReceiver) SaveLoginLog(ctx context.Context, cmd *models.SendLoginLogCommand) error {
r.cmd = cmd
return nil
}
func TestLoginPostSendLoginLog(t *testing.T) {
sc := setupScenarioContext("/login")
hs := &HTTPServer{
log: log.New("test"),
Cfg: setting.NewCfg(),
License: &licensing.OSSLicensingService{},
AuthTokenService: auth.NewFakeUserAuthTokenService(),
}
sc.defaultHandler = Wrap(func(w http.ResponseWriter, c *models.ReqContext) Response {
cmd := dtos.LoginCommand{
User: "admin",
Password: "admin",
}
return hs.LoginPost(c, cmd)
})
testReceiver := loginLogTestReceiver{}
bus.AddHandlerCtx("login-log-receiver", testReceiver.SaveLoginLog)
type sendLoginLogCase struct {
desc string
authUser *models.User
authModule string
authErr error
cmd models.SendLoginLogCommand
}
testUser := &models.User{
Id: 42,
Email: "",
}
testCases := []sendLoginLogCase{
{
desc: "invalid credentials",
authErr: login.ErrInvalidCredentials,
cmd: models.SendLoginLogCommand{
LogAction: "login",
HTTPStatus: 401,
Error: login.ErrInvalidCredentials,
},
},
{
desc: "user disabled",
authErr: login.ErrUserDisabled,
cmd: models.SendLoginLogCommand{
LogAction: "login",
HTTPStatus: 401,
Error: login.ErrUserDisabled,
},
},
{
desc: "valid Grafana user",
authUser: testUser,
authModule: "grafana",
cmd: models.SendLoginLogCommand{
LogAction: "login-grafana",
User: testUser,
HTTPStatus: 200,
},
},
{
desc: "valid LDAP user",
authUser: testUser,
authModule: "ldap",
cmd: models.SendLoginLogCommand{
LogAction: "login-ldap",
User: testUser,
HTTPStatus: 200,
},
},
}
for _, c := range testCases {
t.Run(c.desc, func(t *testing.T) {
bus.AddHandler("grafana-auth", func(query *models.LoginUserQuery) error {
query.User = c.authUser
query.AuthModule = c.authModule
return c.authErr
})
sc.m.Post(sc.url, sc.defaultHandler)
sc.fakeReqNoAssertions("POST", sc.url).exec()
cmd := testReceiver.cmd
assert.Equal(t, c.cmd.LogAction, cmd.LogAction)
assert.Equal(t, c.cmd.HTTPStatus, cmd.HTTPStatus)
assert.Equal(t, c.cmd.Error, cmd.Error)
if c.cmd.User != nil {
require.NotEmpty(t, cmd.User)
assert.Equal(t, c.cmd.User.Id, cmd.User.Id)
}
})
}
}