Skip to content

Commit

Permalink
Various fixes (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
tamalsaha committed Feb 17, 2018
1 parent bdbb0e2 commit 0b4bc31
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 37 deletions.
4 changes: 2 additions & 2 deletions cmds/installer.go
Expand Up @@ -30,8 +30,8 @@ type options struct {
addr string
enableRBAC bool
tokenAuthFile string
Azure lib.AzureOpts
Ldap lib.LdapOpts
Azure lib.AzureOptions
Ldap lib.LDAPOptions
}

func NewCmdInstaller() *cobra.Command {
Expand Down
4 changes: 2 additions & 2 deletions lib/azure.go
Expand Up @@ -37,13 +37,13 @@ var (
// claims represents a map of claims provided with a JWT
type claims map[string]interface{}

type AzureOpts struct {
type AzureOptions struct {
ClientID string
ClientSecret string
TenantID string
}

func (s *AzureOpts) AddFlags(fs *pflag.FlagSet) {
func (s *AzureOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.ClientID, "azure.client-id", s.ClientID, "MS Graph application client ID to use")
fs.StringVar(&s.ClientSecret, "azure.client-secret", s.ClientSecret, "MS Graph application client secret to use")
fs.StringVar(&s.TenantID, "azure.tenant-id", s.TenantID, "MS Graph application tenant id to use")
Expand Down
8 changes: 7 additions & 1 deletion lib/azure_test.go
Expand Up @@ -31,7 +31,13 @@ func TestGraph(t *testing.T) {

func TestCheckAzure(t *testing.T) {
cred := tGetCred()
resp, status := checkAzure(cred.ClientID, cred.ClientSecret, cred.TenantID, id_token)
opts := AzureOptions{
ClientID: cred.ClientID,
ClientSecret: cred.ClientSecret,
TenantID: cred.TenantID,
}
s := Server{Azure: opts}
resp, status := s.checkAzure(id_token)
if status != 200 {
t.Error(resp.Status.Error)
}
Expand Down
2 changes: 1 addition & 1 deletion lib/handler.go
Expand Up @@ -58,7 +58,7 @@ func (s Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
Write(w, resp, code)
return
case "ldap":
resp, code := s.Ldap.checkLdap(data.Spec.Token)
resp, code := s.checkLDAP(data.Spec.Token)
Write(w, resp, code)
return
}
Expand Down
50 changes: 25 additions & 25 deletions lib/ldap.go
Expand Up @@ -21,7 +21,7 @@ const (
DefaultGroupNameAttribute string = "cn"
)

type LdapOpts struct {
type LDAPOptions struct {
ServerAddress string
ServerPort string
BindDN string // The connector uses this DN in credentials to search for users and groups. Not required if the LDAP server provides access for anonymous auth.
Expand All @@ -38,7 +38,7 @@ type LdapOpts struct {
StartTLS bool // for start tls connection
}

func (s *LdapOpts) AddFlags(fs *pflag.FlagSet) {
func (s *LDAPOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.ServerAddress, "ldap.server-address", s.ServerAddress, "Host or IP of the LDAP server")
fs.StringVar(&s.ServerPort, "ldap.server-port", "389", "LDAP server port")
fs.StringVar(&s.BindDN, "ldap.bind-dn", s.BindDN, "The connector uses this DN in credentials to search for users and groups. Not required if the LDAP server provides access for anonymous auth.")
Expand All @@ -55,46 +55,46 @@ func (s *LdapOpts) AddFlags(fs *pflag.FlagSet) {
fs.BoolVar(&s.StartTLS, "ldap.start-tls", false, "Start tls connection")
}

func (ld *LdapOpts) checkLdap(token string) (auth.TokenReview, int) {
func (s Server) checkLDAP(token string) (auth.TokenReview, int) {
username, password, ok := parseEncodedToken(token)
if !ok {
return Error("Invalid basic auth token"), http.StatusUnauthorized
}

data := auth.TokenReview{}
tlsConfig := &tls.Config{
ServerName: ld.ServerAddress,
InsecureSkipVerify: ld.SkipTLSVerification,
ServerName: s.LDAP.ServerAddress,
InsecureSkipVerify: s.LDAP.SkipTLSVerification,
}
var (
err error
conn *ldap.Conn
)
if ld.IsSecureLDAP {
conn, err = ldap.DialTLS("tcp", fmt.Sprintf("%s:%s", ld.ServerAddress, ld.ServerPort), tlsConfig)
if s.LDAP.IsSecureLDAP {
conn, err = ldap.DialTLS("tcp", fmt.Sprintf("%s:%s", s.LDAP.ServerAddress, s.LDAP.ServerPort), tlsConfig)
} else {
conn, err = ldap.Dial("tcp", fmt.Sprintf("%s:%s", ld.ServerAddress, ld.ServerPort))
conn, err = ldap.Dial("tcp", fmt.Sprintf("%s:%s", s.LDAP.ServerAddress, s.LDAP.ServerPort))
}
if err != nil {
return Error(fmt.Sprintf("Unable to create ldap connector for %s:%s", ld.ServerAddress, ld.ServerPort)), http.StatusInternalServerError
return Error(fmt.Sprintf("Unable to create ldap connector for %s:%s", s.LDAP.ServerAddress, s.LDAP.ServerPort)), http.StatusInternalServerError
}
defer conn.Close()

if ld.StartTLS {
if s.LDAP.StartTLS {
err = conn.StartTLS(tlsConfig)
if err != nil {
return Error("Unable to setup TLS connection"), http.StatusInternalServerError
}
}

if ld.BindDN != "" && ld.BindPassword != "" {
err = conn.Bind(ld.BindDN, ld.BindPassword)
if s.LDAP.BindDN != "" && s.LDAP.BindPassword != "" {
err = conn.Bind(s.LDAP.BindDN, s.LDAP.BindPassword)
if err != nil {
return Error(err.Error()), http.StatusUnauthorized
}
}

req := ld.newUserSearchRequest(username)
req := s.LDAP.newUserSearchRequest(username)
res, err := conn.Search(req)
if err != nil {
return Error(fmt.Sprintf("Error searching for user %s. Reason: %v", username, err)), http.StatusUnauthorized
Expand All @@ -115,24 +115,24 @@ func (ld *LdapOpts) checkLdap(token string) (auth.TokenReview, int) {
}

//rebind
if ld.BindDN != "" && ld.BindPassword != "" {
err = conn.Bind(ld.BindDN, ld.BindPassword)
if s.LDAP.BindDN != "" && s.LDAP.BindPassword != "" {
err = conn.Bind(s.LDAP.BindDN, s.LDAP.BindPassword)
if err != nil {
return Error(err.Error()), http.StatusUnauthorized
}
}

// user group list
req = ld.newGroupSearchRequest(userDN)
req = s.LDAP.newGroupSearchRequest(userDN)
res, err = conn.Search(req)
if err != nil {
return Error(fmt.Sprintf("Error searching for user's group for %s : %v", userDN, err)), http.StatusUnauthorized
}
groups := []string{}
var groups []string
//default use `cn` as group name
for _, en := range res.Entries {
for _, g := range en.Attributes {
if g.Name == ld.GroupNameAttribute {
if g.Name == s.LDAP.GroupNameAttribute {
if len(g.Values) == 0 {
return Error(fmt.Sprintf("cn not provided for %s", en.DN)), http.StatusUnauthorized
} else {
Expand All @@ -149,10 +149,10 @@ func (ld *LdapOpts) checkLdap(token string) (auth.TokenReview, int) {
}

// request to search user
func (ld *LdapOpts) newUserSearchRequest(username string) *ldap.SearchRequest {
userFilter := fmt.Sprintf("(&%s(%s=%s))", ld.UserSearchFilter, ld.UserAttribute, username)
func (s *LDAPOptions) newUserSearchRequest(username string) *ldap.SearchRequest {
userFilter := fmt.Sprintf("(&%s(%s=%s))", s.UserSearchFilter, s.UserAttribute, username)
return &ldap.SearchRequest{
BaseDN: ld.UserSearchDN,
BaseDN: s.UserSearchDN,
Scope: ldap.ScopeWholeSubtree,
DerefAliases: ldap.NeverDerefAliases,
SizeLimit: 2, //limit number of entries in result
Expand All @@ -163,17 +163,17 @@ func (ld *LdapOpts) newUserSearchRequest(username string) *ldap.SearchRequest {
}

// request to get user group list
func (ld *LdapOpts) newGroupSearchRequest(userDN string) *ldap.SearchRequest {
groupFilter := fmt.Sprintf("(&%s(%s=%s))", ld.GroupSearchFilter, ld.GroupMemberAttribute, userDN)
func (s *LDAPOptions) newGroupSearchRequest(userDN string) *ldap.SearchRequest {
groupFilter := fmt.Sprintf("(&%s(%s=%s))", s.GroupSearchFilter, s.GroupMemberAttribute, userDN)
return &ldap.SearchRequest{
BaseDN: ld.GroupSearchDN,
BaseDN: s.GroupSearchDN,
Scope: ldap.ScopeWholeSubtree,
DerefAliases: ldap.NeverDerefAliases,
SizeLimit: 0, //limit number of entries in result, 0 values means no limitations
TimeLimit: 10,
TypesOnly: false,
Filter: groupFilter, //filter default format : (&(objectClass=groupOfNames)(member=%s))
Attributes: []string{ld.GroupNameAttribute},
Attributes: []string{s.GroupNameAttribute},
}
}

Expand Down
8 changes: 5 additions & 3 deletions lib/ldap_test.go
Expand Up @@ -4,13 +4,14 @@ import (
"encoding/base64"
"fmt"
"net/http"
"strings"
"testing"
)

func TestCheckLdap(t *testing.T) {
// test 1
// disabled anonymous access
ld := LdapOpts{
opts := LDAPOptions{
ServerAddress: "localhost",
ServerPort: "10389",
BindDN: "uid=admin,ou=system",
Expand All @@ -25,7 +26,8 @@ func TestCheckLdap(t *testing.T) {
SkipTLSVerification: true,
StartTLS: true,
}
resp, status := ld.checkLdap(base64.StdEncoding.EncodeToString([]byte("nahid:12345")))
s := Server{LDAP: opts}
resp, status := s.checkLDAP(base64.StdEncoding.EncodeToString([]byte("nahid:12345")))
if status != http.StatusOK {
t.Error(resp.Status.Error)
}
Expand All @@ -42,7 +44,7 @@ func TestCheckLdap(t *testing.T) {
}
}
if !testFnd || !adminFnd {
t.Error("Expected: group list [\"test\",\"guard-test\"], got %v", resp.Status.User.Groups)
t.Errorf(`expected: group list ["test","guard-test"], got %s`, strings.Join(resp.Status.User.Groups, ","))
}
fmt.Print(resp.Status)
}
Expand Down
6 changes: 3 additions & 3 deletions lib/server.go
Expand Up @@ -27,8 +27,8 @@ type Server struct {
KeyFile string
OpsAddress string
TokenAuthFile string
Azure AzureOpts
Ldap LdapOpts
Azure AzureOptions
LDAP LDAPOptions
}

func (s *Server) AddFlags(fs *pflag.FlagSet) {
Expand All @@ -40,7 +40,7 @@ func (s *Server) AddFlags(fs *pflag.FlagSet) {

fs.StringVar(&s.TokenAuthFile, "token-auth-file", "", "To enable static token authentication")
s.Azure.AddFlags(fs)
s.Ldap.AddFlags(fs)
s.LDAP.AddFlags(fs)
}

func (s Server) UseTLS() bool {
Expand Down

0 comments on commit 0b4bc31

Please sign in to comment.