Just accept a public key to authenticate tokens signed by the token signing service

This commit is contained in:
Melon 2023-07-03 18:47:05 +01:00
parent ab36a39917
commit eb8954f794
Signed by: melon
GPG Key ID: 6C9D970C50D26A25
5 changed files with 16 additions and 103 deletions

View File

@ -6,7 +6,6 @@ type startUpConfig struct {
Listen listenConfig `json:"listen"`
InkscapeCmd string `json:"inkscape"`
RateLimit uint64 `json:"rate_limit"`
SignerIssuer string `json:"signer_issuer"`
}
type listenConfig struct {

View File

@ -15,7 +15,6 @@ func main() {
subcommands.Register(subcommands.CommandsCommand(), "")
subcommands.Register(&serveCmd{}, "")
subcommands.Register(&setupCmd{}, "")
subcommands.Register(&tokenCmd{}, "")
flag.Parse()
ctx := context.Background()

View File

@ -18,7 +18,6 @@ import (
"github.com/google/subcommands"
"io/fs"
"log"
"math/rand"
"net/http"
"os"
"os/signal"
@ -96,14 +95,14 @@ func normalLoad(conf startUpConfig, wd string) {
}
}
// load the MJWT RSA private key from a pem encoded file
mjwtSigner, err := mjwt.NewMJwtSignerFromFileOrCreate(conf.SignerIssuer, filepath.Join(wd, "violet.private.pem"), rand.New(rand.NewSource(time.Now().UnixNano())), 4096)
// load the MJWT RSA public key from a pem encoded file
mJwtVerify, err := mjwt.NewMJwtVerifierFromFile(filepath.Join(wd, "signer.public.pem"))
if err != nil {
log.Fatal("[Violet] Failed to load MJWT verifier public key from file: ", err)
log.Fatalf("[Violet] Failed to load MJWT verifier public key from file '%s': %s", filepath.Join(wd, "signer.public.pem"), err)
}
// open sqlite database
db, err := sql.Open("sqlite3", "violet.db.sqlite")
db, err := sql.Open("sqlite3", filepath.Join(wd, "violet.db.sqlite"))
if err != nil {
log.Fatal("[Violet] Failed to open database")
}
@ -130,7 +129,7 @@ func normalLoad(conf startUpConfig, wd string) {
Acme: acmeChallenges,
Certs: allowedCerts,
Favicons: dynamicFavicons,
Signer: mjwtSigner,
Signer: mJwtVerify,
ErrorPages: dynamicErrorPages,
Router: dynamicRouter,
}

View File

@ -67,7 +67,6 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{})
RateLimit uint64
FirstDomain string
ApiUrl string
SignerIssuer string
}
// ask main questions
@ -104,10 +103,6 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{})
return nil
},
},
{
Name: "SignerIssuer",
Prompt: &survey.Input{Message: "Issuer name to sign API tokens with", Default: "Violet"},
},
{
Name: "FirstDomain",
Prompt: &survey.Input{Message: "First domain", Default: "example.com", Help: "Setup the first domain or it will be more difficult to setup later"},
@ -120,7 +115,7 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{})
}
// generate database path
databaseFile := filepath.Join(wdAbs, "violet.sqlite")
databaseFile := filepath.Join(wdAbs, "violet.db.sqlite")
errorPagePath := ""
if answers.ErrorPages {
errorPagePath = filepath.Join(wdAbs, "error-pages")
@ -144,7 +139,6 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{})
},
InkscapeCmd: "inkscape",
RateLimit: answers.RateLimit,
SignerIssuer: answers.SignerIssuer,
})
if err != nil {
fmt.Println("[Violet] Failed to write config file: ", err)

View File

@ -1,78 +0,0 @@
package main
import (
"context"
"encoding/json"
"flag"
"fmt"
"github.com/MrMelon54/mjwt"
"github.com/google/subcommands"
"github.com/google/uuid"
"os"
"path/filepath"
)
type tokenCmd struct {
configPath string
audience stringSliceFlag
duration string
permission stringSliceFlag
}
func (t *tokenCmd) Name() string { return "auth" }
func (t *tokenCmd) Synopsis() string {
return "Generate an auth token for using the API"
}
func (t *tokenCmd) SetFlags(f *flag.FlagSet) {
f.StringVar(&t.configPath, "conf", "", "/path/to/config.json : path to the config file")
f.Var(&t.audience, "a", "specify the audience attribute, this flag can be used multiple times")
f.StringVar(&t.duration, "d", "15m", "specify the duration attribute (default: 15m)")
f.Var(&t.permission, "p", "specify the permissions granted by this token, this flag can be used multiple times")
}
func (t *tokenCmd) Usage() string {
return `token [-conf <config file>] [-a <audience>] [-d <duration>] [-p <permission>]
Generate an access/refresh token pair for using the API.
`
}
func (t *tokenCmd) Execute(ctx context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus {
err := t.normal()
if err != nil {
fmt.Println("[Violet] Error: ", err)
return subcommands.ExitFailure
}
return subcommands.ExitSuccess
}
func (t *tokenCmd) normal() error {
wd := filepath.Dir(t.configPath)
openConfig, err := os.Open(t.configPath)
if err != nil {
return err
}
var a struct {
SignerIssuer string `json:"signer_issuer"`
}
err = json.NewDecoder(openConfig).Decode(&a)
if err != nil {
return err
}
signer, err := mjwt.NewMJwtSignerFromFile(a.SignerIssuer, filepath.Join(wd, "violet.private.pem"))
if err != nil {
return err
}
signer.GenerateJwt(uuid.NewString())
}
type stringSliceFlag []string
func (a *stringSliceFlag) String() string {
return fmt.Sprintf("%v", *a)
}
func (a *stringSliceFlag) Set(s string) error {
*a = append(*a, s)
return nil
}