mirror of
https://github.com/1f349/violet.git
synced 2024-11-21 10:51:40 +00:00
Hardcode some file names
This commit is contained in:
parent
7e05271a79
commit
76e37f7af9
@ -1,15 +1,12 @@
|
||||
package main
|
||||
|
||||
type startUpConfig struct {
|
||||
Database string `json:"db"`
|
||||
MjwtPubKey string `json:"mjwt_pub_key"`
|
||||
CertPath string `json:"cert_path"`
|
||||
KeyPath string `json:"key_path"`
|
||||
SelfSigned bool `json:"self_signed"`
|
||||
ErrorPagePath string `json:"error_page_path"`
|
||||
Listen listenConfig `json:"listen"`
|
||||
InkscapeCmd string `json:"inkscape"`
|
||||
RateLimit uint64 `json:"rate_limit"`
|
||||
SignerIssuer string `json:"signer_issuer"`
|
||||
}
|
||||
|
||||
type listenConfig struct {
|
||||
|
@ -18,9 +18,11 @@ import (
|
||||
"github.com/google/subcommands"
|
||||
"io/fs"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
@ -63,26 +65,24 @@ func (s *serveCmd) Execute(ctx context.Context, f *flag.FlagSet, _ ...interface{
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
|
||||
normalLoad(conf)
|
||||
// working directory is the parent of the config file
|
||||
wd := filepath.Dir(s.configPath)
|
||||
normalLoad(conf, wd)
|
||||
return subcommands.ExitSuccess
|
||||
}
|
||||
|
||||
func normalLoad(conf startUpConfig) {
|
||||
func normalLoad(conf startUpConfig, wd string) {
|
||||
// the cert and key paths are useless in self-signed mode
|
||||
if !conf.SelfSigned {
|
||||
if conf.CertPath != "" {
|
||||
// create path to cert dir
|
||||
err := os.MkdirAll(conf.CertPath, os.ModePerm)
|
||||
if err != nil {
|
||||
log.Fatalf("[Violet] Failed to create certificate path '%s'", conf.CertPath)
|
||||
}
|
||||
// create path to cert dir
|
||||
err := os.MkdirAll(filepath.Join(wd, "certs"), os.ModePerm)
|
||||
if err != nil {
|
||||
log.Fatal("[Violet] Failed to create certificate path")
|
||||
}
|
||||
if conf.KeyPath != "" {
|
||||
// create path to key dir
|
||||
err := os.MkdirAll(conf.KeyPath, os.ModePerm)
|
||||
if err != nil {
|
||||
log.Fatalf("[Violet] Failed to create certificate key path '%s'", conf.KeyPath)
|
||||
}
|
||||
// create path to key dir
|
||||
err = os.MkdirAll(filepath.Join(wd, "keys"), os.ModePerm)
|
||||
if err != nil {
|
||||
log.Fatal("[Violet] Failed to create certificate key path")
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,25 +96,28 @@ func normalLoad(conf startUpConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
// load the MJWT RSA public key from a pem encoded file
|
||||
mjwtVerify, err := mjwt.NewMJwtVerifierFromFile(conf.MjwtPubKey)
|
||||
// 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)
|
||||
if err != nil {
|
||||
log.Fatalf("[Violet] Failed to load MJWT verifier public key from file: '%s'", conf.MjwtPubKey)
|
||||
log.Fatal("[Violet] Failed to load MJWT verifier public key from file: ", err)
|
||||
}
|
||||
|
||||
// open sqlite database
|
||||
db, err := sql.Open("sqlite3", conf.Database)
|
||||
db, err := sql.Open("sqlite3", "violet.db.sqlite")
|
||||
if err != nil {
|
||||
log.Fatalf("[Violet] Failed to open database '%s'...", conf.Database)
|
||||
log.Fatal("[Violet] Failed to open database")
|
||||
}
|
||||
|
||||
allowedDomains := domains.New(db) // load allowed domains
|
||||
acmeChallenges := utils.NewAcmeChallenge() // load acme challenge store
|
||||
allowedCerts := certs.New(os.DirFS(conf.CertPath), os.DirFS(conf.KeyPath), conf.SelfSigned) // load certificate manager
|
||||
hybridTransport := proxy.NewHybridTransport() // load reverse proxy
|
||||
dynamicFavicons := favicons.New(db, conf.InkscapeCmd) // load dynamic favicon provider
|
||||
dynamicErrorPages := errorPages.New(errorPageDir) // load dynamic error page provider
|
||||
dynamicRouter := router.NewManager(db, hybridTransport) // load dynamic router manager
|
||||
certDir := os.DirFS(filepath.Join(wd, "certs"))
|
||||
keyDir := os.DirFS(filepath.Join(wd, "keys"))
|
||||
|
||||
allowedDomains := domains.New(db) // load allowed domains
|
||||
acmeChallenges := utils.NewAcmeChallenge() // load acme challenge store
|
||||
allowedCerts := certs.New(certDir, keyDir, conf.SelfSigned) // load certificate manager
|
||||
hybridTransport := proxy.NewHybridTransport() // load reverse proxy
|
||||
dynamicFavicons := favicons.New(db, conf.InkscapeCmd) // load dynamic favicon provider
|
||||
dynamicErrorPages := errorPages.New(errorPageDir) // load dynamic error page provider
|
||||
dynamicRouter := router.NewManager(db, hybridTransport) // load dynamic router manager
|
||||
|
||||
// struct containing config for the http servers
|
||||
srvConf := &servers.Conf{
|
||||
@ -127,7 +130,7 @@ func normalLoad(conf startUpConfig) {
|
||||
Acme: acmeChallenges,
|
||||
Certs: allowedCerts,
|
||||
Favicons: dynamicFavicons,
|
||||
Verify: mjwtVerify,
|
||||
Signer: mjwtSigner,
|
||||
ErrorPages: dynamicErrorPages,
|
||||
Router: dynamicRouter,
|
||||
}
|
||||
|
@ -59,14 +59,15 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{})
|
||||
|
||||
// store answers from questions
|
||||
var answers struct {
|
||||
SelfSigned bool
|
||||
ErrorPages bool
|
||||
ApiListen string
|
||||
HttpListen string
|
||||
HttpsListen string
|
||||
RateLimit uint64
|
||||
FirstDomain string
|
||||
ApiUrl string
|
||||
SelfSigned bool
|
||||
ErrorPages bool
|
||||
ApiListen string
|
||||
HttpListen string
|
||||
HttpsListen string
|
||||
RateLimit uint64
|
||||
FirstDomain string
|
||||
ApiUrl string
|
||||
SignerIssuer string
|
||||
}
|
||||
|
||||
// ask main questions
|
||||
@ -103,6 +104,10 @@ 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"},
|
||||
@ -130,10 +135,6 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{})
|
||||
confEncode := json.NewEncoder(createConf)
|
||||
confEncode.SetIndent("", " ")
|
||||
err = confEncode.Encode(startUpConfig{
|
||||
Database: filepath.Join(wdAbs, "violet.sqlite"),
|
||||
MjwtPubKey: filepath.Join(wdAbs, "mjwt.public.key"),
|
||||
CertPath: filepath.Join(wdAbs, "certs"),
|
||||
KeyPath: filepath.Join(wdAbs, "keys"),
|
||||
SelfSigned: answers.SelfSigned,
|
||||
ErrorPagePath: errorPagePath,
|
||||
Listen: listenConfig{
|
||||
@ -141,8 +142,9 @@ func (s *setupCmd) Execute(_ context.Context, _ *flag.FlagSet, _ ...interface{})
|
||||
Http: answers.HttpListen,
|
||||
Https: answers.HttpsListen,
|
||||
},
|
||||
InkscapeCmd: "inkscape",
|
||||
RateLimit: answers.RateLimit,
|
||||
InkscapeCmd: "inkscape",
|
||||
RateLimit: answers.RateLimit,
|
||||
SignerIssuer: answers.SignerIssuer,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Println("[Violet] Failed to write config file: ", err)
|
||||
|
2
go.mod
2
go.mod
@ -5,7 +5,7 @@ go 1.20
|
||||
require (
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7
|
||||
github.com/MrMelon54/certgen v0.0.1
|
||||
github.com/MrMelon54/mjwt v0.0.2
|
||||
github.com/MrMelon54/mjwt v0.1.1
|
||||
github.com/MrMelon54/png2ico v1.0.1
|
||||
github.com/MrMelon54/rescheduler v0.0.1
|
||||
github.com/MrMelon54/trie v0.0.2
|
||||
|
2
go.sum
2
go.sum
@ -4,6 +4,8 @@ github.com/MrMelon54/certgen v0.0.1 h1:ycWdZ2RlxQ5qSuejeBVv4aXjGo5hdqqL4j4EjrXnF
|
||||
github.com/MrMelon54/certgen v0.0.1/go.mod h1:GHflVlSbtFLJZLpN1oWyUvDBRrR8qCWiwZLXCCnS2Gc=
|
||||
github.com/MrMelon54/mjwt v0.0.2 h1:jDqyPnFloh80XdSmZ6jt9qhUj/ULcoQ4QSHXPdkAIE4=
|
||||
github.com/MrMelon54/mjwt v0.0.2/go.mod h1:HzY8P6Je+ovS/fwK5sILRMq5mnZT4+WuFRc98LBy7z4=
|
||||
github.com/MrMelon54/mjwt v0.1.1 h1:m+aTpxbhQCrOPKHN170DQMFR5r938LkviU38unob5Jw=
|
||||
github.com/MrMelon54/mjwt v0.1.1/go.mod h1:oYrDBWK09Hju98xb+bRQ0wy+RuAzacxYvKYOZchR2Tk=
|
||||
github.com/MrMelon54/png2ico v1.0.1 h1:zJoSSl4OkvSIMWGyGPvb8fWNa0KrUvMIjgNGLNLJhVQ=
|
||||
github.com/MrMelon54/png2ico v1.0.1/go.mod h1:NOv3tO4497mInG+3tcFkIohmxCywUwMLU8WNxJZLVmU=
|
||||
github.com/MrMelon54/rescheduler v0.0.1 h1:gzNvL8X81M00uYN0i9clFVrXCkG1UuLNYxDcvjKyBqo=
|
||||
|
@ -18,7 +18,7 @@ func NewApiServer(conf *Conf, compileTarget utils.MultiCompilable) *http.Server
|
||||
|
||||
// Endpoint for compile action
|
||||
r.POST("/compile", func(rw http.ResponseWriter, req *http.Request, _ httprouter.Params) {
|
||||
if !hasPerms(conf.Verify, req, "violet:compile") {
|
||||
if !hasPerms(conf.Signer, req, "violet:compile") {
|
||||
utils.RespondHttpStatus(rw, http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
@ -30,7 +30,7 @@ func NewApiServer(conf *Conf, compileTarget utils.MultiCompilable) *http.Server
|
||||
|
||||
// Endpoint for domains
|
||||
r.PUT("/domain/:domain", func(rw http.ResponseWriter, req *http.Request, params httprouter.Params) {
|
||||
if !hasPerms(conf.Verify, req, "violet:domains") {
|
||||
if !hasPerms(conf.Signer, req, "violet:domains") {
|
||||
utils.RespondHttpStatus(rw, http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
@ -41,7 +41,7 @@ func NewApiServer(conf *Conf, compileTarget utils.MultiCompilable) *http.Server
|
||||
conf.Domains.Compile()
|
||||
})
|
||||
r.DELETE("/domain/:domain", func(rw http.ResponseWriter, req *http.Request, params httprouter.Params) {
|
||||
if !hasPerms(conf.Verify, req, "violet:domains") {
|
||||
if !hasPerms(conf.Signer, req, "violet:domains") {
|
||||
utils.RespondHttpStatus(rw, http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
@ -59,7 +59,7 @@ func NewApiServer(conf *Conf, compileTarget utils.MultiCompilable) *http.Server
|
||||
|
||||
// Endpoint for acme-challenge
|
||||
r.PUT("/acme-challenge/:domain/:key/:value", func(rw http.ResponseWriter, req *http.Request, params httprouter.Params) {
|
||||
if !hasPerms(conf.Verify, req, "violet:acme-challenge") {
|
||||
if !hasPerms(conf.Signer, req, "violet:acme-challenge") {
|
||||
utils.RespondHttpStatus(rw, http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
@ -72,7 +72,7 @@ func NewApiServer(conf *Conf, compileTarget utils.MultiCompilable) *http.Server
|
||||
rw.WriteHeader(http.StatusAccepted)
|
||||
})
|
||||
r.DELETE("/acme-challenge/:domain/:key", func(rw http.ResponseWriter, req *http.Request, params httprouter.Params) {
|
||||
if !hasPerms(conf.Verify, req, "violet:acme-challenge") {
|
||||
if !hasPerms(conf.Signer, req, "violet:acme-challenge") {
|
||||
utils.RespondHttpStatus(rw, http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
@ -34,10 +34,7 @@ func genSnakeOilProv() mjwt.Signer {
|
||||
func genSnakeOilKey(perm string) string {
|
||||
p := claims.NewPermStorage()
|
||||
p.Set(perm)
|
||||
val, err := snakeOilProv.GenerateJwt("abc", "abc", 5*time.Minute, auth.AccessTokenClaims{
|
||||
UserId: 1,
|
||||
Perms: p,
|
||||
})
|
||||
val, err := snakeOilProv.GenerateJwt("abc", "abc", nil, 5*time.Minute, auth.AccessTokenClaims{Perms: p})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -54,7 +51,7 @@ func TestNewApiServer_Compile(t *testing.T) {
|
||||
apiConf := &Conf{
|
||||
Domains: &fakeDomains{},
|
||||
Acme: utils.NewAcmeChallenge(),
|
||||
Verify: snakeOilProv,
|
||||
Signer: snakeOilProv,
|
||||
}
|
||||
f := &fakeCompilable{}
|
||||
srv := NewApiServer(apiConf, utils.MultiCompilable{f})
|
||||
@ -81,7 +78,7 @@ func TestNewApiServer_AcmeChallenge_Put(t *testing.T) {
|
||||
apiConf := &Conf{
|
||||
Domains: &fakeDomains{},
|
||||
Acme: utils.NewAcmeChallenge(),
|
||||
Verify: snakeOilProv,
|
||||
Signer: snakeOilProv,
|
||||
}
|
||||
srv := NewApiServer(apiConf, utils.MultiCompilable{})
|
||||
acmeKey := genSnakeOilKey("violet:acme-challenge")
|
||||
@ -125,7 +122,7 @@ func TestNewApiServer_AcmeChallenge_Delete(t *testing.T) {
|
||||
apiConf := &Conf{
|
||||
Domains: &fakeDomains{},
|
||||
Acme: utils.NewAcmeChallenge(),
|
||||
Verify: snakeOilProv,
|
||||
Signer: snakeOilProv,
|
||||
}
|
||||
srv := NewApiServer(apiConf, utils.MultiCompilable{})
|
||||
acmeKey := genSnakeOilKey("violet:acme-challenge")
|
||||
|
@ -20,7 +20,7 @@ type Conf struct {
|
||||
Acme AcmeChallengeProvider
|
||||
Certs CertProvider
|
||||
Favicons *favicons.Favicons
|
||||
Verify mjwt.Verifier
|
||||
Signer mjwt.Verifier
|
||||
ErrorPages *errorPages.ErrorPages
|
||||
Router *router.Manager
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ func TestNewHttpServer_AcmeChallenge(t *testing.T) {
|
||||
httpConf := &Conf{
|
||||
Domains: &fakeDomains{},
|
||||
Acme: utils.NewAcmeChallenge(),
|
||||
Verify: snakeOilProv,
|
||||
Signer: snakeOilProv,
|
||||
}
|
||||
srv := NewHttpServer(httpConf)
|
||||
httpConf.Acme.Put("example.com", "456", "456def")
|
||||
|
@ -30,7 +30,7 @@ func TestNewHttpsServer_RateLimit(t *testing.T) {
|
||||
RateLimit: 5,
|
||||
Domains: &fakeDomains{},
|
||||
Certs: certs.New(nil, nil, true),
|
||||
Verify: snakeOilProv,
|
||||
Signer: snakeOilProv,
|
||||
Router: router.NewManager(db, proxy.NewHybridTransportWithCalls(ft, ft)),
|
||||
}
|
||||
srv := NewHttpsServer(httpsConf)
|
||||
|
Loading…
Reference in New Issue
Block a user