Skip to content

Commit

Permalink
Merge pull request #71 from mutablelogic/v4
Browse files Browse the repository at this point in the history
Added certificate management
  • Loading branch information
djthorpe authored Jun 7, 2024
2 parents e39a8d5 + d9d7a64 commit e9c0269
Show file tree
Hide file tree
Showing 34 changed files with 2,332 additions and 22 deletions.
2 changes: 1 addition & 1 deletion cmd/http-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import (
// Packages
server "github.com/mutablelogic/go-server"
ctx "github.com/mutablelogic/go-server/pkg/context"
logger "github.com/mutablelogic/go-server/pkg/handler/logger"
router "github.com/mutablelogic/go-server/pkg/handler/router"
static "github.com/mutablelogic/go-server/pkg/handler/static"
httpserver "github.com/mutablelogic/go-server/pkg/httpserver"
logger "github.com/mutablelogic/go-server/pkg/middleware/logger"
provider "github.com/mutablelogic/go-server/pkg/provider"
)

Expand Down
28 changes: 26 additions & 2 deletions cmd/nginx-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ import (
server "github.com/mutablelogic/go-server"
ctx "github.com/mutablelogic/go-server/pkg/context"
auth "github.com/mutablelogic/go-server/pkg/handler/auth"
certmanager "github.com/mutablelogic/go-server/pkg/handler/certmanager"
certstore "github.com/mutablelogic/go-server/pkg/handler/certmanager/certstore"
logger "github.com/mutablelogic/go-server/pkg/handler/logger"
nginx "github.com/mutablelogic/go-server/pkg/handler/nginx"
router "github.com/mutablelogic/go-server/pkg/handler/router"
tokenjar "github.com/mutablelogic/go-server/pkg/handler/tokenjar"
httpserver "github.com/mutablelogic/go-server/pkg/httpserver"
logger "github.com/mutablelogic/go-server/pkg/middleware/logger"
provider "github.com/mutablelogic/go-server/pkg/provider"
)

Expand Down Expand Up @@ -68,6 +70,21 @@ func main() {
log.Fatal(err)
}

// Cert Storage
certstore, err := certstore.Config{
DataPath: filepath.Join(n.(nginx.Nginx).Config(), "cert"),
Group: *group,
}.New()
if err != nil {
log.Fatal(err)
}
certmanager, err := certmanager.Config{
CertStorage: certstore.(certmanager.CertStorage),
}.New()
if err != nil {
log.Fatal(err)
}

// Location of the FCGI unix socket
socket := filepath.Join(n.(nginx.Nginx).Config(), "run/go-server.sock")

Expand All @@ -88,6 +105,13 @@ func main() {
auth.(server.Middleware),
},
},
"cert": { // /api/cert/...
Service: certmanager.(server.ServiceEndpoints),
Middleware: []server.Middleware{
logger.(server.Middleware),
auth.(server.Middleware),
},
},
},
}.New()
if err != nil {
Expand All @@ -105,7 +129,7 @@ func main() {
}

// Run until we receive an interrupt
provider := provider.NewProvider(logger, n, jar, auth, router, httpserver)
provider := provider.NewProvider(logger, n, jar, auth, certstore, certmanager, router, httpserver)
provider.Print(ctx, "Press CTRL+C to exit")
if err := provider.Run(ctx); err != nil {
log.Fatal(err)
Expand Down
103 changes: 103 additions & 0 deletions cmd/run/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package main

import (
"errors"
"flag"
"fmt"
"os"
"path/filepath"
"strings"

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

func main() {
var pluginPath string
name := filepath.Base(os.Args[0])
flags := flag.NewFlagSet(name, flag.ContinueOnError)
flags.StringVar(&pluginPath, "plugin", "*.plugin", "Path to plugins")
if err := flags.Parse(os.Args[1:]); err != nil {
os.Exit(1)
}

// If the path is relative, then make it absolute to either the binary path
// or the current working directory
if !filepath.IsAbs(pluginPath) {
if strings.HasPrefix(pluginPath, ".") || strings.HasPrefix(pluginPath, "..") {
if wd, err := os.Getwd(); err == nil {
pluginPath = filepath.Clean(filepath.Join(wd, pluginPath))
}
} else if exec, err := os.Executable(); err == nil {
pluginPath = filepath.Clean(filepath.Join(filepath.Dir(exec), pluginPath))
}
}

// Create a new provider, load plugins
provider, err := provider.New()
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
if err := provider.LoadPluginsForPattern(pluginPath); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}

// Create configurations
var result error
for _, plugin := range []string{"logger", "httpserver", "router", "nginx-handler", "auth-handler", "tokenjar-handler"} {
if _, err := provider.New(plugin); err != nil {
result = errors.Join(result, err)
}
}
if result != nil {
fmt.Fprintln(os.Stderr, result)
os.Exit(1)
}

// TODO: Set parameters from a JSON file
provider.Set("logger.flags", []string{"default", "prefix"})
}

/*
{
"logger": {
"flags": ["default", "prefix"]
},
"nginx": {
"binary": "/usr/local/bin/nginx",
"data": "/var/run/nginx",
"group": "www-data",
},
httpserver": {
"listen": "run/go-server.sock",
"group": "www-data",
"router": "${ router }",
},
"router": {
"services": {
"nginx": {
"service": "${ nginx }",
"middleware": ["logger", "auth"]
},
"auth": {
"service": "${ auth }",
"middleware": ["logger", "auth"]
},
"router": {
"service": "${ router }",
"middleware": ["logger", "auth"]
},
},
"auth": {
"tokenjar": "${ tokenjar }",
"tokenbytes": 16,
"bearer": true,
},
"tokenjar": {
"data": "run",
"writeinterval": "30s",
},
}
*/
5 changes: 5 additions & 0 deletions etc/json/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

# JSON configuration files

Examples of JSON configuration files for the run command. This is not yet
implemented, but will be in the future.
52 changes: 52 additions & 0 deletions etc/json/nginx-proxy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"logger": {
"flags": [
"default",
"prefix"
]
},
"nginx": {
"binary": "/usr/local/bin/nginx",
"data": "/var/run/nginx",
"group": "nginx"
},
"tokenjar": {
"data": "run",
"writeinterval": "30s"
},
"auth": {
"tokenjar": "${ tokenjar }",
"tokenbytes": 16,
"bearer": true
},
"router": {
"services": {
"nginx": {
"service": "${ nginx }",
"middleware": [
"logger",
"auth"
]
},
"auth": {
"service": "${ auth }",
"middleware": [
"logger",
"auth"
]
},
"router": {
"service": "${ router }",
"middleware": [
"logger",
"auth"
]
}
}
},
"httpserver": {
"listen": "run/go-server.sock",
"group": "nginx",
"router": "${ router }"
}
}
14 changes: 4 additions & 10 deletions pkg/handler/auth/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,19 @@ func (middleware *auth) Wrap(ctx context.Context, next http.HandlerFunc) http.Ha

// Get token from the jar - check it is found and valid
token := middleware.jar.GetWithValue(tokenValue)
authorized := true
if token.IsZero() {
authorized = false
httpresponse.Error(w, http.StatusUnauthorized, "invalid or missing token")
return
} else if !token.IsValid() {
authorized = false
httpresponse.Error(w, http.StatusUnauthorized, "invalid or missing token")
httpresponse.Error(w, http.StatusUnauthorized, "invalid token")
return
} 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, "required scope "+strings.Join(allowedScopes, ", "))
return
}

Expand Down
Loading

0 comments on commit e9c0269

Please sign in to comment.