2023-01-09 09:40:29 -06:00
|
|
|
package clients
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2023-01-17 03:07:46 -06:00
|
|
|
"net/http"
|
2023-01-09 09:40:29 -06:00
|
|
|
"testing"
|
|
|
|
|
2023-01-27 12:36:54 -06:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
2024-07-25 04:52:14 -05:00
|
|
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
2023-01-09 09:40:29 -06:00
|
|
|
"github.com/grafana/grafana/pkg/services/authn"
|
2023-01-27 12:36:54 -06:00
|
|
|
"github.com/grafana/grafana/pkg/services/login"
|
2023-01-09 09:40:29 -06:00
|
|
|
"github.com/grafana/grafana/pkg/services/org"
|
|
|
|
"github.com/grafana/grafana/pkg/services/user"
|
|
|
|
"github.com/grafana/grafana/pkg/services/user/usertest"
|
2023-01-17 03:07:46 -06:00
|
|
|
"github.com/grafana/grafana/pkg/setting"
|
2023-01-09 09:40:29 -06:00
|
|
|
"github.com/grafana/grafana/pkg/util"
|
|
|
|
)
|
|
|
|
|
2023-01-17 03:07:46 -06:00
|
|
|
func TestGrafana_AuthenticateProxy(t *testing.T) {
|
|
|
|
type testCase struct {
|
|
|
|
desc string
|
|
|
|
req *authn.Request
|
|
|
|
username string
|
|
|
|
proxyProperty string
|
|
|
|
additional map[string]string
|
|
|
|
expectedErr error
|
|
|
|
expectedIdentity *authn.Identity
|
|
|
|
}
|
|
|
|
|
|
|
|
tests := []testCase{
|
|
|
|
{
|
|
|
|
desc: "expect valid identity",
|
|
|
|
username: "test",
|
|
|
|
req: &authn.Request{HTTPRequest: &http.Request{}},
|
|
|
|
proxyProperty: "username",
|
|
|
|
additional: map[string]string{
|
|
|
|
proxyFieldName: "name",
|
|
|
|
proxyFieldRole: "Viewer",
|
|
|
|
proxyFieldGroups: "grp1,grp2",
|
|
|
|
proxyFieldEmail: "email@email.com",
|
|
|
|
},
|
|
|
|
expectedIdentity: &authn.Identity{
|
2023-07-12 05:31:36 -05:00
|
|
|
OrgRoles: map[int64]org.RoleType{1: org.RoleViewer},
|
|
|
|
Login: "test",
|
|
|
|
Name: "name",
|
|
|
|
Email: "email@email.com",
|
|
|
|
AuthenticatedBy: login.AuthProxyAuthModule,
|
|
|
|
AuthID: "test",
|
|
|
|
Groups: []string{"grp1", "grp2"},
|
2023-01-17 03:07:46 -06:00
|
|
|
ClientParams: authn.ClientParams{
|
|
|
|
SyncUser: true,
|
2023-02-21 04:21:34 -06:00
|
|
|
SyncTeams: true,
|
2023-01-17 03:07:46 -06:00
|
|
|
AllowSignUp: true,
|
2023-02-03 07:14:38 -06:00
|
|
|
FetchSyncedUser: true,
|
2023-02-22 03:27:48 -06:00
|
|
|
SyncOrgRoles: true,
|
2023-01-27 12:36:54 -06:00
|
|
|
LookUpParams: login.UserLookupParams{
|
2023-01-17 03:07:46 -06:00
|
|
|
Email: strPtr("email@email.com"),
|
|
|
|
Login: strPtr("test"),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "should set email as both email and login when configured proxy auth header property is email",
|
|
|
|
username: "test@test.com",
|
|
|
|
req: &authn.Request{HTTPRequest: &http.Request{Header: map[string][]string{}}},
|
|
|
|
additional: map[string]string{},
|
|
|
|
expectedIdentity: &authn.Identity{
|
2023-07-12 05:31:36 -05:00
|
|
|
Login: "test@test.com",
|
|
|
|
Email: "test@test.com",
|
|
|
|
AuthenticatedBy: login.AuthProxyAuthModule,
|
|
|
|
AuthID: "test@test.com",
|
2023-01-17 03:07:46 -06:00
|
|
|
ClientParams: authn.ClientParams{
|
2023-02-22 03:27:48 -06:00
|
|
|
SyncUser: true,
|
|
|
|
SyncTeams: true,
|
|
|
|
AllowSignUp: true,
|
|
|
|
SyncOrgRoles: true,
|
2023-01-27 12:36:54 -06:00
|
|
|
LookUpParams: login.UserLookupParams{
|
2023-01-17 03:07:46 -06:00
|
|
|
Email: strPtr("test@test.com"),
|
|
|
|
Login: strPtr("test@test.com"),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
proxyProperty: "email",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "should return error on invalid auth proxy header property",
|
|
|
|
req: &authn.Request{HTTPRequest: &http.Request{Header: map[string][]string{}}},
|
|
|
|
proxyProperty: "other",
|
|
|
|
expectedErr: errInvalidProxyHeader,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.desc, func(t *testing.T) {
|
|
|
|
cfg := setting.NewCfg()
|
2024-03-01 04:31:06 -06:00
|
|
|
cfg.AuthProxy.AutoSignUp = true
|
|
|
|
cfg.AuthProxy.HeaderProperty = tt.proxyProperty
|
2023-01-17 03:07:46 -06:00
|
|
|
c := ProvideGrafana(cfg, usertest.NewUserServiceFake())
|
|
|
|
|
|
|
|
identity, err := c.AuthenticateProxy(context.Background(), tt.req, tt.username, tt.additional)
|
|
|
|
assert.ErrorIs(t, err, tt.expectedErr)
|
|
|
|
if tt.expectedIdentity != nil {
|
|
|
|
assert.Equal(t, tt.expectedIdentity.OrgID, identity.OrgID)
|
|
|
|
assert.Equal(t, tt.expectedIdentity.Login, identity.Login)
|
|
|
|
assert.Equal(t, tt.expectedIdentity.Name, identity.Name)
|
|
|
|
assert.Equal(t, tt.expectedIdentity.Email, identity.Email)
|
|
|
|
assert.Equal(t, tt.expectedIdentity.AuthID, identity.AuthID)
|
2023-07-12 05:31:36 -05:00
|
|
|
assert.Equal(t, tt.expectedIdentity.AuthenticatedBy, identity.AuthenticatedBy)
|
2023-01-17 03:07:46 -06:00
|
|
|
assert.Equal(t, tt.expectedIdentity.Groups, identity.Groups)
|
|
|
|
|
|
|
|
assert.Equal(t, tt.expectedIdentity.ClientParams.SyncUser, identity.ClientParams.SyncUser)
|
|
|
|
assert.Equal(t, tt.expectedIdentity.ClientParams.AllowSignUp, identity.ClientParams.AllowSignUp)
|
2023-02-21 04:21:34 -06:00
|
|
|
assert.Equal(t, tt.expectedIdentity.ClientParams.SyncTeams, identity.ClientParams.SyncTeams)
|
2023-09-27 04:16:53 -05:00
|
|
|
assert.Equal(t, tt.expectedIdentity.ClientParams.EnableUser, identity.ClientParams.EnableUser)
|
2023-01-17 03:07:46 -06:00
|
|
|
|
|
|
|
assert.EqualValues(t, tt.expectedIdentity.ClientParams.LookUpParams.Email, identity.ClientParams.LookUpParams.Email)
|
|
|
|
assert.EqualValues(t, tt.expectedIdentity.ClientParams.LookUpParams.Login, identity.ClientParams.LookUpParams.Login)
|
|
|
|
} else {
|
|
|
|
assert.Nil(t, tt.expectedIdentity)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-09 09:40:29 -06:00
|
|
|
func TestGrafana_AuthenticatePassword(t *testing.T) {
|
|
|
|
type testCase struct {
|
2024-04-24 02:57:34 -05:00
|
|
|
desc string
|
|
|
|
username string
|
|
|
|
password string
|
|
|
|
findUser bool
|
|
|
|
expectedErr error
|
|
|
|
expectedIdentity *authn.Identity
|
2023-01-09 09:40:29 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
tests := []testCase{
|
|
|
|
{
|
2024-04-24 02:57:34 -05:00
|
|
|
desc: "should successfully authenticate user with correct password",
|
|
|
|
username: "user",
|
|
|
|
password: "password",
|
|
|
|
findUser: true,
|
2023-03-08 06:35:54 -06:00
|
|
|
expectedIdentity: &authn.Identity{
|
2024-07-25 04:52:14 -05:00
|
|
|
ID: identity.MustParseTypedID("user:1"),
|
2023-07-12 05:31:36 -05:00
|
|
|
OrgID: 1,
|
|
|
|
AuthenticatedBy: login.PasswordAuthModule,
|
2024-04-24 02:57:34 -05:00
|
|
|
ClientParams: authn.ClientParams{FetchSyncedUser: true, SyncPermissions: true},
|
2023-07-12 05:31:36 -05:00
|
|
|
},
|
2023-01-09 09:40:29 -06:00
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "should fail for incorrect password",
|
|
|
|
username: "user",
|
|
|
|
password: "wrong",
|
|
|
|
findUser: true,
|
|
|
|
expectedErr: errInvalidPassword,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "should fail if user is not found",
|
|
|
|
username: "user",
|
|
|
|
password: "password",
|
|
|
|
expectedErr: errIdentityNotFound,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.desc, func(t *testing.T) {
|
|
|
|
hashed, _ := util.EncodePassword("password", "salt")
|
|
|
|
userService := &usertest.FakeUserService{
|
2024-04-24 02:57:34 -05:00
|
|
|
ExpectedUser: &user.User{ID: 1, Password: user.Password(hashed), Salt: "salt"},
|
2023-01-09 09:40:29 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
if !tt.findUser {
|
|
|
|
userService.ExpectedUser = nil
|
|
|
|
userService.ExpectedError = user.ErrUserNotFound
|
|
|
|
}
|
|
|
|
|
2023-01-17 03:07:46 -06:00
|
|
|
c := ProvideGrafana(setting.NewCfg(), userService)
|
2023-01-12 08:02:04 -06:00
|
|
|
identity, err := c.AuthenticatePassword(context.Background(), &authn.Request{OrgID: 1}, tt.username, tt.password)
|
2023-01-09 09:40:29 -06:00
|
|
|
assert.ErrorIs(t, err, tt.expectedErr)
|
|
|
|
assert.EqualValues(t, tt.expectedIdentity, identity)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|