Skip to content

Commit

Permalink
Added some more scoping functions
Browse files Browse the repository at this point in the history
  • Loading branch information
djthorpe committed Jun 5, 2024
1 parent 99ba24c commit f013315
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 1 deletion.
4 changes: 3 additions & 1 deletion pkg/handler/auth/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,22 @@ func (middleware *auth) Wrap(ctx context.Context, next http.HandlerFunc) http.Ha
authorized := true
if token.IsZero() {
authorized = false
httpresponse.Error(w, http.StatusUnauthorized, "invalid or missing token")
} else if !token.IsValid() {
authorized = false
httpresponse.Error(w, http.StatusUnauthorized, "invalid or missing token")
} else if token.IsScope(ScopeRoot) {
// Allow - token is a super-user token
} else if allowedScopes := router.Scope(r.Context()); len(allowedScopes) == 0 {
// Allow - no scopes have been defined on this endpoint
} else if !token.IsScope(allowedScopes...) {
// Deny - token does not have the required scopes
authorized = false
httpresponse.Error(w, http.StatusUnauthorized, "required scope: ", strings.Join(allowedScopes, ","))
}

// Return unauthorized if token is not found or not valid
if !authorized {
httpresponse.Error(w, http.StatusUnauthorized)
return
}

Expand Down
43 changes: 43 additions & 0 deletions pkg/handler/router/endpoints.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package router

import (
"context"
"net/http"
"regexp"

// Packages
server "github.com/mutablelogic/go-server"
httpresponse "github.com/mutablelogic/go-server/pkg/httpresponse"
)

///////////////////////////////////////////////////////////////////////////////
// GLOBALS

const (
jsonIndent = 2
)

var (
reRoot = regexp.MustCompile(`^/?$`)
)

///////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS - ENDPOINTS

// Add endpoints to the router
func (service *router) AddEndpoints(ctx context.Context, r server.Router) {
// Path: /
// Methods: GET
// Scopes: read
// Description: Get router services
r.AddHandlerFuncRe(ctx, reRoot, service.GetScopes, http.MethodGet).(Route).
SetScope(service.ScopeRead()...)
}

///////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS

// Get registered scopes
func (service *router) GetScopes(w http.ResponseWriter, r *http.Request) {
httpresponse.JSON(w, service.Scopes(), http.StatusOK, jsonIndent)
}
3 changes: 3 additions & 0 deletions pkg/handler/router/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ type Router interface {
// http status code, which will be 200 on success, 404 or 405 and
// path parameters extracted from the path.
Match(host, method, path string) (*matchedRoute, int)

// Return all known scopes
Scopes() []string
}

type Route interface {
Expand Down
25 changes: 25 additions & 0 deletions pkg/handler/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,31 @@ func (router *router) Match(host, method, path string) (*matchedRoute, int) {
return nil, http.StatusMethodNotAllowed
}

func (router *router) Scopes() []string {
scopes := make(map[string]bool)
for _, r := range router.host {
for _, h := range r.prefix {
for _, r := range h.handlers {
for _, s := range r.scopes {
scopes[s] = true
}
}
}
}

// Gather all scopes
result := make([]string, 0, len(scopes))
for scope := range scopes {
result = append(result, scope)
}

// Sort alphabetically
sort.Strings(result)

// Return the result
return result
}

///////////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS

Expand Down
33 changes: 33 additions & 0 deletions pkg/handler/router/scope.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package router

import (
// Packages
"github.com/mutablelogic/go-server/pkg/version"
)

////////////////////////////////////////////////////////////////////////////////
// GLOBALS

var (
// Prefix
scopePrefix = version.GitSource + "/scope/"
)

////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS

func (router *router) ScopeRead() []string {
// Return read (list, get) scopes
return []string{
scopePrefix + router.Label() + "/read",
scopePrefix + defaultName + "/read",
}
}

func (router *router) ScopeWrite() []string {
// Return write (create, delete, update) scopes
return []string{
scopePrefix + router.Label() + "/write",
scopePrefix + defaultName + "/write",
}
}

0 comments on commit f013315

Please sign in to comment.