mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2026-02-25 10:22:00 +00:00
Compare commits
3 Commits
refactor/r
...
fix/sessio
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
acc3ad97cd | ||
|
|
5409aa5f7f | ||
|
|
ebcf6e6aa6 |
7
.github/workflows/ci.yml
vendored
7
.github/workflows/ci.yml
vendored
@@ -39,9 +39,4 @@ jobs:
|
|||||||
cp -r frontend/dist internal/assets/dist
|
cp -r frontend/dist internal/assets/dist
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: go test -coverprofile=coverage.txt -v ./...
|
run: go test -v ./...
|
||||||
|
|
||||||
- name: Upload coverage reports to Codecov
|
|
||||||
uses: codecov/codecov-action@v5
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
|
||||||
|
|||||||
28
cmd/root.go
28
cmd/root.go
@@ -8,13 +8,13 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
totpCmd "tinyauth/cmd/totp"
|
totpCmd "tinyauth/cmd/totp"
|
||||||
userCmd "tinyauth/cmd/user"
|
userCmd "tinyauth/cmd/user"
|
||||||
|
"tinyauth/internal/api"
|
||||||
"tinyauth/internal/auth"
|
"tinyauth/internal/auth"
|
||||||
"tinyauth/internal/constants"
|
"tinyauth/internal/constants"
|
||||||
"tinyauth/internal/docker"
|
"tinyauth/internal/docker"
|
||||||
"tinyauth/internal/handlers"
|
"tinyauth/internal/handlers"
|
||||||
"tinyauth/internal/hooks"
|
"tinyauth/internal/hooks"
|
||||||
"tinyauth/internal/providers"
|
"tinyauth/internal/providers"
|
||||||
"tinyauth/internal/server"
|
|
||||||
"tinyauth/internal/types"
|
"tinyauth/internal/types"
|
||||||
"tinyauth/internal/utils"
|
"tinyauth/internal/utils"
|
||||||
|
|
||||||
@@ -114,8 +114,8 @@ var rootCmd = &cobra.Command{
|
|||||||
RedirectCookieName: redirectCookieName,
|
RedirectCookieName: redirectCookieName,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create server config
|
// Create api config
|
||||||
serverConfig := types.ServerConfig{
|
apiConfig := types.APIConfig{
|
||||||
Port: config.Port,
|
Port: config.Port,
|
||||||
Address: config.Address,
|
Address: config.Address,
|
||||||
}
|
}
|
||||||
@@ -140,7 +140,10 @@ var rootCmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create docker service
|
// Create docker service
|
||||||
docker, err := docker.NewDocker()
|
docker := docker.NewDocker()
|
||||||
|
|
||||||
|
// Initialize docker
|
||||||
|
err = docker.Init()
|
||||||
HandleError(err, "Failed to initialize docker")
|
HandleError(err, "Failed to initialize docker")
|
||||||
|
|
||||||
// Create auth service
|
// Create auth service
|
||||||
@@ -149,19 +152,24 @@ var rootCmd = &cobra.Command{
|
|||||||
// Create OAuth providers service
|
// Create OAuth providers service
|
||||||
providers := providers.NewProviders(oauthConfig)
|
providers := providers.NewProviders(oauthConfig)
|
||||||
|
|
||||||
|
// Initialize providers
|
||||||
|
providers.Init()
|
||||||
|
|
||||||
// Create hooks service
|
// Create hooks service
|
||||||
hooks := hooks.NewHooks(hooksConfig, auth, providers)
|
hooks := hooks.NewHooks(hooksConfig, auth, providers)
|
||||||
|
|
||||||
// Create handlers
|
// Create handlers
|
||||||
handlers := handlers.NewHandlers(handlersConfig, auth, hooks, providers, docker)
|
handlers := handlers.NewHandlers(handlersConfig, auth, hooks, providers, docker)
|
||||||
|
|
||||||
// Create server
|
// Create API
|
||||||
srv, err := server.NewServer(serverConfig, handlers)
|
api := api.NewAPI(apiConfig, handlers)
|
||||||
HandleError(err, "Failed to create server")
|
|
||||||
|
|
||||||
// Start server
|
// Setup routes
|
||||||
err = srv.Start()
|
api.Init()
|
||||||
HandleError(err, "Failed to start server")
|
api.SetupRoutes()
|
||||||
|
|
||||||
|
// Start
|
||||||
|
api.Run()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package server
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -15,13 +15,20 @@ import (
|
|||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Server struct {
|
func NewAPI(config types.APIConfig, handlers *handlers.Handlers) *API {
|
||||||
Config types.ServerConfig
|
return &API{
|
||||||
Handlers *handlers.Handlers
|
Config: config,
|
||||||
Router *gin.Engine
|
Handlers: handlers,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServer(config types.ServerConfig, handlers *handlers.Handlers) (*Server, error) {
|
type API struct {
|
||||||
|
Config types.APIConfig
|
||||||
|
Router *gin.Engine
|
||||||
|
Handlers *handlers.Handlers
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *API) Init() {
|
||||||
// Disable gin logs
|
// Disable gin logs
|
||||||
gin.SetMode(gin.ReleaseMode)
|
gin.SetMode(gin.ReleaseMode)
|
||||||
|
|
||||||
@@ -35,7 +42,7 @@ func NewServer(config types.ServerConfig, handlers *handlers.Handlers) (*Server,
|
|||||||
dist, err := fs.Sub(assets.Assets, "dist")
|
dist, err := fs.Sub(assets.Assets, "dist")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
log.Fatal().Err(err).Msg("Failed to get UI assets")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create file server
|
// Create file server
|
||||||
@@ -62,38 +69,41 @@ func NewServer(config types.ServerConfig, handlers *handlers.Handlers) (*Server,
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Proxy routes
|
// Set router
|
||||||
router.GET("/api/auth/:proxy", handlers.AuthHandler)
|
api.Router = router
|
||||||
|
|
||||||
// Auth routes
|
|
||||||
router.POST("/api/login", handlers.LoginHandler)
|
|
||||||
router.POST("/api/totp", handlers.TotpHandler)
|
|
||||||
router.POST("/api/logout", handlers.LogoutHandler)
|
|
||||||
|
|
||||||
// Context routes
|
|
||||||
router.GET("/api/app", handlers.AppHandler)
|
|
||||||
router.GET("/api/user", handlers.UserHandler)
|
|
||||||
|
|
||||||
// OAuth routes
|
|
||||||
router.GET("/api/oauth/url/:provider", handlers.OauthUrlHandler)
|
|
||||||
router.GET("/api/oauth/callback/:provider", handlers.OauthCallbackHandler)
|
|
||||||
|
|
||||||
// App routes
|
|
||||||
router.GET("/api/healthcheck", handlers.HealthcheckHandler)
|
|
||||||
|
|
||||||
// Return the server
|
|
||||||
return &Server{
|
|
||||||
Config: config,
|
|
||||||
Handlers: handlers,
|
|
||||||
Router: router,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Start() error {
|
func (api *API) SetupRoutes() {
|
||||||
// Run server
|
// Proxy
|
||||||
log.Info().Str("address", s.Config.Address).Int("port", s.Config.Port).Msg("Starting server")
|
api.Router.GET("/api/auth/:proxy", api.Handlers.AuthHandler)
|
||||||
|
|
||||||
return s.Router.Run(fmt.Sprintf("%s:%d", s.Config.Address, s.Config.Port))
|
// Auth
|
||||||
|
api.Router.POST("/api/login", api.Handlers.LoginHandler)
|
||||||
|
api.Router.POST("/api/totp", api.Handlers.TotpHandler)
|
||||||
|
api.Router.POST("/api/logout", api.Handlers.LogoutHandler)
|
||||||
|
|
||||||
|
// Context
|
||||||
|
api.Router.GET("/api/app", api.Handlers.AppHandler)
|
||||||
|
api.Router.GET("/api/user", api.Handlers.UserHandler)
|
||||||
|
|
||||||
|
// OAuth
|
||||||
|
api.Router.GET("/api/oauth/url/:provider", api.Handlers.OauthUrlHandler)
|
||||||
|
api.Router.GET("/api/oauth/callback/:provider", api.Handlers.OauthCallbackHandler)
|
||||||
|
|
||||||
|
// App
|
||||||
|
api.Router.GET("/api/healthcheck", api.Handlers.HealthcheckHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *API) Run() {
|
||||||
|
log.Info().Str("address", api.Config.Address).Int("port", api.Config.Port).Msg("Starting server")
|
||||||
|
|
||||||
|
// Run server
|
||||||
|
err := api.Router.Run(fmt.Sprintf("%s:%d", api.Config.Address, api.Config.Port))
|
||||||
|
|
||||||
|
// Check for errors
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal().Err(err).Msg("Failed to start server")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// zerolog is a middleware for gin that logs requests using zerolog
|
// zerolog is a middleware for gin that logs requests using zerolog
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package server_test
|
package api_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@@ -8,19 +8,19 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"tinyauth/internal/api"
|
||||||
"tinyauth/internal/auth"
|
"tinyauth/internal/auth"
|
||||||
"tinyauth/internal/docker"
|
"tinyauth/internal/docker"
|
||||||
"tinyauth/internal/handlers"
|
"tinyauth/internal/handlers"
|
||||||
"tinyauth/internal/hooks"
|
"tinyauth/internal/hooks"
|
||||||
"tinyauth/internal/providers"
|
"tinyauth/internal/providers"
|
||||||
"tinyauth/internal/server"
|
|
||||||
"tinyauth/internal/types"
|
"tinyauth/internal/types"
|
||||||
|
|
||||||
"github.com/magiconair/properties/assert"
|
"github.com/magiconair/properties/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Simple server config for tests
|
// Simple API config for tests
|
||||||
var serverConfig = types.ServerConfig{
|
var apiConfig = types.APIConfig{
|
||||||
Port: 8080,
|
Port: 8080,
|
||||||
Address: "0.0.0.0",
|
Address: "0.0.0.0",
|
||||||
}
|
}
|
||||||
@@ -68,11 +68,15 @@ var user = types.User{
|
|||||||
Password: "$2a$10$AvGHLTYv3xiRJ0xV9xs3XeVIlkGTygI9nqIamFYB5Xu.5.0UWF7B6", // pass
|
Password: "$2a$10$AvGHLTYv3xiRJ0xV9xs3XeVIlkGTygI9nqIamFYB5Xu.5.0UWF7B6", // pass
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need all this to be able to test the server
|
// We need all this to be able to test the API
|
||||||
func getServer(t *testing.T) *server.Server {
|
func getAPI(t *testing.T) *api.API {
|
||||||
// Create docker service
|
// Create docker service
|
||||||
docker, err := docker.NewDocker()
|
docker := docker.NewDocker()
|
||||||
|
|
||||||
|
// Initialize docker
|
||||||
|
err := docker.Init()
|
||||||
|
|
||||||
|
// Check if there was an error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to initialize docker: %v", err)
|
t.Fatalf("Failed to initialize docker: %v", err)
|
||||||
}
|
}
|
||||||
@@ -89,29 +93,31 @@ func getServer(t *testing.T) *server.Server {
|
|||||||
// Create providers service
|
// Create providers service
|
||||||
providers := providers.NewProviders(types.OAuthConfig{})
|
providers := providers.NewProviders(types.OAuthConfig{})
|
||||||
|
|
||||||
|
// Initialize providers
|
||||||
|
providers.Init()
|
||||||
|
|
||||||
// Create hooks service
|
// Create hooks service
|
||||||
hooks := hooks.NewHooks(hooksConfig, auth, providers)
|
hooks := hooks.NewHooks(hooksConfig, auth, providers)
|
||||||
|
|
||||||
// Create handlers service
|
// Create handlers service
|
||||||
handlers := handlers.NewHandlers(handlersConfig, auth, hooks, providers, docker)
|
handlers := handlers.NewHandlers(handlersConfig, auth, hooks, providers, docker)
|
||||||
|
|
||||||
// Create server
|
// Create API
|
||||||
srv, err := server.NewServer(serverConfig, handlers)
|
api := api.NewAPI(apiConfig, handlers)
|
||||||
|
|
||||||
if err != nil {
|
// Setup routes
|
||||||
t.Fatalf("Failed to create server: %v", err)
|
api.Init()
|
||||||
|
api.SetupRoutes()
|
||||||
|
|
||||||
|
return api
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the server
|
// Test login (we will need this for the other tests)
|
||||||
return srv
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test login
|
|
||||||
func TestLogin(t *testing.T) {
|
func TestLogin(t *testing.T) {
|
||||||
t.Log("Testing login")
|
t.Log("Testing login")
|
||||||
|
|
||||||
// Get server
|
// Get API
|
||||||
api := getServer(t)
|
api := getAPI(t)
|
||||||
|
|
||||||
// Create recorder
|
// Create recorder
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
@@ -156,8 +162,8 @@ func TestLogin(t *testing.T) {
|
|||||||
func TestAppContext(t *testing.T) {
|
func TestAppContext(t *testing.T) {
|
||||||
t.Log("Testing app context")
|
t.Log("Testing app context")
|
||||||
|
|
||||||
// Get server
|
// Get API
|
||||||
api := getServer(t)
|
api := getAPI(t)
|
||||||
|
|
||||||
// Create recorder
|
// Create recorder
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
@@ -224,8 +230,8 @@ func TestAppContext(t *testing.T) {
|
|||||||
func TestUserContext(t *testing.T) {
|
func TestUserContext(t *testing.T) {
|
||||||
t.Log("Testing user context")
|
t.Log("Testing user context")
|
||||||
|
|
||||||
// Get server
|
// Get API
|
||||||
api := getServer(t)
|
api := getAPI(t)
|
||||||
|
|
||||||
// Create recorder
|
// Create recorder
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
@@ -282,8 +288,8 @@ func TestUserContext(t *testing.T) {
|
|||||||
func TestLogout(t *testing.T) {
|
func TestLogout(t *testing.T) {
|
||||||
t.Log("Testing logout")
|
t.Log("Testing logout")
|
||||||
|
|
||||||
// Get server
|
// Get API
|
||||||
api := getServer(t)
|
api := getAPI(t)
|
||||||
|
|
||||||
// Create recorder
|
// Create recorder
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
@@ -313,3 +319,5 @@ func TestLogout(t *testing.T) {
|
|||||||
t.Fatalf("Cookie not flushed")
|
t.Fatalf("Cookie not flushed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Testing for the oauth stuff
|
||||||
@@ -16,38 +16,36 @@ import (
|
|||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func NewAuth(config types.AuthConfig, docker *docker.Docker) *Auth {
|
||||||
|
return &Auth{
|
||||||
|
Config: config,
|
||||||
|
Docker: docker,
|
||||||
|
LoginAttempts: make(map[string]*types.LoginAttempt),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type Auth struct {
|
type Auth struct {
|
||||||
Config types.AuthConfig
|
Config types.AuthConfig
|
||||||
Docker *docker.Docker
|
Docker *docker.Docker
|
||||||
LoginAttempts map[string]*types.LoginAttempt
|
LoginAttempts map[string]*types.LoginAttempt
|
||||||
LoginMutex sync.RWMutex
|
LoginMutex sync.RWMutex
|
||||||
Store *sessions.CookieStore
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAuth(config types.AuthConfig, docker *docker.Docker) *Auth {
|
func (auth *Auth) GetSession(c *gin.Context) (*sessions.Session, error) {
|
||||||
// Create cookie store
|
// Create cookie store
|
||||||
store := sessions.NewCookieStore([]byte(config.HMACSecret), []byte(config.EncryptionSecret))
|
store := sessions.NewCookieStore([]byte(auth.Config.HMACSecret), []byte(auth.Config.EncryptionSecret))
|
||||||
|
|
||||||
// Configure cookie store
|
// Configure cookie store
|
||||||
store.Options = &sessions.Options{
|
store.Options = &sessions.Options{
|
||||||
Path: "/",
|
Path: "/",
|
||||||
MaxAge: config.SessionExpiry,
|
MaxAge: auth.Config.SessionExpiry,
|
||||||
Secure: config.CookieSecure,
|
Secure: auth.Config.CookieSecure,
|
||||||
HttpOnly: true,
|
HttpOnly: true,
|
||||||
Domain: fmt.Sprintf(".%s", config.Domain),
|
Domain: fmt.Sprintf(".%s", auth.Config.Domain),
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Auth{
|
|
||||||
Config: config,
|
|
||||||
Docker: docker,
|
|
||||||
LoginAttempts: make(map[string]*types.LoginAttempt),
|
|
||||||
Store: store,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (auth *Auth) GetSession(c *gin.Context) (*sessions.Session, error) {
|
|
||||||
// Get session
|
// Get session
|
||||||
session, err := auth.Store.Get(c.Request, auth.Config.SessionCookieName)
|
session, err := store.Get(c.Request, auth.Config.SessionCookieName)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn().Err(err).Msg("Invalid session, clearing cookie and retrying")
|
log.Warn().Err(err).Msg("Invalid session, clearing cookie and retrying")
|
||||||
@@ -56,7 +54,7 @@ func (auth *Auth) GetSession(c *gin.Context) (*sessions.Session, error) {
|
|||||||
c.SetCookie(auth.Config.SessionCookieName, "", -1, "/", fmt.Sprintf(".%s", auth.Config.Domain), auth.Config.CookieSecure, true)
|
c.SetCookie(auth.Config.SessionCookieName, "", -1, "/", fmt.Sprintf(".%s", auth.Config.Domain), auth.Config.CookieSecure, true)
|
||||||
|
|
||||||
// Try to get the session again
|
// Try to get the session again
|
||||||
session, err = auth.Store.Get(c.Request, auth.Config.SessionCookieName)
|
session, err = store.Get(c.Request, auth.Config.SessionCookieName)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If we still can't get the session, log the error and return nil
|
// If we still can't get the session, log the error and return nil
|
||||||
|
|||||||
@@ -11,30 +11,35 @@ import (
|
|||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func NewDocker() *Docker {
|
||||||
|
return &Docker{}
|
||||||
|
}
|
||||||
|
|
||||||
type Docker struct {
|
type Docker struct {
|
||||||
Client *client.Client
|
Client *client.Client
|
||||||
Context context.Context
|
Context context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDocker() (*Docker, error) {
|
func (docker *Docker) Init() error {
|
||||||
// Create a new docker client
|
// Create a new docker client
|
||||||
client, err := client.NewClientWithOpts(client.FromEnv)
|
client, err := client.NewClientWithOpts(client.FromEnv)
|
||||||
|
|
||||||
// Check if there was an error
|
// Check if there was an error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the context
|
// Create the context
|
||||||
ctx := context.Background()
|
docker.Context = context.Background()
|
||||||
|
|
||||||
// Negotiate API version
|
// Negotiate API version
|
||||||
client.NegotiateAPIVersion(ctx)
|
client.NegotiateAPIVersion(docker.Context)
|
||||||
|
|
||||||
return &Docker{
|
// Set client
|
||||||
Client: client,
|
docker.Client = client
|
||||||
Context: ctx,
|
|
||||||
}, nil
|
// Done
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (docker *Docker) GetContainers() ([]container.Summary, error) {
|
func (docker *Docker) GetContainers() ([]container.Summary, error) {
|
||||||
|
|||||||
@@ -18,14 +18,6 @@ import (
|
|||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Handlers struct {
|
|
||||||
Config types.HandlersConfig
|
|
||||||
Auth *auth.Auth
|
|
||||||
Hooks *hooks.Hooks
|
|
||||||
Providers *providers.Providers
|
|
||||||
Docker *docker.Docker
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewHandlers(config types.HandlersConfig, auth *auth.Auth, hooks *hooks.Hooks, providers *providers.Providers, docker *docker.Docker) *Handlers {
|
func NewHandlers(config types.HandlersConfig, auth *auth.Auth, hooks *hooks.Hooks, providers *providers.Providers, docker *docker.Docker) *Handlers {
|
||||||
return &Handlers{
|
return &Handlers{
|
||||||
Config: config,
|
Config: config,
|
||||||
@@ -36,6 +28,14 @@ func NewHandlers(config types.HandlersConfig, auth *auth.Auth, hooks *hooks.Hook
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Handlers struct {
|
||||||
|
Config types.HandlersConfig
|
||||||
|
Auth *auth.Auth
|
||||||
|
Hooks *hooks.Hooks
|
||||||
|
Providers *providers.Providers
|
||||||
|
Docker *docker.Docker
|
||||||
|
}
|
||||||
|
|
||||||
func (h *Handlers) AuthHandler(c *gin.Context) {
|
func (h *Handlers) AuthHandler(c *gin.Context) {
|
||||||
// Create struct for proxy
|
// Create struct for proxy
|
||||||
var proxy types.Proxy
|
var proxy types.Proxy
|
||||||
|
|||||||
@@ -12,12 +12,6 @@ import (
|
|||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Hooks struct {
|
|
||||||
Config types.HooksConfig
|
|
||||||
Auth *auth.Auth
|
|
||||||
Providers *providers.Providers
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewHooks(config types.HooksConfig, auth *auth.Auth, providers *providers.Providers) *Hooks {
|
func NewHooks(config types.HooksConfig, auth *auth.Auth, providers *providers.Providers) *Hooks {
|
||||||
return &Hooks{
|
return &Hooks{
|
||||||
Config: config,
|
Config: config,
|
||||||
@@ -26,6 +20,12 @@ func NewHooks(config types.HooksConfig, auth *auth.Auth, providers *providers.Pr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Hooks struct {
|
||||||
|
Config types.HooksConfig
|
||||||
|
Auth *auth.Auth
|
||||||
|
Providers *providers.Providers
|
||||||
|
}
|
||||||
|
|
||||||
func (hooks *Hooks) UseUserContext(c *gin.Context) types.UserContext {
|
func (hooks *Hooks) UseUserContext(c *gin.Context) types.UserContext {
|
||||||
// Get session cookie and basic auth
|
// Get session cookie and basic auth
|
||||||
cookie, err := hooks.Auth.GetSessionCookie(c)
|
cookie, err := hooks.Auth.GetSessionCookie(c)
|
||||||
|
|||||||
@@ -10,24 +10,32 @@ import (
|
|||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func NewOAuth(config oauth2.Config, insecureSkipVerify bool) *OAuth {
|
||||||
|
return &OAuth{
|
||||||
|
Config: config,
|
||||||
|
InsecureSkipVerify: insecureSkipVerify,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type OAuth struct {
|
type OAuth struct {
|
||||||
Config oauth2.Config
|
Config oauth2.Config
|
||||||
Context context.Context
|
Context context.Context
|
||||||
Token *oauth2.Token
|
Token *oauth2.Token
|
||||||
Verifier string
|
Verifier string
|
||||||
|
InsecureSkipVerify bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOAuth(config oauth2.Config, insecureSkipVerify bool) *OAuth {
|
func (oauth *OAuth) Init() {
|
||||||
// Create transport with TLS
|
// Create transport with TLS
|
||||||
transport := &http.Transport{
|
transport := &http.Transport{
|
||||||
TLSClientConfig: &tls.Config{
|
TLSClientConfig: &tls.Config{
|
||||||
InsecureSkipVerify: insecureSkipVerify,
|
InsecureSkipVerify: oauth.InsecureSkipVerify,
|
||||||
MinVersion: tls.VersionTLS12,
|
MinVersion: tls.VersionTLS12,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new context
|
// Create a new context
|
||||||
ctx := context.Background()
|
oauth.Context = context.Background()
|
||||||
|
|
||||||
// Create the HTTP client with the transport
|
// Create the HTTP client with the transport
|
||||||
httpClient := &http.Client{
|
httpClient := &http.Client{
|
||||||
@@ -35,16 +43,9 @@ func NewOAuth(config oauth2.Config, insecureSkipVerify bool) *OAuth {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the HTTP client in the context
|
// Set the HTTP client in the context
|
||||||
ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient)
|
oauth.Context = context.WithValue(oauth.Context, oauth2.HTTPClient, httpClient)
|
||||||
|
|
||||||
// Create the verifier
|
// Create the verifier
|
||||||
verifier := oauth2.GenerateVerifier()
|
oauth.Verifier = oauth2.GenerateVerifier()
|
||||||
|
|
||||||
return &OAuth{
|
|
||||||
Config: config,
|
|
||||||
Context: ctx,
|
|
||||||
Verifier: verifier,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (oauth *OAuth) GetAuthURL(state string) string {
|
func (oauth *OAuth) GetAuthURL(state string) string {
|
||||||
|
|||||||
@@ -11,6 +11,12 @@ import (
|
|||||||
"golang.org/x/oauth2/endpoints"
|
"golang.org/x/oauth2/endpoints"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func NewProviders(config types.OAuthConfig) *Providers {
|
||||||
|
return &Providers{
|
||||||
|
Config: config,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type Providers struct {
|
type Providers struct {
|
||||||
Config types.OAuthConfig
|
Config types.OAuthConfig
|
||||||
Github *oauth.OAuth
|
Github *oauth.OAuth
|
||||||
@@ -18,57 +24,60 @@ type Providers struct {
|
|||||||
Generic *oauth.OAuth
|
Generic *oauth.OAuth
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProviders(config types.OAuthConfig) *Providers {
|
func (providers *Providers) Init() {
|
||||||
providers := &Providers{
|
|
||||||
Config: config,
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we have a client id and secret for github, initialize the oauth provider
|
// If we have a client id and secret for github, initialize the oauth provider
|
||||||
if config.GithubClientId != "" && config.GithubClientSecret != "" {
|
if providers.Config.GithubClientId != "" && providers.Config.GithubClientSecret != "" {
|
||||||
log.Info().Msg("Initializing Github OAuth")
|
log.Info().Msg("Initializing Github OAuth")
|
||||||
|
|
||||||
// Create a new oauth provider with the github config
|
// Create a new oauth provider with the github config
|
||||||
providers.Github = oauth.NewOAuth(oauth2.Config{
|
providers.Github = oauth.NewOAuth(oauth2.Config{
|
||||||
ClientID: config.GithubClientId,
|
ClientID: providers.Config.GithubClientId,
|
||||||
ClientSecret: config.GithubClientSecret,
|
ClientSecret: providers.Config.GithubClientSecret,
|
||||||
RedirectURL: fmt.Sprintf("%s/api/oauth/callback/github", config.AppURL),
|
RedirectURL: fmt.Sprintf("%s/api/oauth/callback/github", providers.Config.AppURL),
|
||||||
Scopes: GithubScopes(),
|
Scopes: GithubScopes(),
|
||||||
Endpoint: endpoints.GitHub,
|
Endpoint: endpoints.GitHub,
|
||||||
}, false)
|
}, false)
|
||||||
|
|
||||||
|
// Initialize the oauth provider
|
||||||
|
providers.Github.Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have a client id and secret for google, initialize the oauth provider
|
// If we have a client id and secret for google, initialize the oauth provider
|
||||||
if config.GoogleClientId != "" && config.GoogleClientSecret != "" {
|
if providers.Config.GoogleClientId != "" && providers.Config.GoogleClientSecret != "" {
|
||||||
log.Info().Msg("Initializing Google OAuth")
|
log.Info().Msg("Initializing Google OAuth")
|
||||||
|
|
||||||
// Create a new oauth provider with the google config
|
// Create a new oauth provider with the google config
|
||||||
providers.Google = oauth.NewOAuth(oauth2.Config{
|
providers.Google = oauth.NewOAuth(oauth2.Config{
|
||||||
ClientID: config.GoogleClientId,
|
ClientID: providers.Config.GoogleClientId,
|
||||||
ClientSecret: config.GoogleClientSecret,
|
ClientSecret: providers.Config.GoogleClientSecret,
|
||||||
RedirectURL: fmt.Sprintf("%s/api/oauth/callback/google", config.AppURL),
|
RedirectURL: fmt.Sprintf("%s/api/oauth/callback/google", providers.Config.AppURL),
|
||||||
Scopes: GoogleScopes(),
|
Scopes: GoogleScopes(),
|
||||||
Endpoint: endpoints.Google,
|
Endpoint: endpoints.Google,
|
||||||
}, false)
|
}, false)
|
||||||
|
|
||||||
|
// Initialize the oauth provider
|
||||||
|
providers.Google.Init()
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have a client id and secret for generic oauth, initialize the oauth provider
|
// If we have a client id and secret for generic oauth, initialize the oauth provider
|
||||||
if config.GenericClientId != "" && config.GenericClientSecret != "" {
|
if providers.Config.GenericClientId != "" && providers.Config.GenericClientSecret != "" {
|
||||||
log.Info().Msg("Initializing Generic OAuth")
|
log.Info().Msg("Initializing Generic OAuth")
|
||||||
|
|
||||||
// Create a new oauth provider with the generic config
|
// Create a new oauth provider with the generic config
|
||||||
providers.Generic = oauth.NewOAuth(oauth2.Config{
|
providers.Generic = oauth.NewOAuth(oauth2.Config{
|
||||||
ClientID: config.GenericClientId,
|
ClientID: providers.Config.GenericClientId,
|
||||||
ClientSecret: config.GenericClientSecret,
|
ClientSecret: providers.Config.GenericClientSecret,
|
||||||
RedirectURL: fmt.Sprintf("%s/api/oauth/callback/generic", config.AppURL),
|
RedirectURL: fmt.Sprintf("%s/api/oauth/callback/generic", providers.Config.AppURL),
|
||||||
Scopes: config.GenericScopes,
|
Scopes: providers.Config.GenericScopes,
|
||||||
Endpoint: oauth2.Endpoint{
|
Endpoint: oauth2.Endpoint{
|
||||||
AuthURL: config.GenericAuthURL,
|
AuthURL: providers.Config.GenericAuthURL,
|
||||||
TokenURL: config.GenericTokenURL,
|
TokenURL: providers.Config.GenericTokenURL,
|
||||||
},
|
},
|
||||||
}, config.GenericSkipSSL)
|
}, providers.Config.GenericSkipSSL)
|
||||||
}
|
|
||||||
|
|
||||||
return providers
|
// Initialize the oauth provider
|
||||||
|
providers.Generic.Init()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (providers *Providers) GetProvider(provider string) *oauth.OAuth {
|
func (providers *Providers) GetProvider(provider string) *oauth.OAuth {
|
||||||
|
|||||||
@@ -69,8 +69,8 @@ type OAuthConfig struct {
|
|||||||
AppURL string
|
AppURL string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerConfig is the configuration for the server
|
// APIConfig is the configuration for the API
|
||||||
type ServerConfig struct {
|
type APIConfig struct {
|
||||||
Port int
|
Port int
|
||||||
Address string
|
Address string
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user