Files
portainer/api/useractivity/auth_log_test.go
2021-04-07 16:54:07 +12:00

405 lines
10 KiB
Go

package useractivity
import (
"fmt"
"os"
"testing"
"time"
"github.com/stretchr/testify/assert"
portainer "github.com/portainer/portainer/api"
)
func BenchmarkAuthLog(b *testing.B) {
defer timeTrack(time.Now(), "AuthActivityLog")
// https://github.com/golang/go/issues/41062
// bug in go 1.15 causes b.TempDir() to break in benchmarks
// TODO remove in go 1.16
err := os.RemoveAll("./useractivity.db")
if err != nil {
b.Fatalf("Failed removing db: %s", err)
}
store, err := setup("")
if err != nil {
b.Fatalf("Failed setup: %s", err)
}
defer store.Close()
for i := 0; i < 100; i++ {
_, err = store.LogAuthActivity("username", "endpoint", portainer.AuthenticationInternal, testType)
if err != nil {
b.Fatalf("Failed adding activity log: %s", err)
}
}
count, err := store.db.Count(&portainer.AuthActivityLog{})
if err != nil {
fmt.Println(err)
}
fmt.Printf("Number of logs: %d\n", count)
}
const (
testType = portainer.AuthenticationActivityType(0)
)
func setup(path string) (*Store, error) {
store, err := NewUserActivityStore(path)
if err != nil {
return nil, fmt.Errorf("Failed creating new store: %w", err)
}
return store, nil
}
func TestAddActivity(t *testing.T) {
store, err := setup(t.TempDir())
if err != nil {
t.Fatalf("Failed setup: %s", err)
}
defer store.Close()
_, err = store.LogAuthActivity("username", "endpoint", portainer.AuthenticationInternal, testType)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
count, err := store.db.Count(&portainer.AuthActivityLog{})
if err != nil {
t.Fatalf("Failed counting activities: %s", err)
}
assert.Equal(t, 1, count, "Store should have one element")
}
func TestGetLogs(t *testing.T) {
store, err := setup(t.TempDir())
if err != nil {
t.Fatalf("Failed setup: %s", err)
}
defer store.Close()
log1, err := store.LogAuthActivity("username1", "endpoint1", portainer.AuthenticationInternal, testType)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
log2, err := store.LogAuthActivity("username2", "endpoint2", portainer.AuthenticationInternal, testType)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
log3, err := store.LogAuthActivity("username3", "endpoint3", portainer.AuthenticationInternal, testType)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
logs, _, err := store.GetAuthLogs(portainer.AuthLogsQuery{})
if err != nil {
t.Fatalf("failed fetching logs: %s", err)
}
assert.Equal(t, []*portainer.AuthActivityLog{log1, log2, log3}, logs)
}
func TestGetLogsByTimestamp(t *testing.T) {
store, err := setup(t.TempDir())
if err != nil {
t.Fatalf("Failed setup: %s", err)
}
defer store.Close()
log1, err := store.LogAuthActivity("username1", "endpoint1", portainer.AuthenticationInternal, testType)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
time.Sleep(time.Second * 1)
log2, err := store.LogAuthActivity("username2", "endpoint2", portainer.AuthenticationInternal, testType)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
time.Sleep(time.Second * 1)
log3, err := store.LogAuthActivity("username3", "endpoint3", portainer.AuthenticationInternal, testType)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
logs, _, err := store.GetAuthLogs(portainer.AuthLogsQuery{
BeforeTimestamp: log3.Timestamp - 1,
AfterTimestamp: log1.Timestamp + 1,
})
if err != nil {
t.Fatalf("failed fetching logs: %s", err)
}
assert.Equal(t, log2, logs[0], "logs are not equal")
}
func TestGetLogsByKeyword(t *testing.T) {
store, err := setup(t.TempDir())
if err != nil {
t.Fatalf("Failed setup: %s", err)
}
defer store.Close()
log1, err := store.LogAuthActivity("username1", "endpoint1", portainer.AuthenticationInternal, testType)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
log2, err := store.LogAuthActivity("username2", "endpoint2", portainer.AuthenticationInternal, testType)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
log3, err := store.LogAuthActivity("username3", "endpoint3", portainer.AuthenticationInternal, testType)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
// like
shouldHaveAllLogs, _, err := store.GetAuthLogs(portainer.AuthLogsQuery{
Keyword: "username",
})
if err != nil {
t.Fatalf("failed fetching logs: %s", err)
}
assert.Equal(t, []*portainer.AuthActivityLog{log1, log2, log3}, shouldHaveAllLogs)
// username
shouldHaveOnlyLog1, _, err := store.GetAuthLogs(portainer.AuthLogsQuery{
Keyword: "username1",
})
if err != nil {
t.Fatalf("failed fetching logs: %s", err)
}
assert.Equal(t, log1, shouldHaveOnlyLog1[0])
// origin
shouldHaveOnlyLog3, _, err := store.GetAuthLogs(portainer.AuthLogsQuery{
Keyword: "endpoint3",
})
if err != nil {
t.Fatalf("failed fetching logs: %s", err)
}
assert.Equal(t, log3, shouldHaveOnlyLog3[0])
}
func TestGetLogsByContext(t *testing.T) {
store, err := setup(t.TempDir())
if err != nil {
t.Fatalf("Failed setup: %s", err)
}
defer store.Close()
log1, err := store.LogAuthActivity("username1", "endpoint1", portainer.AuthenticationInternal, testType)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
log2, err := store.LogAuthActivity("username2", "endpoint2", portainer.AuthenticationLDAP, testType)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
log3, err := store.LogAuthActivity("username3", "endpoint3", portainer.AuthenticationOAuth, testType)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
// one type
shouldHaveLog2, _, err := store.GetAuthLogs(portainer.AuthLogsQuery{
ContextTypes: []portainer.AuthenticationMethod{
portainer.AuthenticationLDAP,
},
})
if err != nil {
t.Fatalf("failed fetching logs: %s", err)
}
assert.Equal(t, []*portainer.AuthActivityLog{log2}, shouldHaveLog2)
// two types
shouldHaveLog1And3, _, err := store.GetAuthLogs(portainer.AuthLogsQuery{
ContextTypes: []portainer.AuthenticationMethod{
portainer.AuthenticationInternal,
portainer.AuthenticationOAuth,
},
})
if err != nil {
t.Fatalf("failed fetching logs: %s", err)
}
assert.Equal(t, []*portainer.AuthActivityLog{log1, log3}, shouldHaveLog1And3)
}
func TestGetLogsByType(t *testing.T) {
store, err := setup(t.TempDir())
if err != nil {
t.Fatalf("Failed setup: %s", err)
}
defer store.Close()
log1, err := store.LogAuthActivity("username1", "endpoint1", portainer.AuthenticationInternal, portainer.AuthenticationActivityFailure)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
log2, err := store.LogAuthActivity("username2", "endpoint2", portainer.AuthenticationLDAP, portainer.AuthenticationActivityLogOut)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
log3, err := store.LogAuthActivity("username3", "endpoint3", portainer.AuthenticationOAuth, portainer.AuthenticationActivitySuccess)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
// one type
shouldHaveLog2, _, err := store.GetAuthLogs(portainer.AuthLogsQuery{
ActivityTypes: []portainer.AuthenticationActivityType{
portainer.AuthenticationActivityLogOut,
},
})
if err != nil {
t.Fatalf("failed fetching logs: %s", err)
}
assert.Equal(t, []*portainer.AuthActivityLog{log2}, shouldHaveLog2)
// two types
shouldHaveLog1And3, _, err := store.GetAuthLogs(portainer.AuthLogsQuery{
ActivityTypes: []portainer.AuthenticationActivityType{
portainer.AuthenticationActivityFailure,
portainer.AuthenticationActivitySuccess,
},
})
if err != nil {
t.Fatalf("failed fetching logs: %s", err)
}
assert.Equal(t, []*portainer.AuthActivityLog{log1, log3}, shouldHaveLog1And3)
}
func TestSortOrderAndPaginate(t *testing.T) {
store, err := setup(t.TempDir())
if err != nil {
t.Fatalf("Failed setup: %s", err)
}
defer store.Close()
log1, err := store.LogAuthActivity("username1", "endpoint1", portainer.AuthenticationInternal, testType)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
log2, err := store.LogAuthActivity("username2", "endpoint2", portainer.AuthenticationInternal, testType)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
log3, err := store.LogAuthActivity("username3", "endpoint3", portainer.AuthenticationInternal, testType)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
log4, err := store.LogAuthActivity("username4", "endpoint4", portainer.AuthenticationInternal, testType)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
shouldBeLog4AndLog3, _, err := store.GetAuthLogs(portainer.AuthLogsQuery{
SortDesc: true,
SortBy: "Username",
Offset: 0,
Limit: 2,
})
if err != nil {
t.Fatalf("failed fetching logs: %s", err)
}
assert.Equal(t, []*portainer.AuthActivityLog{log4, log3}, shouldBeLog4AndLog3)
shouldBeLog2AndLog1, _, err := store.GetAuthLogs(portainer.AuthLogsQuery{
SortDesc: true,
SortBy: "Username",
Offset: 2,
Limit: 2,
})
if err != nil {
t.Fatalf("failed fetching logs: %s", err)
}
assert.Equal(t, []*portainer.AuthActivityLog{log2, log1}, shouldBeLog2AndLog1)
}
func TestGetLogsDesc(t *testing.T) {
store, err := setup(t.TempDir())
if err != nil {
t.Fatalf("Failed setup: %s", err)
}
defer store.Close()
log1, err := store.LogAuthActivity("username1", "endpoint1", portainer.AuthenticationInternal, testType)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
log2, err := store.LogAuthActivity("username2", "endpoint2", portainer.AuthenticationInternal, testType)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
log3, err := store.LogAuthActivity("username3", "endpoint3", portainer.AuthenticationInternal, testType)
if err != nil {
t.Fatalf("Failed adding activity log: %s", err)
}
logs, _, err := store.GetAuthLogs(portainer.AuthLogsQuery{
SortDesc: true,
})
if err != nil {
t.Fatalf("failed fetching logs: %s", err)
}
assert.Equal(t, []*portainer.AuthActivityLog{log3, log2, log1}, logs)
}
func timeTrack(start time.Time, name string) {
elapsed := time.Since(start)
fmt.Printf("%s took %s\n", name, elapsed)
}