ldap: add initial stub upstream LDAP connection package
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
This commit is contained in:
parent
f6ded84f07
commit
4ab704b7de
1
go.mod
1
go.mod
@ -7,6 +7,7 @@ require (
|
|||||||
github.com/MakeNowJust/heredoc/v2 v2.0.1
|
github.com/MakeNowJust/heredoc/v2 v2.0.1
|
||||||
github.com/coreos/go-oidc/v3 v3.0.0
|
github.com/coreos/go-oidc/v3 v3.0.0
|
||||||
github.com/davecgh/go-spew v1.1.1
|
github.com/davecgh/go-spew v1.1.1
|
||||||
|
github.com/go-ldap/ldap/v3 v3.3.0
|
||||||
github.com/go-logr/logr v0.4.0
|
github.com/go-logr/logr v0.4.0
|
||||||
github.com/go-logr/stdr v0.4.0
|
github.com/go-logr/stdr v0.4.0
|
||||||
github.com/go-openapi/spec v0.20.3
|
github.com/go-openapi/spec v0.20.3
|
||||||
|
7
go.sum
7
go.sum
@ -49,6 +49,8 @@ github.com/Azure/go-autorest/logger v0.2.0 h1:e4RVHVZKC5p6UANLJHkM4OfR1UKZPj8Wt8
|
|||||||
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||||
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
|
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
|
||||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||||
|
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28=
|
||||||
|
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
@ -201,12 +203,16 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo
|
|||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
|
github.com/go-asn1-ber/asn1-ber v1.5.1 h1:pDbRAunXzIUXfx4CB2QJFv5IuPiuoW+sWvr/Us009o8=
|
||||||
|
github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||||
github.com/go-bindata/go-bindata v3.1.1+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo=
|
github.com/go-bindata/go-bindata v3.1.1+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo=
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
|
github.com/go-ldap/ldap/v3 v3.3.0 h1:lwx+SJpgOHd8tG6SumBQZXCmNX51zM8B1cfxJ5gv4tQ=
|
||||||
|
github.com/go-ldap/ldap/v3 v3.3.0/go.mod h1:iYS1MdmrmceOJ1QOTnRXrIs7i3kloqtmGQjRvjKpyMg=
|
||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||||
@ -1094,6 +1100,7 @@ golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPh
|
|||||||
golang.org/x/crypto v0.0.0-20200320181102-891825fb96df/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200320181102-891825fb96df/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
|
6
internal/mocks/mockldapconn/generate.go
Normal file
6
internal/mocks/mockldapconn/generate.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package mockldapconn
|
||||||
|
|
||||||
|
//go:generate go run -v github.com/golang/mock/mockgen -destination=mockldapconn.go -package=mockldapconn -copyright_file=../../../hack/header.txt go.pinniped.dev/internal/upstreamldap Conn
|
80
internal/mocks/mockldapconn/mockldapconn.go
Normal file
80
internal/mocks/mockldapconn/mockldapconn.go
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
// Code generated by MockGen. DO NOT EDIT.
|
||||||
|
// Source: go.pinniped.dev/internal/upstreamldap (interfaces: Conn)
|
||||||
|
|
||||||
|
// Package mockldapconn is a generated GoMock package.
|
||||||
|
package mockldapconn
|
||||||
|
|
||||||
|
import (
|
||||||
|
reflect "reflect"
|
||||||
|
|
||||||
|
ldap "github.com/go-ldap/ldap/v3"
|
||||||
|
gomock "github.com/golang/mock/gomock"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MockConn is a mock of Conn interface.
|
||||||
|
type MockConn struct {
|
||||||
|
ctrl *gomock.Controller
|
||||||
|
recorder *MockConnMockRecorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// MockConnMockRecorder is the mock recorder for MockConn.
|
||||||
|
type MockConnMockRecorder struct {
|
||||||
|
mock *MockConn
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMockConn creates a new mock instance.
|
||||||
|
func NewMockConn(ctrl *gomock.Controller) *MockConn {
|
||||||
|
mock := &MockConn{ctrl: ctrl}
|
||||||
|
mock.recorder = &MockConnMockRecorder{mock}
|
||||||
|
return mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||||
|
func (m *MockConn) EXPECT() *MockConnMockRecorder {
|
||||||
|
return m.recorder
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind mocks base method.
|
||||||
|
func (m *MockConn) Bind(arg0, arg1 string) error {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "Bind", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].(error)
|
||||||
|
return ret0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind indicates an expected call of Bind.
|
||||||
|
func (mr *MockConnMockRecorder) Bind(arg0, arg1 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Bind", reflect.TypeOf((*MockConn)(nil).Bind), arg0, arg1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close mocks base method.
|
||||||
|
func (m *MockConn) Close() {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
m.ctrl.Call(m, "Close")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close indicates an expected call of Close.
|
||||||
|
func (mr *MockConnMockRecorder) Close() *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockConn)(nil).Close))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search mocks base method.
|
||||||
|
func (m *MockConn) Search(arg0 *ldap.SearchRequest) (*ldap.SearchResult, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "Search", arg0)
|
||||||
|
ret0, _ := ret[0].(*ldap.SearchResult)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search indicates an expected call of Search.
|
||||||
|
func (mr *MockConnMockRecorder) Search(arg0 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Search", reflect.TypeOf((*MockConn)(nil).Search), arg0)
|
||||||
|
}
|
70
internal/upstreamldap/upstreamldap.go
Normal file
70
internal/upstreamldap/upstreamldap.go
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
// Package upstreamldap implements an abstraction of upstream LDAP IDP interactions.
|
||||||
|
package upstreamldap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
ldap "github.com/go-ldap/ldap/v3"
|
||||||
|
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Conn abstracts the upstream LDAP communication protocol (mostly for testing).
|
||||||
|
type Conn interface {
|
||||||
|
// Bind abstracts ldap.Conn.Bind().
|
||||||
|
Bind(username, password string) error
|
||||||
|
// Search abstracts ldap.Conn.Search().
|
||||||
|
Search(searchRequest *ldap.SearchRequest) (*ldap.SearchResult, error)
|
||||||
|
// Close abstracts ldap.Conn.Close().
|
||||||
|
Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserSearch contains information about how to search for users in the upstream LDAP IDP.
|
||||||
|
type UserSearch struct {
|
||||||
|
// Base is the base DN to use for the user search in the upstream LDAP IDP.
|
||||||
|
Base string
|
||||||
|
// Filter is the filter to use for the user search in the upstream LDAP IDP.
|
||||||
|
Filter string
|
||||||
|
// UsernameAttribute is the attribute in the LDAP entry from which the username should be
|
||||||
|
// retrieved.
|
||||||
|
UsernameAttribute string
|
||||||
|
// UIDAttribute is the attribute in the LDAP entry from which the user's unique ID should be
|
||||||
|
// retrieved.
|
||||||
|
UIDAttribute string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provider contains can interact with an upstream LDAP IDP.
|
||||||
|
type Provider struct {
|
||||||
|
// Name is the unique name of this upstream LDAP IDP.
|
||||||
|
Name string
|
||||||
|
// URL is the URL of this upstream LDAP IDP.
|
||||||
|
URL string
|
||||||
|
|
||||||
|
// Dial is a func that, given a URL, will return an LDAPConn to use for communicating with an
|
||||||
|
// upstream LDAP IDP.
|
||||||
|
Dial func(ctx context.Context, url string) (Conn, error)
|
||||||
|
|
||||||
|
// BindUsername is the username to use when performing a bind with the upstream LDAP IDP.
|
||||||
|
BindUsername string
|
||||||
|
// BindPassword is the password to use when performing a bind with the upstream LDAP IDP.
|
||||||
|
BindPassword string
|
||||||
|
|
||||||
|
// UserSearch contains information about how to search for users in the upstream LDAP IDP.
|
||||||
|
UserSearch *UserSearch
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Provider) GetName() string {
|
||||||
|
return p.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Provider) GetURL() string {
|
||||||
|
return p.URL
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Provider) AuthenticateUser(ctx context.Context, username, password string) (*authenticator.Response, bool, error) {
|
||||||
|
// TODO: test context timeout?
|
||||||
|
// TODO: test dial context timeout?
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
104
internal/upstreamldap/upstreamldap_test.go
Normal file
104
internal/upstreamldap/upstreamldap_test.go
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package upstreamldap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
ldap "github.com/go-ldap/ldap/v3"
|
||||||
|
"github.com/golang/mock/gomock"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||||
|
"k8s.io/apiserver/pkg/authentication/user"
|
||||||
|
|
||||||
|
"go.pinniped.dev/internal/mocks/mockldapconn"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
upstreamUsername = "some-upstream-username"
|
||||||
|
upstreamPassword = "some-upstream-password"
|
||||||
|
upstreamGroups = []string{"some-upstream-group-0", "some-upstream-group-1"}
|
||||||
|
upstreamUID = "some-upstream-uid"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAuthenticateUser(t *testing.T) {
|
||||||
|
// Please the linter...
|
||||||
|
_ = upstreamGroups
|
||||||
|
_ = upstreamUID
|
||||||
|
t.Skip("TODO: make me pass!")
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
provider *Provider
|
||||||
|
wantError string
|
||||||
|
wantUnauthenticated bool
|
||||||
|
wantAuthResponse *authenticator.Response
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "happy path",
|
||||||
|
provider: &Provider{
|
||||||
|
URL: "ldaps://some-ldap-url:1234",
|
||||||
|
BindUsername: upstreamUsername,
|
||||||
|
BindPassword: upstreamPassword,
|
||||||
|
UserSearch: &UserSearch{
|
||||||
|
Base: "some-upstream-base-dn",
|
||||||
|
Filter: "some-filter",
|
||||||
|
UsernameAttribute: "some-upstream-username-attribute",
|
||||||
|
UIDAttribute: "some-upstream-uid-attribute",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantAuthResponse: &authenticator.Response{
|
||||||
|
User: &user.DefaultInfo{
|
||||||
|
Name: upstreamUsername,
|
||||||
|
Groups: upstreamGroups,
|
||||||
|
UID: upstreamUID,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
test := test
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
ctrl := gomock.NewController(t)
|
||||||
|
t.Cleanup(ctrl.Finish)
|
||||||
|
conn := mockldapconn.NewMockConn(ctrl)
|
||||||
|
conn.EXPECT().Bind(test.provider.BindUsername, test.provider.BindPassword).Times(1)
|
||||||
|
conn.EXPECT().Search(&ldap.SearchRequest{
|
||||||
|
BaseDN: test.provider.UserSearch.Base,
|
||||||
|
Scope: 99, // TODO: what should this be?
|
||||||
|
DerefAliases: 99, // TODO: what should this be?
|
||||||
|
SizeLimit: 99,
|
||||||
|
TimeLimit: 99, // TODO: what should this be?
|
||||||
|
TypesOnly: true, // TODO: what should this be?
|
||||||
|
Filter: test.provider.UserSearch.Filter,
|
||||||
|
Attributes: []string{}, // TODO: what should this be?
|
||||||
|
Controls: []ldap.Control{}, // TODO: what should this be?
|
||||||
|
}).Return(&ldap.SearchResult{
|
||||||
|
Entries: []*ldap.Entry{
|
||||||
|
{
|
||||||
|
DN: "", // TODO: what should this be?
|
||||||
|
Attributes: []*ldap.EntryAttribute{}, // TODO: what should this be?
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Referrals: []string{}, // TODO: what should this be?
|
||||||
|
Controls: []ldap.Control{}, // TODO: what should this be?
|
||||||
|
}, nil).Times(1)
|
||||||
|
conn.EXPECT().Close().Times(1)
|
||||||
|
|
||||||
|
test.provider.Dial = func(ctx context.Context, url string) (Conn, error) {
|
||||||
|
require.Equal(t, test.provider.URL, url)
|
||||||
|
return conn, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
authResponse, authenticated, err := test.provider.AuthenticateUser(context.Background(), upstreamUsername, upstreamPassword)
|
||||||
|
if test.wantError != "" {
|
||||||
|
require.EqualError(t, err, test.wantError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
require.Equal(t, !test.wantUnauthenticated, authenticated)
|
||||||
|
require.Equal(t, test.wantAuthResponse, authResponse)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user