-
-
Save influx6/358cb5c518631ae6869f4970b247e51c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package auth | |
import ( | |
"context" | |
"net/http" | |
"strings" | |
"google.golang.org/grpc/metadata" | |
"github.com/andela/micro-api-gateway/pb/authorization" | |
"github.com/andela/micro-api-gateway/pb/user" | |
"github.com/labstack/echo" | |
) | |
// NewOAuth2Provider returns a generic OAuth 2.0 backend endpoint. | |
func Authorize(fn func(string) (Claims, error)) echo.MiddlewareFunc { | |
return func(next echo.HandlerFunc) echo.HandlerFunc { | |
return func(c echo.Context) error { | |
if c.Path() == "/favicon.ico" { | |
return nil | |
} | |
if c.Path() == "/" { | |
return next(c) | |
} | |
if c.Path() == "/health" { | |
return next(c) | |
} | |
if c.Request().Header.Get("x-forwarded-proto") == "http" { | |
to := "https://" + c.Request().Host + c.Request().URL.RequestURI() | |
return c.Redirect(redirectStatusCode, to) | |
} | |
return handleOtherRouteAccess(fn, next, c) | |
} | |
} | |
} | |
func handleOtherRouteAccess(fn func(string) (Claims, error), next echo.HandlerFunc, c echo.Context) error { | |
var claims Claims | |
if apiToken := c.Request().Header.Get("api-token"); apiToken != "" { | |
u, err := usersClient.ValidateAPIToken(context.Background(), &user.APIToken{Token: apiToken}) | |
if err != nil { | |
return respondWithError(401, "invalid api token", c) | |
} | |
claims = NewClaims(u) | |
claims.Permissions, _ = getPermission(u.Roles) | |
} else { | |
var tokenString string | |
jwtToken, err := c.Cookie("jwt-token") | |
if err != nil || jwtToken == nil { | |
if tokenString = getTokenFromRequest(c.Request()); tokenString == "" { | |
return respondWithError(401, "token not present", c) | |
} | |
} else { | |
tokenString = jwtToken.Value | |
} | |
claims, err = fn(tokenString) | |
if err != nil { | |
return respondWithError(401, "invalid token", c) | |
} | |
} | |
in := authorization.AuthorizeRequest{} | |
in.Method = c.Request().Method | |
in.Url = c.Request().URL.Path | |
for _, id := range claims.Permissions { | |
in.PermissionIds = append(in.PermissionIds, id) | |
} | |
if _, err := authorizationClient.Authorize(context.Background(), &in); err != nil { | |
return respondWithError(401, "user not authorized", c) | |
} | |
ctx := metadata.NewContext( | |
context.Background(), | |
metadata.Pairs("author_id", claims.Id, "author_name", claims.Name, "author_email", claims.Email), | |
) | |
c.Set("claims", claims) | |
c.Set("context", ctx) | |
c.Set("user_id", claims.Id) | |
return next(c) | |
} | |
func respondWithError(code int, message string, c echo.Context) error { | |
return c.JSON(code, echo.Map{"error": message}) | |
} | |
func getTokenFromRequest(req *http.Request) string { | |
authStr := req.Header.Get("Authorization") | |
if !strings.HasPrefix(authStr, "Bearer ") { | |
return "" | |
} | |
return authStr[7:] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment