Skip to content

Commit

Permalink
Release v2.2.0 (#81)
Browse files Browse the repository at this point in the history
  • Loading branch information
shurwit committed Nov 23, 2022
2 parents 008e877 + 2633df3 commit 81e5036
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 56 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased
## [2.2.0] - 2022-11-23
### Added
- Function param on base token auth handlers [#79](https://github.com/rokwire/core-auth-library-go/issues/79)
### Fixed
- Empty request body on refresh service token in makeRequest [#77](https://github.com/rokwire/core-auth-library-go/issues/77)

## [2.1.0] - 2022-11-16
### Added
Expand Down Expand Up @@ -85,7 +90,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Initial release

[Unreleased]: https://github.com/rokwire/core-auth-library-go/compare/v2.1.0....HEAD
[Unreleased]: https://github.com/rokwire/core-auth-library-go/compare/v2.2.0....HEAD
[2.2.0]: https://github.com/rokwire/core-auth-library-go/compare/v2.1.0...v2.2.0
[2.1.0]: https://github.com/rokwire/core-auth-library-go/compare/v2.0.3...v2.1.0
[2.0.3]: https://github.com/rokwire/core-auth-library-go/compare/v2.0.2...v2.0.3
[2.0.2]: https://github.com/rokwire/core-auth-library-go/compare/v2.0.1...v2.0.2
Expand Down
4 changes: 2 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
Patches for **Core Auth Library** in this repository will only be applied to the following versions:
| Version | Supported |
| ------- | ------------------ |
| 2.1.0 | :white_check_mark: |
| < 2.1.0 | :x: |
| 2.2.0 | :white_check_mark: |
| < 2.2.0 | :x: |

## Reporting a Bug or Vulnerability

Expand Down
31 changes: 29 additions & 2 deletions authservice/auth_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ func (s *ServiceAccountManager) GetAccessTokens() (map[AppOrgPair]AccessToken, [
i++
}

now := time.Now()
now := time.Now().UTC()
s.tokensUpdated = &now

return tokens, newPairs, nil
Expand Down Expand Up @@ -670,6 +670,16 @@ func (s *ServiceAccountManager) makeRequest(req *http.Request, appID string, org
}
}

// copy request body in case token refresh is required
var reqBody io.ReadCloser
if req.Body != nil {
reqBody, err = req.GetBody()
if err != nil {
retErr := fmt.Errorf("error reading request body: %v", err)
return s.handleRequestResponse(async, false, *appOrgPair, nil, retErr, nil, rrc, pc, dc)
}
}

req.Header.Set("Authorization", token.String())
resp, err := s.client.Do(req)
if err != nil {
Expand All @@ -686,12 +696,18 @@ func (s *ServiceAccountManager) makeRequest(req *http.Request, appID string, org
return s.handleRequestResponse(async, false, *appOrgPair, nil, err, newPairs, rrc, pc, dc)
}

req.Body = reqBody
req.Header.Set("Authorization", token.String())
resp, err = s.client.Do(req)
if err != nil {
retErr := fmt.Errorf("error sending request: %v", err)
return s.handleRequestResponse(async, false, *refreshedPair, nil, retErr, newPairs, rrc, pc, dc)
}
if resp.StatusCode == http.StatusUnauthorized {
// unauthorized again, so set error containing info about max token refresh frequency
retErr := fmt.Errorf("unauthorized after token refresh (max token refresh frequency is set to once every %d minutes, see SetMaxRefreshCacheFreq)", s.maxRefreshCacheFreq)
return s.handleRequestResponse(async, false, *refreshedPair, resp, retErr, newPairs, rrc, pc, dc)
}

appOrgPair = refreshedPair
}
Expand Down Expand Up @@ -735,8 +751,19 @@ func (s *ServiceAccountManager) makeRequests(req *http.Request, pairs []AppOrgPa
// filter out duplicate pairs and launch a goroutine for each unique requested pair
for _, pair := range pairs {
if !authutils.ContainsString(uniquePairs, pair.String()) {
// clone request
clonedReq := req.Clone(context.Background())
if req.Body != nil {
reqBody, err := req.GetBody()
if err != nil {
responses[pair] = RequestResponse{TokenPair: pair, Response: nil, Error: fmt.Errorf("error getting request body: %v", err)}
continue
}
clonedReq.Body = reqBody
}

uniquePairs = append(uniquePairs, pair.String())
go s.makeRequest(req.Clone(context.Background()), pair.AppID, pair.OrgID, responseChan, pairChan, duplicateChan)
go s.makeRequest(clonedReq, pair.AppID, pair.OrgID, responseChan, pairChan, duplicateChan)
}
}

Expand Down
2 changes: 1 addition & 1 deletion example/token/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func main() {
if err != nil || tokenAuth == nil {
log.Fatalf("Error initializing token auth: %v", err)
}
authHandlers := tokenauth.NewHandlers(tokenauth.NewScopeHandler(*tokenAuth))
authHandlers := tokenauth.NewHandlers(tokenauth.NewScopeHandler(*tokenAuth, nil))

fmt.Println("Setup complete")

Expand Down
101 changes: 51 additions & 50 deletions tokenauth/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,58 +48,59 @@ func NewHandlers(auth Handler) Handlers {
// StandardHandler entity
// This enforces that the token is valid
type StandardHandler struct {
tokenAuth TokenAuth
tokenAuth TokenAuth
claimsCheck func(*Claims, *http.Request) (int, error)
}

// Check checks the token in the provided request
func (a StandardHandler) Check(req *http.Request) (int, *Claims, error) {
claims, err := a.tokenAuth.CheckRequestTokens(req)
func (h StandardHandler) Check(req *http.Request) (int, *Claims, error) {
claims, err := h.tokenAuth.CheckRequestTokens(req)
if err != nil {
return http.StatusUnauthorized, nil, errors.WrapErrorAction(logutils.ActionValidate, logutils.TypeToken, nil, err)
}

return http.StatusOK, claims, nil
status := http.StatusOK
if h.claimsCheck != nil {
status, err = h.claimsCheck(claims, req)
if err != nil {
return status, nil, err
}
}

return status, claims, nil
}

// GetTokenAuth exposes the TokenAuth for the handler
func (a StandardHandler) GetTokenAuth() *TokenAuth {
return &a.tokenAuth
func (h StandardHandler) GetTokenAuth() *TokenAuth {
return &h.tokenAuth
}

// NewStandardHandler creates a new StandardHandler
func NewStandardHandler(tokenAuth TokenAuth) StandardHandler {
return StandardHandler{tokenAuth: tokenAuth}
}

// ScopeHandler entity
// This enforces that the token has scopes matching the policy
type ScopeHandler struct {
tokenAuth TokenAuth
}

// Check checks the token in the provided request
func (a ScopeHandler) Check(req *http.Request) (int, *Claims, error) {
claims, err := a.tokenAuth.CheckRequestTokens(req)
if err != nil {
return http.StatusUnauthorized, nil, errors.WrapErrorAction(logutils.ActionValidate, logutils.TypeToken, nil, err)
func NewStandardHandler(tokenAuth TokenAuth, claimsCheck func(*Claims, *http.Request) (int, error)) StandardHandler {
return StandardHandler{tokenAuth: tokenAuth, claimsCheck: claimsCheck}
}

// NewScopeHandler creates a new StandardHandler that checks scopes
func NewScopeHandler(tokenAuth TokenAuth, claimsCheck func(*Claims, *http.Request) (int, error)) StandardHandler {
check := func(claims *Claims, req *http.Request) (int, error) {
status := http.StatusOK
var err error
if claimsCheck != nil {
status, err = claimsCheck(claims, req)
if err != nil {
return status, err
}
}

err = tokenAuth.AuthorizeRequestScope(claims, req)
if err != nil {
return http.StatusForbidden, errors.WrapErrorAction(logutils.ActionValidate, logutils.TypeScope, nil, err)
}

return status, nil
}

err = a.tokenAuth.AuthorizeRequestScope(claims, req)
if err != nil {
return http.StatusForbidden, nil, errors.WrapErrorAction(logutils.ActionValidate, logutils.TypeScope, nil, err)
}

return http.StatusOK, claims, nil
}

// GetTokenAuth exposes the TokenAuth for the handler
func (a ScopeHandler) GetTokenAuth() *TokenAuth {
return &a.tokenAuth
}

// NewScopeHandler creates a new ScopeHandler
func NewScopeHandler(tokenAuth TokenAuth) ScopeHandler {
return ScopeHandler{tokenAuth: tokenAuth}
return NewStandardHandler(tokenAuth, check)
}

// PermissionsHandler entity
Expand All @@ -109,13 +110,13 @@ type PermissionsHandler struct {
}

// Check checks the token in the provided request
func (a PermissionsHandler) Check(req *http.Request) (int, *Claims, error) {
status, claims, err := a.auth.Check(req)
func (h PermissionsHandler) Check(req *http.Request) (int, *Claims, error) {
status, claims, err := h.auth.Check(req)
if err != nil || claims == nil {
return status, claims, err
}

err = a.auth.GetTokenAuth().AuthorizeRequestPermissions(claims, req)
err = h.auth.GetTokenAuth().AuthorizeRequestPermissions(claims, req)
if err != nil {
return http.StatusForbidden, nil, errors.WrapErrorAction(logutils.ActionValidate, logutils.TypePermission, nil, err)
}
Expand All @@ -124,8 +125,8 @@ func (a PermissionsHandler) Check(req *http.Request) (int, *Claims, error) {
}

// GetTokenAuth exposes the TokenAuth for the handler
func (a PermissionsHandler) GetTokenAuth() *TokenAuth {
return a.auth.GetTokenAuth()
func (h PermissionsHandler) GetTokenAuth() *TokenAuth {
return h.auth.GetTokenAuth()
}

// NewPermissionsHandler creates a new PermissionsHandler
Expand All @@ -140,8 +141,8 @@ type UserHandler struct {
}

// Check checks the token in the provided request
func (a UserHandler) Check(req *http.Request) (int, *Claims, error) {
status, claims, err := a.auth.Check(req)
func (h UserHandler) Check(req *http.Request) (int, *Claims, error) {
status, claims, err := h.auth.Check(req)
if err != nil || claims == nil {
return status, claims, err
}
Expand All @@ -154,8 +155,8 @@ func (a UserHandler) Check(req *http.Request) (int, *Claims, error) {
}

// GetTokenAuth exposes the TokenAuth for the handler
func (a UserHandler) GetTokenAuth() *TokenAuth {
return a.auth.GetTokenAuth()
func (h UserHandler) GetTokenAuth() *TokenAuth {
return h.auth.GetTokenAuth()
}

// NewUserHandler creates a new UserHandler
Expand All @@ -170,8 +171,8 @@ type AuthenticatedHandler struct {
}

// Check checks the token in the provided request
func (a AuthenticatedHandler) Check(req *http.Request) (int, *Claims, error) {
status, claims, err := a.userAuth.Check(req)
func (h AuthenticatedHandler) Check(req *http.Request) (int, *Claims, error) {
status, claims, err := h.userAuth.Check(req)
if err != nil || claims == nil {
return status, claims, err
}
Expand All @@ -184,8 +185,8 @@ func (a AuthenticatedHandler) Check(req *http.Request) (int, *Claims, error) {
}

// GetTokenAuth exposes the TokenAuth for the handler
func (a AuthenticatedHandler) GetTokenAuth() *TokenAuth {
return a.userAuth.GetTokenAuth()
func (h AuthenticatedHandler) GetTokenAuth() *TokenAuth {
return h.userAuth.GetTokenAuth()
}

// NewAuthenticatedHandler creates a new AuthenticatedHandler
Expand Down

0 comments on commit 81e5036

Please sign in to comment.