mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-07 17:15:56 +00:00
move logout url to conf
This commit is contained in:
parent
405692e376
commit
6faa889bfb
8 changed files with 76 additions and 41 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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.")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 = ""
|
||||
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue