move logout url to conf

This commit is contained in:
Samir Patel 2021-12-20 14:30:19 -06:00
parent 405692e376
commit 6faa889bfb
8 changed files with 76 additions and 41 deletions

View file

@ -30,13 +30,13 @@ type Auth struct {
oAuthConfig *oauth2.Config
}
func NewAuth(logger logger.Logger, url string, scopes []string, authUrl, tokenUrl, groupEndpoint, clientID, clientSecret, hashKey, blockKey string) (*Auth, error) {
func NewAuth(logger logger.Logger, url string, scopes []string, authUrl, tokenUrl, groupEndpoint, logout, clientID, clientSecret, hashKey, blockKey string) (*Auth, error) {
auth := &Auth{
logger: logger,
cookieName: "molecula-chip",
refreshWithin: time.Minute * time.Duration(15),
groupEndpoint: groupEndpoint,
logoutEndpoint: "https://login.microsoftonline.com/common/oauth2/v2.0/logout",
logoutEndpoint: logout,
fbURL: url,
oAuthConfig: &oauth2.Config{
RedirectURL: fmt.Sprintf("%s/redirect", url),
@ -172,13 +172,13 @@ func (a *Auth) newCookieValue(token *oauth2.Token) (*CookieValue, error) {
}
accessParsed, err := jwt.Parse(token.AccessToken, nil)
if token == nil {
fmt.Println(errors.Wrap(err, "parsing jwt claims from access tokens"))
a.logger.Errorf("parsing jwt claims from access tokens: %v", err)
}
claims := accessParsed.Claims.(jwt.MapClaims)
groups, err := a.getGroupMembership(token)
if err != nil {
fmt.Println(errors.Wrap(err, "getting group memebership"))
a.logger.Errorf("getting group memebership %v", err)
}
// not needed at this point in the logic and makes the encoded cookie too large
token.AccessToken = ""
@ -194,6 +194,10 @@ func (a *Auth) getGroupMembership(token *oauth2.Token) (Groups, error) {
var groups Groups
var bearer = fmt.Sprintf("Bearer %s", token.AccessToken)
req, err := http.NewRequest("GET", a.groupEndpoint, nil)
if err != nil {
return groups, errors.Wrap(err, "creating new request to group endpoint")
}
req.Header.Add("Authorization", bearer)
client := &http.Client{}
response, err := client.Do(req)
@ -248,7 +252,6 @@ func (a *Auth) setCookie(w http.ResponseWriter, cookie *CookieValue) error {
}
func (a *Auth) refreshToken(w http.ResponseWriter, cookie *CookieValue) error {
fmt.Println("REFRESHING TOKEN")
if cookie.Token.RefreshToken == "" {
return errors.New("no refresh token found, check auth scopes to see if refresh tokens are being provided by your IdP.")
}
@ -258,8 +261,6 @@ func (a *Auth) refreshToken(w http.ResponseWriter, cookie *CookieValue) error {
return errors.Wrap(err, "refreshing token")
}
fmt.Printf("Refreshed AT: %v\n\n", newToken.AccessToken)
if newToken.Expiry != cookie.Token.Expiry {
cv, err := a.newCookieValue(newToken)
if err != nil {
@ -267,7 +268,6 @@ func (a *Auth) refreshToken(w http.ResponseWriter, cookie *CookieValue) error {
}
a.setCookie(w, cv)
fmt.Println("refreshed access token")
}
return nil

View file

@ -22,6 +22,7 @@ func TestAuth(t *testing.T) {
settings.Auth.AuthorizeURL = "https://login.microsoftonline.com/4a137d66-d161-4ae4-b1e6-07e9920874b8/oauth2/v2.0/authorize"
settings.Auth.TokenURL = "https://login.microsoftonline.com/4a137d66-d161-4ae4-b1e6-07e9920874b8/oauth2/v2.0/token"
settings.Auth.GroupEndpointURL = "https://graph.microsoft.com/v1.0/me/transitiveMemberOf/microsoft.graph.group?$count=true"
settings.Auth.LogoutURL = "https://login.microsoftonline.com/common/oauth2/v2.0/logout"
settings.Auth.Scopes = []string{"https://graph.microsoft.com/.default", "offline_access"}
settings.Auth.HashKey = "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"
settings.Auth.BlockKey = "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"
@ -33,6 +34,7 @@ func TestAuth(t *testing.T) {
settings.Auth.AuthorizeURL,
settings.Auth.TokenURL,
settings.Auth.GroupEndpointURL,
settings.Auth.LogoutURL,
settings.Auth.ClientId,
settings.Auth.ClientSecret,
settings.Auth.HashKey,

View file

@ -116,6 +116,7 @@ func BuildServerFlags(cmd *cobra.Command, srv *server.Command) {
flags.StringVar(&srv.Config.Auth.AuthorizeURL, "auth.authorize-url", srv.Config.Auth.AuthorizeURL, "Identity Provider's Authorize URL.")
flags.StringVar(&srv.Config.Auth.TokenURL, "auth.token-url", srv.Config.Auth.TokenURL, "Identity Provider's Token URL.")
flags.StringVar(&srv.Config.Auth.GroupEndpointURL, "auth.group-endpoint-url", srv.Config.Auth.GroupEndpointURL, "Identity Provider's Group endpoint URL.")
flags.StringVar(&srv.Config.Auth.LogoutURL, "auth.logout-url", srv.Config.Auth.LogoutURL, "Identity Provider's Logout URL.")
flags.StringSliceVar(&srv.Config.Auth.Scopes, "auth.scopes", srv.Config.Auth.Scopes, "Comma separated list of scopes obtained from IdP")
flags.StringVar(&srv.Config.Auth.HashKey, "auth.hash-key", srv.Config.Auth.HashKey, "First Secret for Auth.")
flags.StringVar(&srv.Config.Auth.BlockKey, "auth.block-key", srv.Config.Auth.BlockKey, "Second Secret for Auth.")

View file

@ -178,25 +178,43 @@ func TestFieldOptionValidation(t *testing.T) {
}
}
func readResponse(w *httptest.ResponseRecorder) ([]byte, error) {
res := w.Result()
defer res.Body.Close()
return ioutil.ReadAll(res.Body)
}
func TestAuth(t *testing.T) {
var (
ClientId = "e9088663-eb08-41d7-8f65-efb5f54bbb71"
ClientSecret = "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"
AuthorizeURL = "https://login.microsoftonline.com/4a137d66-d161-4ae4-b1e6-07e9920874b8/oauth2/v2.0/authorize"
TokenURL = "https://login.microsoftonline.com/4a137d66-d161-4ae4-b1e6-07e9920874b8/oauth2/v2.0/token"
GroupEndpointURL = "https://graph.microsoft.com/v1.0/me/transitiveMemberOf/microsoft.graph.group?$count=true"
LogoutURL = "https://login.microsoftonline.com/common/oauth2/v2.0/logout"
Scopes = []string{"https://graph.microsoft.com/.default", "offline_access"}
HashKey = "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"
BlockKey = "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"
)
hashKey, _ := hex.DecodeString("DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF")
blockKey, _ := hex.DecodeString("DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF")
a, err := authn.NewAuth(
logger.NewStandardLogger(os.Stdout),
"http://localhost:10101/",
[]string{"https://graph.microsoft.com/.default", "offline_access"},
"https://login.microsoftonline.com/4a137d66-d161-4ae4-b1e6-07e9920874b8/oauth2/v2.0/authorize",
"https://login.microsoftonline.com/4a137d66-d161-4ae4-b1e6-07e9920874b8/oauth2/v2.0/token",
"https://graph.microsoft.com/v1.0/me/transitiveMemberOf/microsoft.graph.group?$count=true",
"e9088663-eb08-41d7-8f65-efb5f54bbb71",
"DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF",
"DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF",
"DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF",
Scopes,
AuthorizeURL,
TokenURL,
GroupEndpointURL,
LogoutURL,
ClientId,
ClientSecret,
HashKey,
BlockKey,
)
if err != nil {
t.Errorf("building auth object %s", err)
t.Errorf("building auth object%s", err)
}
h := Handler{
@ -235,30 +253,21 @@ func TestAuth(t *testing.T) {
Expires: validToken.Expiry,
}
t.Run("Login-Cookie", func(t *testing.T) {
t.Run("Login", func(t *testing.T) {
r := httptest.NewRequest(gohttp.MethodGet, "/login", nil)
w := httptest.NewRecorder()
h.handleLogin(w, r)
})
t.Run("Login-NoCookie", func(t *testing.T) {
r := httptest.NewRequest(gohttp.MethodGet, "/login", nil)
w := httptest.NewRecorder()
r.AddCookie(validCookie)
//login w/o cookie
h.handleLogin(w, r)
res := w.Result()
defer res.Body.Close()
data, err := ioutil.ReadAll(res.Body)
data, err := readResponse(w)
if err != nil {
t.Errorf("expected no errors reading response, got: %+v", err)
}
fmt.Printf("%s", data)
//login with cookie
fmt.Printf("%d", strings.Index(string(data), AuthorizeURL))
if strings.Index(string(data), AuthorizeURL) != 9 {
t.Errorf("incorrect redirect url: expected: %s, got: %s", AuthorizeURL, string(data))
}
})
t.Run("Login-BadCookie", func(t *testing.T) {
r := httptest.NewRequest(gohttp.MethodGet, "/login", nil)
@ -280,9 +289,12 @@ func TestAuth(t *testing.T) {
t.Run("Logout", func(t *testing.T) {
r := httptest.NewRequest(gohttp.MethodGet, "/logout", nil)
w := httptest.NewRecorder()
r.AddCookie(validCookie)
h.handleLogout(w, r)
fmt.Println()
//logout with cookie
//logout without cookie

View file

@ -378,9 +378,10 @@ log-path = "/var/log/molecula/featurebase.log"
# enable = false
# client-id = ""
# client-secret = ""
# authorize-url = "https://login.microsoftonline.com/4a137d66-d161-4ae4-b1e6-07e9920874b8/oauth2/v2.0/authorize"
# token-url = "https://login.microsoftonline.com/4a137d66-d161-4ae4-b1e6-07e9920874b8/oauth2/v2.0/token"
# group-endpoint-url = "https://graph.microsoft.com/v1.0/me/transitiveMemberOf/microsoft.graph.group?$count=true"
# scopes = ["https://graph.microsoft.com/.default", "offline_access"]
# authorize-url = ""
# token-url = ""
# group-endpoint-url = ""
# logout-url = ""
# scopes = ["", ""]
# hash-key = ""
# block-key = ""

View file

@ -243,6 +243,7 @@ type Auth struct {
AuthorizeURL string `toml:"authorize-url"`
TokenURL string `toml:"token-url"`
GroupEndpointURL string `toml:"group-endpoint-url"`
LogoutURL string `toml:"logout-url"`
Scopes []string `toml:"scopes"`
HashKey string `toml:"hash-key"`
BlockKey string `toml:"block-key"`
@ -620,6 +621,7 @@ func (c *Config) ValidateAuth() ([]error, error) {
"AuthorizeURL": c.Auth.AuthorizeURL,
"TokenURL": c.Auth.TokenURL,
"GroupEndpointURL": c.Auth.GroupEndpointURL,
"LogoutURL": c.Auth.LogoutURL,
"HashKey": c.Auth.HashKey,
"BlockKey": c.Auth.BlockKey,
}

View file

@ -308,6 +308,7 @@ func TestConfig_validateAuth(t *testing.T) {
errorMesgEmpty,
errorMesgEmpty,
errorMesgEmpty,
errorMesgEmpty,
errorMesgScope,
},
Auth{
@ -317,6 +318,7 @@ func TestConfig_validateAuth(t *testing.T) {
AuthorizeURL: emptyString,
TokenURL: emptyString,
GroupEndpointURL: emptyString,
LogoutURL: emptyString,
Scopes: emptySlice,
HashKey: emptyString,
BlockKey: emptyString,
@ -331,6 +333,7 @@ func TestConfig_validateAuth(t *testing.T) {
errorMesgEmpty,
errorMesgEmpty,
errorMesgEmpty,
errorMesgEmpty,
errorMesgScope,
},
Auth{
@ -340,6 +343,7 @@ func TestConfig_validateAuth(t *testing.T) {
AuthorizeURL: emptyString,
TokenURL: emptyString,
GroupEndpointURL: emptyString,
LogoutURL: emptyString,
Scopes: emptySlice,
HashKey: emptyString,
BlockKey: emptyString,
@ -354,6 +358,7 @@ func TestConfig_validateAuth(t *testing.T) {
errorMesgEmpty,
errorMesgEmpty,
errorMesgEmpty,
errorMesgEmpty,
errorMesgScope,
},
Auth{
@ -363,6 +368,7 @@ func TestConfig_validateAuth(t *testing.T) {
AuthorizeURL: emptyString,
TokenURL: emptyString,
GroupEndpointURL: emptyString,
LogoutURL: emptyString,
Scopes: emptySlice,
HashKey: emptyString,
BlockKey: emptyString,
@ -376,6 +382,7 @@ func TestConfig_validateAuth(t *testing.T) {
errorMesgEmpty,
errorMesgEmpty,
errorMesgEmpty,
errorMesgURL,
errorMesgScope,
},
Auth{
@ -385,6 +392,7 @@ func TestConfig_validateAuth(t *testing.T) {
AuthorizeURL: emptyString,
TokenURL: emptyString,
GroupEndpointURL: emptyString,
LogoutURL: notValidURL,
Scopes: emptySlice,
HashKey: emptyString,
BlockKey: emptyString,
@ -397,6 +405,7 @@ func TestConfig_validateAuth(t *testing.T) {
errorMesgEmpty,
errorMesgEmpty,
errorMesgEmpty,
errorMesgEmpty,
errorMesgScope,
},
Auth{
@ -406,6 +415,7 @@ func TestConfig_validateAuth(t *testing.T) {
AuthorizeURL: validTestURL,
TokenURL: emptyString,
GroupEndpointURL: emptyString,
LogoutURL: emptyString,
Scopes: emptySlice,
HashKey: emptyString,
BlockKey: emptyString,
@ -426,6 +436,7 @@ func TestConfig_validateAuth(t *testing.T) {
AuthorizeURL: validTestURL,
TokenURL: validTestURL,
GroupEndpointURL: emptyString,
LogoutURL: validTestURL,
Scopes: emptySlice,
HashKey: emptyString,
BlockKey: emptyString,
@ -437,6 +448,7 @@ func TestConfig_validateAuth(t *testing.T) {
errorMesgEmpty,
errorMesgEmpty,
errorMesgURL,
errorMesgURL,
},
Auth{
Enable: enable,
@ -445,6 +457,7 @@ func TestConfig_validateAuth(t *testing.T) {
AuthorizeURL: notValidURL,
TokenURL: validTestURL,
GroupEndpointURL: validTestURL,
LogoutURL: notValidURL,
Scopes: validStringSlice,
HashKey: emptyString,
BlockKey: emptyString,
@ -453,6 +466,7 @@ func TestConfig_validateAuth(t *testing.T) {
{
// Auth enabled, some strings are set to invalid URL
[]string{
errorMesgURL,
errorMesgURL,
errorMesgURL,
errorMesgEmpty,
@ -464,6 +478,7 @@ func TestConfig_validateAuth(t *testing.T) {
AuthorizeURL: validTestURL,
TokenURL: notValidURL,
GroupEndpointURL: notValidURL,
LogoutURL: notValidURL,
Scopes: validStringSlice,
HashKey: emptyString,
BlockKey: validKey,
@ -479,21 +494,23 @@ func TestConfig_validateAuth(t *testing.T) {
AuthorizeURL: validTestURL,
TokenURL: validTestURL,
GroupEndpointURL: validTestURL,
LogoutURL: validTestURL,
Scopes: validStringSlice,
HashKey: validKey,
BlockKey: validKey,
},
},
{
// Auth disabled, all configs are set to valid values
// Auth disabled, all configs are set to some values
[]string{},
Auth{
Enable: disable,
ClientId: validString,
ClientSecret: validString,
AuthorizeURL: validString,
TokenURL: validString,
GroupEndpointURL: validString,
TokenURL: validTestURL,
GroupEndpointURL: validTestURL,
LogoutURL: validTestURL,
Scopes: validStringSlice,
HashKey: validKey,
BlockKey: validKey,

View file

@ -525,7 +525,7 @@ func (m *Command) SetupServer() error {
if m.Config.Auth.Enable {
m.Config.MustValidateAuth()
ac := m.Config.Auth
m.auth, err = authn.NewAuth(m.logger, m.listenURI.String(), ac.Scopes, ac.AuthorizeURL, ac.TokenURL, ac.GroupEndpointURL, ac.ClientId, ac.ClientSecret, ac.HashKey, ac.BlockKey)
m.auth, err = authn.NewAuth(m.logger, m.listenURI.String(), ac.Scopes, ac.AuthorizeURL, ac.TokenURL, ac.GroupEndpointURL, ac.LogoutURL, ac.ClientId, ac.ClientSecret, ac.HashKey, ac.BlockKey)
if err != nil {
return errors.Wrap(err, "instantiating authN object")
}