diff --git a/internal/cognitoauth/auth.go b/internal/cognitoauth/auth.go
index c675e868..bfb1fd4d 100644
--- a/internal/cognitoauth/auth.go
+++ b/internal/cognitoauth/auth.go
@@ -47,17 +47,6 @@ func RegisterRoutes(e *echo.Echo, config auth.ConfigProvider) {
})
})
- //fmt.Printf("registering logoutpath: %s \v", config.GetAuthLogoutPath())
- //// Register logout route
- //e.GET(config.GetAuthLogoutPath(), func(c echo.Context) error {
- // return LogoutHandler(c)
- //})
-
- //// Default home page handler if requested
- //e.GET(config.GetAuthHomePath(), func(c echo.Context) error {
- // return HomeHandler(c, config)
- //})
-
// Apply the JWT Auth middleware first
e.Use(JWTAuthMiddleware(config))
@@ -65,183 +54,6 @@ func RegisterRoutes(e *echo.Echo, config auth.ConfigProvider) {
e.Use(TokenValidationMiddleware(config))
}
-// HomeHandler implements a simple home page that shows auth status and available endpoints
-func HomeHandler(c echo.Context, config auth.ConfigProvider) error {
- // Create a list of all registered routes
- println("HomeHandler called.")
-
- var endpoints []string
-
- // Add the auth routes
- endpoints = append(endpoints, []string{
- config.GetAuthLoginPath(),
- config.GetAuthCallbackPath(),
- config.GetAuthHomePath(),
- config.GetAuthLogoutPath(),
- }...)
-
- // Add routes from the permission map
- for route := range config.GetAuthRoutePermissions() {
- // Skip routes that are already in the list
- alreadyAdded := false
- for _, endpoint := range endpoints {
- if route == endpoint {
- alreadyAdded = true
- break
- }
- }
- if !alreadyAdded {
- endpoints = append(endpoints, route)
- }
- }
-
- // Check if user is authenticated by looking for token in cookie
- tokenCookie, err := c.Cookie("auth_token")
- isAuthenticated := (err == nil && tokenCookie.Value != "")
-
- // Variables for user info
- username := ""
- email := ""
- var userGroups []string
-
- // If authenticated, try to decode the JWT token to get user info
- if isAuthenticated {
- // Parse the JWT token without verification (just to extract info for display)
- token, _ := jwt.Parse([]byte(tokenCookie.Value), jwt.WithVerify(false))
- if token != nil {
- claims, _ := token.AsMap(context.Background())
- username, _ = claims["cognito:username"].(string)
- email, _ = claims["email"].(string)
-
- // Try to extract groups
- userGroups, _ = GetUserGroups(claims)
- }
- }
-
- // Create HTML for the endpoints list
- var linksHTML string
- baseURL := c.Scheme() + "://" + c.Request().Host
-
- // Create list items for each endpoint
- for _, endpoint := range endpoints {
- // Skip endpoints with path parameters for direct linking
- if strings.Contains(endpoint, ":") {
- displayPath := strings.Replace(endpoint, ":id", "{id}", -1)
- linksHTML += fmt.Sprintf("
%s (requires parameter)\n", displayPath)
- } else {
- linksHTML += fmt.Sprintf("%s\n", baseURL, endpoint, endpoint)
- }
- }
-
- // Create authentication status section
- var authStatusHTML string
- if isAuthenticated {
- authStatusHTML = fmt.Sprintf(`
-
-
Authentication Status: Authenticated
-
Username: %s
-
Email: %s
-
Groups: %s
-
Logout
-
- `, username, email, strings.Join(userGroups, ", "), baseURL)
- } else {
- authStatusHTML = fmt.Sprintf(`
-
-
Authentication Status: Not Authenticated
-
You are not currently logged in.
-
Login
-
- `, baseURL)
- }
-
- // Create the complete HTML page
- html := fmt.Sprintf(`
-
-
-
- Authentication Home
-
-
-
- Authentication Home
-
- %s
-
- Available Endpoints
-
-
-
-
Note: This is a debugging page. Some endpoints require authentication or specific permissions.
-
-
-
- `, authStatusHTML, linksHTML)
-
- return c.HTML(http.StatusOK, html)
-}
-
// GetTokenFromRequest extracts the token from the request
func GetTokenFromRequest(c echo.Context) string {
// First try from Authorization header
diff --git a/internal/cognitoauth/readme.md b/internal/cognitoauth/readme.md
index 4ad8f29f..85bb9ab5 100644
--- a/internal/cognitoauth/readme.md
+++ b/internal/cognitoauth/readme.md
@@ -31,3 +31,7 @@ The package reads configuration from environment variables:
- `AWS_REGION`: AWS region where your Cognito User Pool is located (us-east-2)
- `DEBUG`: Set to "true" for debug logging
+## Route Permissions
+Route permissions are hard-coded in the `route_permissions.go` file.
+In the future we may
+integrate this information into the swagger API document.
\ No newline at end of file
diff --git a/internal/cognitoauth/summary.md b/internal/cognitoauth/summary.md
index ae260adf..1a0e228a 100644
--- a/internal/cognitoauth/summary.md
+++ b/internal/cognitoauth/summary.md
@@ -37,6 +37,9 @@ This package uses AWS Cognito for authentication and implements Role-Based Acces
- **Registers Cognito RBAC middleware and routes before registering API handlers.**
- Sets route-level permissions via a map of route to allowed groups.
+## Cognito client user group setup
+The cognito client must be setup to redirect back to /login-callback for PKCE flow to work.
+
## Integration Flow
1. **Config Initialization**: Auth config and route permissions are loaded at startup.
@@ -79,3 +82,30 @@ RegisterHandlers(echoRouter, controllers)
- Route permissions are fully customizable.
- Middleware can be extended or replaced for fine-grained control.
- User info is accessible in handlers via helper functions.
+
+
+## Cognito auth flow (mermaid)
+For a live graph of the auto flow go [here.](https://mermaid.live/edit#pako:eNp9VE2P2jAQ_SsjH3pisyQQAlHLimVXvfQDle0eKqTK6wxgAXZqO7sFxH_vOISvhZKDFdvPb968GXvNhM6QpczinwKVwAfJJ4YvRgroy7lxUsicKwf3Rr9ZNOcbvTwfonlFA9zCgxarZS-X94_nwL6eKOn0dmM7VqQ33e6eJYUwgM-PT3A71xOptrhv2iFoH-MIFxEOFRpOez6L37QqxxLNxxdz2z3dElM-n6Oa4JZvz0KRKw0pNAL4gZk0KBw4fSr3ILRaTqFZydS8cNPo1o_ayBXeBUFwKeYhhz1FHMDAaIHWgj8OxhfBui2-Qh0rbAW7VfjizYEB37FfEJgE8JOWQBjMUDnJ5_a_StoBPPO5zErD3uMvKOkcefUmSbrP-FpN68dFvRHkzAsXszt_7BMZdqXMYehjOSPx9V2dz2u5zyek5hh8Hx7K4_QMVdkYu5AfTrguiTiwNY7toWPAVQanMg4mHWunJnnykS3V1uZaWbyWKfXDsyddQinXlnr7UxQzyNEspLWSKK60cEgd0qN8ffkEd4QGWwjfYONizmpsQSxcZnTf155lxAi6wBFL6TfjZjZiI7UhHHmmh0slWOpMgTVmdDGZsnRMLUGzIvdGVC_FDkJX_JfW-yk1h9Pm6_ZxKd-YGpsYH7piRJWh6etCOZZ2yuMsXbO_LA3rSdAMw7DRiOJOUo86cY0tWZokQb3ZbMRRFLWjsBVvamxVxqsH7aSexO1WHLX8X9TZ_AMOB5n7)
+```mermaid
+sequenceDiagram
+ participant Browser
+ participant AppServer as DoczyApiBE
+ participant Cognito
+
+ Browser->>AppServer: 1. GET /login
+ Note over AppServer: 2. Generate code_verifier
Generate code_challenge
+ AppServer->>Browser: 3. Redirect to Cognito
+ Browser->>Cognito: 4. GET /oauth2/authorize?...code_challenge
+ Note over Cognito: 5. Process auth request
+ Cognito->>Browser: 6. Cognito Login Page
+ Browser->>Cognito: 7. User credentials
+ Note over Cognito: 8. Validate credentials
+ Cognito->>Browser: 9. Redirect with code
+ Browser->>AppServer: 10. GET /login-callback?code=...
+ Note over AppServer: 11. Retrieve code_verifier
+ AppServer->>Cognito: 12. POST /oauth2/token
code=...&code_verifier=...
+ Note over Cognito: 13. Validate code and verifier
+ Cognito->>AppServer: 14. Tokens response
+ Note over AppServer: 15. Verify tokens
Check permissions
+ AppServer->>Browser: 16. Authentication successful
+```
\ No newline at end of file
diff --git a/internal/server/api/listener.go b/internal/server/api/listener.go
index 1371b143..d4a03d1d 100644
--- a/internal/server/api/listener.go
+++ b/internal/server/api/listener.go
@@ -189,14 +189,8 @@ func New(ctx context.Context, cfg Config) (*Server, error) {
cfg.SetRouter(e)
// auth start - may move to separate rbac function
- routePermissions := map[string][]string{
- "/users": {"exporters", "uploaders", "querybuilders"},
- "/users/:id": {"exporters", "querybuilders"},
- "/orders": {"exporters"},
- "/reports/sales": {"exporters", "uploaders", "querybuilders"},
- "/settings": {"exporters"},
- "/api/inventory/update": {"exporters", "uploaders"},
- }
+ // update these to match the endpoints.
+ routePermissions := GetRoutePermissions()
cfg.SetAuthRoutePermissions(routePermissions)
cognitoauth.RegisterRoutes(cfg.GetRouter(), cfg)
diff --git a/internal/server/api/route_permissions.go b/internal/server/api/route_permissions.go
new file mode 100644
index 00000000..f61cc014
--- /dev/null
+++ b/internal/server/api/route_permissions.go
@@ -0,0 +1,11 @@
+package api
+
+func GetRoutePermissions() map[string][]string {
+ return map[string][]string{
+ "/client": {"exporters", "uploaders", "querybuilders"},
+ "/document": {"exporters", "querybuilders"},
+ "/query": {"exporters", "uploaders", "querybuilders"},
+ "/export": {"exporters"},
+ "/settings": {"exporters"},
+ }
+}