remove environment
This commit is contained in:
@@ -6,17 +6,52 @@ import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultAPISessionExpirationDuration = 5 * 60 * time.Second
|
||||
defaultAdminPassword = "admin"
|
||||
defaultAdminUsername = "admin"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrSessionIDCollision = errors.New("sessionId collision")
|
||||
ErrUnauthorized = errors.New("unauthorized")
|
||||
)
|
||||
|
||||
var adminPassword = sync.OnceValue[string](func() string {
|
||||
adminPassword := os.Getenv("API_ADMIN_PASSWORD")
|
||||
if adminPassword == "" {
|
||||
log.Error().Msg("API_ADMIN_PASSWORD env var is empty, set to default")
|
||||
return defaultAdminPassword
|
||||
}
|
||||
return adminPassword
|
||||
})
|
||||
|
||||
var adminUsername = sync.OnceValue[string](func() string {
|
||||
adminUsername := os.Getenv("API_ADMIN_USERNAME")
|
||||
if adminUsername == "" {
|
||||
log.Error().Msg("API_ADMIN_USERNAME env var is empty, set to default")
|
||||
return defaultAdminUsername
|
||||
}
|
||||
return adminUsername
|
||||
})
|
||||
|
||||
var sessionExpirationTime = sync.OnceValue[time.Duration](func() time.Duration {
|
||||
sessionExpirationDuration, err := strconv.Atoi(os.Getenv("API_SESSION_EXPIRATION_DURATION"))
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Dur("default", defaultAPISessionExpirationDuration).Msg("unable to load API_SESSION_EXPIRATION_DURATION, set to default")
|
||||
return defaultAPISessionExpirationDuration
|
||||
}
|
||||
return time.Duration(sessionExpirationDuration)
|
||||
})
|
||||
|
||||
func generateSessionID() (string, error) {
|
||||
sessionID := make([]byte, 32) //nolint
|
||||
if _, err := rand.Read(sessionID); err != nil {
|
||||
@@ -32,7 +67,7 @@ type Session struct {
|
||||
expirationTime time.Time
|
||||
}
|
||||
|
||||
func (s *Session) GenerateCookie() *http.Cookie {
|
||||
func (s *Session) GenerateCookie(isSecure bool) *http.Cookie {
|
||||
s.l.RLock()
|
||||
defer s.l.RUnlock()
|
||||
|
||||
@@ -40,7 +75,7 @@ func (s *Session) GenerateCookie() *http.Cookie {
|
||||
Name: "session_id",
|
||||
Value: s.sessionID,
|
||||
HttpOnly: true,
|
||||
Secure: GetEnv().isSecure,
|
||||
Secure: isSecure,
|
||||
Expires: s.expirationTime,
|
||||
}
|
||||
}
|
||||
@@ -48,6 +83,7 @@ func (s *Session) GenerateCookie() *http.Cookie {
|
||||
type IAuthenticate interface {
|
||||
IsLogged(r *http.Request) bool
|
||||
Authenticate(username, password string) (*Session, error)
|
||||
IsSecure() bool
|
||||
}
|
||||
|
||||
var _ IAuthenticate = (*Authentication)(nil)
|
||||
@@ -59,15 +95,17 @@ type Authentication struct {
|
||||
fnCancel context.CancelFunc
|
||||
|
||||
sessions map[string]*Session
|
||||
isSecure bool
|
||||
}
|
||||
|
||||
func NewAuthentication(ctx context.Context) *Authentication {
|
||||
func NewAuthentication(ctx context.Context, isSecure bool) *Authentication {
|
||||
ctxChild, fnCancel := context.WithCancel(ctx)
|
||||
|
||||
s := &Authentication{
|
||||
ctx: ctxChild,
|
||||
fnCancel: fnCancel,
|
||||
sessions: map[string]*Session{},
|
||||
isSecure: isSecure,
|
||||
}
|
||||
s.purgeWorker()
|
||||
|
||||
@@ -108,6 +146,10 @@ func (a *Authentication) purgeWorker() {
|
||||
}()
|
||||
}
|
||||
|
||||
func (a *Authentication) IsSecure() bool {
|
||||
return a.isSecure
|
||||
}
|
||||
|
||||
func (a *Authentication) Stop() {
|
||||
a.fnCancel()
|
||||
}
|
||||
@@ -117,8 +159,7 @@ func (a *Authentication) Done() <-chan struct{} {
|
||||
}
|
||||
|
||||
func (a *Authentication) Authenticate(username, password string) (*Session, error) {
|
||||
adminUsername, adminPassword := GetEnv().GetCredentials()
|
||||
if username != adminUsername || password != adminPassword {
|
||||
if username != adminUsername() || password != adminPassword() {
|
||||
return nil, ErrUnauthorized
|
||||
}
|
||||
|
||||
@@ -136,7 +177,7 @@ func (a *Authentication) Authenticate(username, password string) (*Session, erro
|
||||
return nil, ErrSessionIDCollision
|
||||
}
|
||||
|
||||
now := time.Now().Add(GetEnv().GetSessionExpirationDuration())
|
||||
now := time.Now().Add(sessionExpirationTime())
|
||||
session := Session{expirationTime: now, sessionID: sessionID}
|
||||
a.sessions[sessionID] = &session
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ func (bs *BookStore) Save(bm *BookMetadata, content io.ReadCloser) error {
|
||||
|
||||
defer content.Close()
|
||||
|
||||
bm.Path = filepath.Join(GetEnv().GetDir(), bm.getFormattedName())
|
||||
bm.Path = filepath.Join(bs.dir, bm.getFormattedName())
|
||||
|
||||
dst, err := os.Create(bm.Path)
|
||||
if err != nil {
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultAPISessionExpirationDuration = 5 * 60 * time.Second
|
||||
defaultPort = 8585
|
||||
defaultMainDir = "./store"
|
||||
)
|
||||
|
||||
var env = sync.OnceValue[environment](newEnv)
|
||||
|
||||
type environment struct {
|
||||
adminUsername string
|
||||
adminPassword string
|
||||
sessionExpirationDuration time.Duration
|
||||
port int
|
||||
isSecure bool
|
||||
storeDir string
|
||||
}
|
||||
|
||||
func (e environment) GetCredentials() (username, password string) {
|
||||
return e.adminUsername, e.adminPassword
|
||||
}
|
||||
|
||||
func (e environment) GetSessionExpirationDuration() time.Duration {
|
||||
return e.sessionExpirationDuration
|
||||
}
|
||||
|
||||
func (e environment) GetPort() int {
|
||||
return e.port
|
||||
}
|
||||
|
||||
func (e environment) IsSecure() bool {
|
||||
return e.isSecure
|
||||
}
|
||||
|
||||
func (e environment) GetDir() string {
|
||||
return e.storeDir
|
||||
}
|
||||
|
||||
func newEnv() environment {
|
||||
env := environment{
|
||||
adminUsername: "test",
|
||||
adminPassword: "test",
|
||||
isSecure: os.Getenv("API_SECURE") == "true",
|
||||
}
|
||||
|
||||
sessionExpirationDuration, err := strconv.Atoi(os.Getenv("API_SESSION_EXPIRATION_DURATION"))
|
||||
env.sessionExpirationDuration = time.Duration(sessionExpirationDuration)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Dur("default", defaultAPISessionExpirationDuration).Msg("unable to load API_SESSION_EXPIRATION_DURATION, set to default")
|
||||
env.sessionExpirationDuration = defaultAPISessionExpirationDuration
|
||||
}
|
||||
|
||||
port, err := strconv.Atoi(os.Getenv("API_PORT"))
|
||||
env.port = port
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Int("default", defaultPort).Msg("unable to load API_PORT, set to default")
|
||||
env.port = defaultPort
|
||||
}
|
||||
|
||||
storeDir := os.Getenv("API_STORE_DIR")
|
||||
if storeDir == "" {
|
||||
storeDir = defaultMainDir
|
||||
}
|
||||
env.storeDir = storeDir
|
||||
|
||||
return env
|
||||
}
|
||||
|
||||
func GetEnv() environment {
|
||||
return env()
|
||||
}
|
||||
Reference in New Issue
Block a user