Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
D
dex
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
dex
Commits
aad328bb
Commit
aad328bb
authored
Aug 11, 2017
by
Eric Chiang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
*: add log events for login, LDAP queries, and SAML responses
parent
c45185f6
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
64 additions
and
1 deletion
+64
-1
ldap.go
connector/ldap/ldap.go
+21
-1
saml.go
connector/saml/saml.go
+5
-0
types.go
connector/saml/types.go
+27
-0
handlers.go
server/handlers.go
+11
-0
No files found.
connector/ldap/ldap.go
View file @
aad328bb
...
@@ -127,6 +127,19 @@ type Config struct {
...
@@ -127,6 +127,19 @@ type Config struct {
}
`json:"groupSearch"`
}
`json:"groupSearch"`
}
}
func
scopeString
(
i
int
)
string
{
switch
i
{
case
ldap
.
ScopeBaseObject
:
return
"base"
case
ldap
.
ScopeSingleLevel
:
return
"one"
case
ldap
.
ScopeWholeSubtree
:
return
"sub"
default
:
return
""
}
}
func
parseScope
(
s
string
)
(
int
,
bool
)
{
func
parseScope
(
s
string
)
(
int
,
bool
)
{
// NOTE(ericchiang): ScopeBaseObject doesn't really make sense for us because we
// NOTE(ericchiang): ScopeBaseObject doesn't really make sense for us because we
// never know the user's or group's DN.
// never know the user's or group's DN.
...
@@ -342,6 +355,9 @@ func (c *ldapConnector) userEntry(conn *ldap.Conn, username string) (user ldap.E
...
@@ -342,6 +355,9 @@ func (c *ldapConnector) userEntry(conn *ldap.Conn, username string) (user ldap.E
if
c
.
UserSearch
.
NameAttr
!=
""
{
if
c
.
UserSearch
.
NameAttr
!=
""
{
req
.
Attributes
=
append
(
req
.
Attributes
,
c
.
UserSearch
.
NameAttr
)
req
.
Attributes
=
append
(
req
.
Attributes
,
c
.
UserSearch
.
NameAttr
)
}
}
c
.
logger
.
Infof
(
"performing ldap search %s %s %s"
,
req
.
BaseDN
,
scopeString
(
req
.
Scope
),
req
.
Filter
)
resp
,
err
:=
conn
.
Search
(
req
)
resp
,
err
:=
conn
.
Search
(
req
)
if
err
!=
nil
{
if
err
!=
nil
{
return
ldap
.
Entry
{},
false
,
fmt
.
Errorf
(
"ldap: search with filter %q failed: %v"
,
req
.
Filter
,
err
)
return
ldap
.
Entry
{},
false
,
fmt
.
Errorf
(
"ldap: search with filter %q failed: %v"
,
req
.
Filter
,
err
)
...
@@ -352,7 +368,9 @@ func (c *ldapConnector) userEntry(conn *ldap.Conn, username string) (user ldap.E
...
@@ -352,7 +368,9 @@ func (c *ldapConnector) userEntry(conn *ldap.Conn, username string) (user ldap.E
c
.
logger
.
Errorf
(
"ldap: no results returned for filter: %q"
,
filter
)
c
.
logger
.
Errorf
(
"ldap: no results returned for filter: %q"
,
filter
)
return
ldap
.
Entry
{},
false
,
nil
return
ldap
.
Entry
{},
false
,
nil
case
1
:
case
1
:
return
*
resp
.
Entries
[
0
],
true
,
nil
user
=
*
resp
.
Entries
[
0
]
c
.
logger
.
Infof
(
"username %q mapped to entry %s"
,
username
,
user
.
DN
)
return
user
,
true
,
nil
default
:
default
:
return
ldap
.
Entry
{},
false
,
fmt
.
Errorf
(
"ldap: filter returned multiple (%d) results: %q"
,
n
,
filter
)
return
ldap
.
Entry
{},
false
,
fmt
.
Errorf
(
"ldap: filter returned multiple (%d) results: %q"
,
n
,
filter
)
}
}
...
@@ -493,6 +511,8 @@ func (c *ldapConnector) groups(ctx context.Context, user ldap.Entry) ([]string,
...
@@ -493,6 +511,8 @@ func (c *ldapConnector) groups(ctx context.Context, user ldap.Entry) ([]string,
gotGroups
:=
false
gotGroups
:=
false
if
err
:=
c
.
do
(
ctx
,
func
(
conn
*
ldap
.
Conn
)
error
{
if
err
:=
c
.
do
(
ctx
,
func
(
conn
*
ldap
.
Conn
)
error
{
c
.
logger
.
Infof
(
"performing ldap search %s %s %s"
,
req
.
BaseDN
,
scopeString
(
req
.
Scope
),
req
.
Filter
)
resp
,
err
:=
conn
.
Search
(
req
)
resp
,
err
:=
conn
.
Search
(
req
)
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"ldap: search failed: %v"
,
err
)
return
fmt
.
Errorf
(
"ldap: search failed: %v"
,
err
)
...
...
connector/saml/saml.go
View file @
aad328bb
...
@@ -366,6 +366,11 @@ func (p *provider) HandlePOST(s connector.Scopes, samlResponse, inResponseTo str
...
@@ -366,6 +366,11 @@ func (p *provider) HandlePOST(s connector.Scopes, samlResponse, inResponseTo str
return
ident
,
fmt
.
Errorf
(
"response did not contain a AttributeStatement"
)
return
ident
,
fmt
.
Errorf
(
"response did not contain a AttributeStatement"
)
}
}
// Log the actual attributes we got back from the server. This helps debug
// configuration errors on the server side, where the SAML server doesn't
// send us the correct attributes.
p
.
logger
.
Infof
(
"parsed and verified saml response attributes %s"
,
attributes
)
// Grab the email.
// Grab the email.
if
ident
.
Email
,
_
=
attributes
.
get
(
p
.
emailAttr
);
ident
.
Email
==
""
{
if
ident
.
Email
,
_
=
attributes
.
get
(
p
.
emailAttr
);
ident
.
Email
==
""
{
return
ident
,
fmt
.
Errorf
(
"no attribute with name %q: %s"
,
p
.
emailAttr
,
attributes
.
names
())
return
ident
,
fmt
.
Errorf
(
"no attribute with name %q: %s"
,
p
.
emailAttr
,
attributes
.
names
())
...
...
connector/saml/types.go
View file @
aad328bb
package
saml
package
saml
import
(
import
(
"bytes"
"encoding/xml"
"encoding/xml"
"fmt"
"fmt"
"time"
"time"
...
@@ -233,6 +234,18 @@ func (a *attributeStatement) names() []string {
...
@@ -233,6 +234,18 @@ func (a *attributeStatement) names() []string {
return
s
return
s
}
}
// String is a formatter for logging an attribute statement's sub statements.
func
(
a
*
attributeStatement
)
String
()
string
{
buff
:=
new
(
bytes
.
Buffer
)
for
i
,
attr
:=
range
a
.
Attributes
{
if
i
!=
0
{
buff
.
WriteString
(
", "
)
}
buff
.
WriteString
(
attr
.
String
())
}
return
buff
.
String
()
}
type
attribute
struct
{
type
attribute
struct
{
XMLName
xml
.
Name
`xml:"urn:oasis:names:tc:SAML:2.0:assertion Attribute"`
XMLName
xml
.
Name
`xml:"urn:oasis:names:tc:SAML:2.0:assertion Attribute"`
...
@@ -248,3 +261,17 @@ type attributeValue struct {
...
@@ -248,3 +261,17 @@ type attributeValue struct {
XMLName
xml
.
Name
`xml:"AttributeValue"`
XMLName
xml
.
Name
`xml:"AttributeValue"`
Value
string
`xml:",chardata"`
Value
string
`xml:",chardata"`
}
}
func
(
a
attribute
)
String
()
string
{
if
len
(
a
.
AttributeValues
)
==
1
{
// "email" = "jane.doe@coreos.com"
return
fmt
.
Sprintf
(
"%q = %q"
,
a
.
Name
,
a
.
AttributeValues
[
0
]
.
Value
)
}
values
:=
make
([]
string
,
len
(
a
.
AttributeValues
))
for
i
,
av
:=
range
a
.
AttributeValues
{
values
[
i
]
=
av
.
Value
}
// "groups" = ["engineering", "docs"]
return
fmt
.
Sprintf
(
"%q = %q"
,
a
.
Name
,
values
)
}
server/handlers.go
View file @
aad328bb
...
@@ -390,6 +390,8 @@ func (s *Server) handleConnectorCallback(w http.ResponseWriter, r *http.Request)
...
@@ -390,6 +390,8 @@ func (s *Server) handleConnectorCallback(w http.ResponseWriter, r *http.Request)
http
.
Redirect
(
w
,
r
,
redirectURL
,
http
.
StatusSeeOther
)
http
.
Redirect
(
w
,
r
,
redirectURL
,
http
.
StatusSeeOther
)
}
}
// finalizeLogin associates the user's identity with the current AuthRequest, then returns
// the approval page's path.
func
(
s
*
Server
)
finalizeLogin
(
identity
connector
.
Identity
,
authReq
storage
.
AuthRequest
,
conn
connector
.
Connector
)
(
string
,
error
)
{
func
(
s
*
Server
)
finalizeLogin
(
identity
connector
.
Identity
,
authReq
storage
.
AuthRequest
,
conn
connector
.
Connector
)
(
string
,
error
)
{
claims
:=
storage
.
Claims
{
claims
:=
storage
.
Claims
{
UserID
:
identity
.
UserID
,
UserID
:
identity
.
UserID
,
...
@@ -408,6 +410,15 @@ func (s *Server) finalizeLogin(identity connector.Identity, authReq storage.Auth
...
@@ -408,6 +410,15 @@ func (s *Server) finalizeLogin(identity connector.Identity, authReq storage.Auth
if
err
:=
s
.
storage
.
UpdateAuthRequest
(
authReq
.
ID
,
updater
);
err
!=
nil
{
if
err
:=
s
.
storage
.
UpdateAuthRequest
(
authReq
.
ID
,
updater
);
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"failed to update auth request: %v"
,
err
)
return
""
,
fmt
.
Errorf
(
"failed to update auth request: %v"
,
err
)
}
}
email
:=
claims
.
Email
if
!
claims
.
EmailVerified
{
email
=
email
+
" (unverified)"
}
s
.
logger
.
Infof
(
"login successful: connector %q, username=%q, email=%q, groups=%q"
,
authReq
.
ConnectorID
,
claims
.
Username
,
email
,
claims
.
Groups
)
return
path
.
Join
(
s
.
issuerURL
.
Path
,
"/approval"
)
+
"?req="
+
authReq
.
ID
,
nil
return
path
.
Join
(
s
.
issuerURL
.
Path
,
"/approval"
)
+
"?req="
+
authReq
.
ID
,
nil
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment