mirror of
https://github.com/steveiliop56/tinyauth.git
synced 2025-10-28 04:35:40 +00:00
refactor: don't export non-needed fields (#336)
* refactor: don't export non-needed fields * feat: coderabbit suggestions * fix: avoid queries panic
This commit is contained in:
@@ -35,21 +35,21 @@ type AuthServiceConfig struct {
|
||||
}
|
||||
|
||||
type AuthService struct {
|
||||
Config AuthServiceConfig
|
||||
Docker *DockerService
|
||||
LoginAttempts map[string]*LoginAttempt
|
||||
LoginMutex sync.RWMutex
|
||||
LDAP *LdapService
|
||||
Database *gorm.DB
|
||||
config AuthServiceConfig
|
||||
docker *DockerService
|
||||
loginAttempts map[string]*LoginAttempt
|
||||
loginMutex sync.RWMutex
|
||||
ldap *LdapService
|
||||
database *gorm.DB
|
||||
}
|
||||
|
||||
func NewAuthService(config AuthServiceConfig, docker *DockerService, ldap *LdapService, database *gorm.DB) *AuthService {
|
||||
return &AuthService{
|
||||
Config: config,
|
||||
Docker: docker,
|
||||
LoginAttempts: make(map[string]*LoginAttempt),
|
||||
LDAP: ldap,
|
||||
Database: database,
|
||||
config: config,
|
||||
docker: docker,
|
||||
loginAttempts: make(map[string]*LoginAttempt),
|
||||
ldap: ldap,
|
||||
database: database,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,12 +65,14 @@ func (auth *AuthService) SearchUser(username string) config.UserSearch {
|
||||
}
|
||||
}
|
||||
|
||||
if auth.LDAP != nil {
|
||||
userDN, err := auth.LDAP.Search(username)
|
||||
if auth.ldap != nil {
|
||||
userDN, err := auth.ldap.Search(username)
|
||||
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Str("username", username).Msg("Failed to search for user in LDAP")
|
||||
return config.UserSearch{}
|
||||
return config.UserSearch{
|
||||
Type: "error",
|
||||
}
|
||||
}
|
||||
|
||||
return config.UserSearch{
|
||||
@@ -90,14 +92,14 @@ func (auth *AuthService) VerifyUser(search config.UserSearch, password string) b
|
||||
user := auth.GetLocalUser(search.Username)
|
||||
return auth.CheckPassword(user, password)
|
||||
case "ldap":
|
||||
if auth.LDAP != nil {
|
||||
err := auth.LDAP.Bind(search.Username, password)
|
||||
if auth.ldap != nil {
|
||||
err := auth.ldap.Bind(search.Username, password)
|
||||
if err != nil {
|
||||
log.Warn().Err(err).Str("username", search.Username).Msg("Failed to bind to LDAP")
|
||||
return false
|
||||
}
|
||||
|
||||
err = auth.LDAP.Bind(auth.LDAP.Config.BindDN, auth.LDAP.Config.BindPassword)
|
||||
err = auth.ldap.Bind(auth.ldap.Config.BindDN, auth.ldap.Config.BindPassword)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Failed to rebind with service account after user authentication")
|
||||
return false
|
||||
@@ -115,7 +117,7 @@ func (auth *AuthService) VerifyUser(search config.UserSearch, password string) b
|
||||
}
|
||||
|
||||
func (auth *AuthService) GetLocalUser(username string) config.User {
|
||||
for _, user := range auth.Config.Users {
|
||||
for _, user := range auth.config.Users {
|
||||
if user.Username == username {
|
||||
return user
|
||||
}
|
||||
@@ -130,14 +132,14 @@ func (auth *AuthService) CheckPassword(user config.User, password string) bool {
|
||||
}
|
||||
|
||||
func (auth *AuthService) IsAccountLocked(identifier string) (bool, int) {
|
||||
auth.LoginMutex.RLock()
|
||||
defer auth.LoginMutex.RUnlock()
|
||||
auth.loginMutex.RLock()
|
||||
defer auth.loginMutex.RUnlock()
|
||||
|
||||
if auth.Config.LoginMaxRetries <= 0 || auth.Config.LoginTimeout <= 0 {
|
||||
if auth.config.LoginMaxRetries <= 0 || auth.config.LoginTimeout <= 0 {
|
||||
return false, 0
|
||||
}
|
||||
|
||||
attempt, exists := auth.LoginAttempts[identifier]
|
||||
attempt, exists := auth.loginAttempts[identifier]
|
||||
if !exists {
|
||||
return false, 0
|
||||
}
|
||||
@@ -151,17 +153,17 @@ func (auth *AuthService) IsAccountLocked(identifier string) (bool, int) {
|
||||
}
|
||||
|
||||
func (auth *AuthService) RecordLoginAttempt(identifier string, success bool) {
|
||||
if auth.Config.LoginMaxRetries <= 0 || auth.Config.LoginTimeout <= 0 {
|
||||
if auth.config.LoginMaxRetries <= 0 || auth.config.LoginTimeout <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
auth.LoginMutex.Lock()
|
||||
defer auth.LoginMutex.Unlock()
|
||||
auth.loginMutex.Lock()
|
||||
defer auth.loginMutex.Unlock()
|
||||
|
||||
attempt, exists := auth.LoginAttempts[identifier]
|
||||
attempt, exists := auth.loginAttempts[identifier]
|
||||
if !exists {
|
||||
attempt = &LoginAttempt{}
|
||||
auth.LoginAttempts[identifier] = attempt
|
||||
auth.loginAttempts[identifier] = attempt
|
||||
}
|
||||
|
||||
attempt.LastAttempt = time.Now()
|
||||
@@ -174,14 +176,14 @@ func (auth *AuthService) RecordLoginAttempt(identifier string, success bool) {
|
||||
|
||||
attempt.FailedAttempts++
|
||||
|
||||
if attempt.FailedAttempts >= auth.Config.LoginMaxRetries {
|
||||
attempt.LockedUntil = time.Now().Add(time.Duration(auth.Config.LoginTimeout) * time.Second)
|
||||
log.Warn().Str("identifier", identifier).Int("timeout", auth.Config.LoginTimeout).Msg("Account locked due to too many failed login attempts")
|
||||
if attempt.FailedAttempts >= auth.config.LoginMaxRetries {
|
||||
attempt.LockedUntil = time.Now().Add(time.Duration(auth.config.LoginTimeout) * time.Second)
|
||||
log.Warn().Str("identifier", identifier).Int("timeout", auth.config.LoginTimeout).Msg("Account locked due to too many failed login attempts")
|
||||
}
|
||||
}
|
||||
|
||||
func (auth *AuthService) IsEmailWhitelisted(email string) bool {
|
||||
return utils.CheckFilter(auth.Config.OauthWhitelist, email)
|
||||
return utils.CheckFilter(auth.config.OauthWhitelist, email)
|
||||
}
|
||||
|
||||
func (auth *AuthService) CreateSessionCookie(c *gin.Context, data *config.SessionCookie) error {
|
||||
@@ -196,7 +198,7 @@ func (auth *AuthService) CreateSessionCookie(c *gin.Context, data *config.Sessio
|
||||
if data.TotpPending {
|
||||
expiry = 3600
|
||||
} else {
|
||||
expiry = auth.Config.SessionExpiry
|
||||
expiry = auth.config.SessionExpiry
|
||||
}
|
||||
|
||||
session := model.Session{
|
||||
@@ -210,37 +212,37 @@ func (auth *AuthService) CreateSessionCookie(c *gin.Context, data *config.Sessio
|
||||
Expiry: time.Now().Add(time.Duration(expiry) * time.Second).Unix(),
|
||||
}
|
||||
|
||||
err = auth.Database.Create(&session).Error
|
||||
err = auth.database.Create(&session).Error
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.SetCookie(auth.Config.SessionCookieName, session.UUID, expiry, "/", fmt.Sprintf(".%s", auth.Config.RootDomain), auth.Config.SecureCookie, true)
|
||||
c.SetCookie(auth.config.SessionCookieName, session.UUID, expiry, "/", fmt.Sprintf(".%s", auth.config.RootDomain), auth.config.SecureCookie, true)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (auth *AuthService) DeleteSessionCookie(c *gin.Context) error {
|
||||
cookie, err := c.Cookie(auth.Config.SessionCookieName)
|
||||
cookie, err := c.Cookie(auth.config.SessionCookieName)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
res := auth.Database.Unscoped().Where("uuid = ?", cookie).Delete(&model.Session{})
|
||||
res := auth.database.Unscoped().Where("uuid = ?", cookie).Delete(&model.Session{})
|
||||
|
||||
if res.Error != nil {
|
||||
return res.Error
|
||||
}
|
||||
|
||||
c.SetCookie(auth.Config.SessionCookieName, "", -1, "/", fmt.Sprintf(".%s", auth.Config.RootDomain), auth.Config.SecureCookie, true)
|
||||
c.SetCookie(auth.config.SessionCookieName, "", -1, "/", fmt.Sprintf(".%s", auth.config.RootDomain), auth.config.SecureCookie, true)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (auth *AuthService) GetSessionCookie(c *gin.Context) (config.SessionCookie, error) {
|
||||
cookie, err := c.Cookie(auth.Config.SessionCookieName)
|
||||
cookie, err := c.Cookie(auth.config.SessionCookieName)
|
||||
|
||||
if err != nil {
|
||||
return config.SessionCookie{}, err
|
||||
@@ -248,7 +250,7 @@ func (auth *AuthService) GetSessionCookie(c *gin.Context) (config.SessionCookie,
|
||||
|
||||
var session model.Session
|
||||
|
||||
res := auth.Database.Unscoped().Where("uuid = ?", cookie).First(&session)
|
||||
res := auth.database.Unscoped().Where("uuid = ?", cookie).First(&session)
|
||||
|
||||
if res.Error != nil {
|
||||
return config.SessionCookie{}, res.Error
|
||||
@@ -261,7 +263,7 @@ func (auth *AuthService) GetSessionCookie(c *gin.Context) (config.SessionCookie,
|
||||
currentTime := time.Now().Unix()
|
||||
|
||||
if currentTime > session.Expiry {
|
||||
res := auth.Database.Unscoped().Where("uuid = ?", session.UUID).Delete(&model.Session{})
|
||||
res := auth.database.Unscoped().Where("uuid = ?", session.UUID).Delete(&model.Session{})
|
||||
if res.Error != nil {
|
||||
log.Error().Err(res.Error).Msg("Failed to delete expired session")
|
||||
}
|
||||
@@ -280,7 +282,7 @@ func (auth *AuthService) GetSessionCookie(c *gin.Context) (config.SessionCookie,
|
||||
}
|
||||
|
||||
func (auth *AuthService) UserAuthConfigured() bool {
|
||||
return len(auth.Config.Users) > 0 || auth.LDAP != nil
|
||||
return len(auth.config.Users) > 0 || auth.ldap != nil
|
||||
}
|
||||
|
||||
func (auth *AuthService) IsResourceAllowed(c *gin.Context, context config.UserContext, labels config.AppLabels) bool {
|
||||
|
||||
@@ -16,18 +16,18 @@ type DatabaseServiceConfig struct {
|
||||
}
|
||||
|
||||
type DatabaseService struct {
|
||||
Config DatabaseServiceConfig
|
||||
Database *gorm.DB
|
||||
config DatabaseServiceConfig
|
||||
database *gorm.DB
|
||||
}
|
||||
|
||||
func NewDatabaseService(config DatabaseServiceConfig) *DatabaseService {
|
||||
return &DatabaseService{
|
||||
Config: config,
|
||||
config: config,
|
||||
}
|
||||
}
|
||||
|
||||
func (ds *DatabaseService) Init() error {
|
||||
gormDB, err := gorm.Open(sqlite.Open(ds.Config.DatabasePath), &gorm.Config{})
|
||||
gormDB, err := gorm.Open(sqlite.Open(ds.config.DatabasePath), &gorm.Config{})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -47,7 +47,7 @@ func (ds *DatabaseService) Init() error {
|
||||
return err
|
||||
}
|
||||
|
||||
ds.Database = gormDB
|
||||
ds.database = gormDB
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -74,5 +74,5 @@ func (ds *DatabaseService) migrateDatabase(sqlDB *sql.DB) error {
|
||||
}
|
||||
|
||||
func (ds *DatabaseService) GetDatabase() *gorm.DB {
|
||||
return ds.Database
|
||||
return ds.database
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@ import (
|
||||
)
|
||||
|
||||
type DockerService struct {
|
||||
Client *client.Client
|
||||
Context context.Context
|
||||
client *client.Client
|
||||
context context.Context
|
||||
}
|
||||
|
||||
func NewDockerService() *DockerService {
|
||||
@@ -29,13 +29,13 @@ func (docker *DockerService) Init() error {
|
||||
ctx := context.Background()
|
||||
client.NegotiateAPIVersion(ctx)
|
||||
|
||||
docker.Client = client
|
||||
docker.Context = ctx
|
||||
docker.client = client
|
||||
docker.context = ctx
|
||||
return nil
|
||||
}
|
||||
|
||||
func (docker *DockerService) GetContainers() ([]container.Summary, error) {
|
||||
containers, err := docker.Client.ContainerList(docker.Context, container.ListOptions{})
|
||||
containers, err := docker.client.ContainerList(docker.context, container.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -43,7 +43,7 @@ func (docker *DockerService) GetContainers() ([]container.Summary, error) {
|
||||
}
|
||||
|
||||
func (docker *DockerService) InspectContainer(containerId string) (container.InspectResponse, error) {
|
||||
inspect, err := docker.Client.ContainerInspect(docker.Context, containerId)
|
||||
inspect, err := docker.client.ContainerInspect(docker.context, containerId)
|
||||
if err != nil {
|
||||
return container.InspectResponse{}, err
|
||||
}
|
||||
@@ -51,11 +51,11 @@ func (docker *DockerService) InspectContainer(containerId string) (container.Ins
|
||||
}
|
||||
|
||||
func (docker *DockerService) DockerConnected() bool {
|
||||
_, err := docker.Client.Ping(docker.Context)
|
||||
_, err := docker.client.Ping(docker.context)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func (docker *DockerService) GetLabels(app string, domain string) (config.AppLabels, error) {
|
||||
func (docker *DockerService) GetLabels(appDomain string) (config.AppLabels, error) {
|
||||
isConnected := docker.DockerConnected()
|
||||
|
||||
if !isConnected {
|
||||
@@ -68,21 +68,21 @@ func (docker *DockerService) GetLabels(app string, domain string) (config.AppLab
|
||||
return config.AppLabels{}, err
|
||||
}
|
||||
|
||||
for _, container := range containers {
|
||||
inspect, err := docker.InspectContainer(container.ID)
|
||||
for _, ctr := range containers {
|
||||
inspect, err := docker.InspectContainer(ctr.ID)
|
||||
if err != nil {
|
||||
log.Warn().Str("id", container.ID).Err(err).Msg("Error inspecting container, skipping")
|
||||
log.Warn().Str("id", ctr.ID).Err(err).Msg("Error inspecting container, skipping")
|
||||
continue
|
||||
}
|
||||
|
||||
labels, err := utils.GetLabels(inspect.Config.Labels)
|
||||
if err != nil {
|
||||
log.Warn().Str("id", container.ID).Err(err).Msg("Error getting container labels, skipping")
|
||||
log.Warn().Str("id", ctr.ID).Err(err).Msg("Error getting container labels, skipping")
|
||||
continue
|
||||
}
|
||||
|
||||
for appName, appLabels := range labels.Apps {
|
||||
if appLabels.Config.Domain == domain {
|
||||
if appLabels.Config.Domain == appDomain {
|
||||
log.Debug().Str("id", inspect.ID).Msg("Found matching container by domain")
|
||||
return appLabels, nil
|
||||
}
|
||||
|
||||
@@ -16,17 +16,17 @@ import (
|
||||
)
|
||||
|
||||
type GenericOAuthService struct {
|
||||
Config oauth2.Config
|
||||
Context context.Context
|
||||
Token *oauth2.Token
|
||||
Verifier string
|
||||
InsecureSkipVerify bool
|
||||
UserinfoURL string
|
||||
config oauth2.Config
|
||||
context context.Context
|
||||
token *oauth2.Token
|
||||
verifier string
|
||||
insecureSkipVerify bool
|
||||
userinfoUrl string
|
||||
}
|
||||
|
||||
func NewGenericOAuthService(config config.OAuthServiceConfig) *GenericOAuthService {
|
||||
return &GenericOAuthService{
|
||||
Config: oauth2.Config{
|
||||
config: oauth2.Config{
|
||||
ClientID: config.ClientID,
|
||||
ClientSecret: config.ClientSecret,
|
||||
RedirectURL: config.RedirectURL,
|
||||
@@ -36,15 +36,15 @@ func NewGenericOAuthService(config config.OAuthServiceConfig) *GenericOAuthServi
|
||||
TokenURL: config.TokenURL,
|
||||
},
|
||||
},
|
||||
InsecureSkipVerify: config.InsecureSkipVerify,
|
||||
UserinfoURL: config.UserinfoURL,
|
||||
insecureSkipVerify: config.InsecureSkipVerify,
|
||||
userinfoUrl: config.UserinfoURL,
|
||||
}
|
||||
}
|
||||
|
||||
func (generic *GenericOAuthService) Init() error {
|
||||
transport := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{
|
||||
InsecureSkipVerify: generic.InsecureSkipVerify,
|
||||
InsecureSkipVerify: generic.insecureSkipVerify,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
},
|
||||
}
|
||||
@@ -58,8 +58,8 @@ func (generic *GenericOAuthService) Init() error {
|
||||
ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient)
|
||||
verifier := oauth2.GenerateVerifier()
|
||||
|
||||
generic.Context = ctx
|
||||
generic.Verifier = verifier
|
||||
generic.context = ctx
|
||||
generic.verifier = verifier
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -74,26 +74,26 @@ func (generic *GenericOAuthService) GenerateState() string {
|
||||
}
|
||||
|
||||
func (generic *GenericOAuthService) GetAuthURL(state string) string {
|
||||
return generic.Config.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.S256ChallengeOption(generic.Verifier))
|
||||
return generic.config.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.S256ChallengeOption(generic.verifier))
|
||||
}
|
||||
|
||||
func (generic *GenericOAuthService) VerifyCode(code string) error {
|
||||
token, err := generic.Config.Exchange(generic.Context, code, oauth2.VerifierOption(generic.Verifier))
|
||||
token, err := generic.config.Exchange(generic.context, code, oauth2.VerifierOption(generic.verifier))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
generic.Token = token
|
||||
generic.token = token
|
||||
return nil
|
||||
}
|
||||
|
||||
func (generic *GenericOAuthService) Userinfo() (config.Claims, error) {
|
||||
var user config.Claims
|
||||
|
||||
client := generic.Config.Client(generic.Context, generic.Token)
|
||||
client := generic.config.Client(generic.context, generic.token)
|
||||
|
||||
res, err := client.Get(generic.UserinfoURL)
|
||||
res, err := client.Get(generic.userinfoUrl)
|
||||
if err != nil {
|
||||
return user, err
|
||||
}
|
||||
|
||||
@@ -29,15 +29,15 @@ type GithubUserInfoResponse struct {
|
||||
}
|
||||
|
||||
type GithubOAuthService struct {
|
||||
Config oauth2.Config
|
||||
Context context.Context
|
||||
Token *oauth2.Token
|
||||
Verifier string
|
||||
config oauth2.Config
|
||||
context context.Context
|
||||
token *oauth2.Token
|
||||
verifier string
|
||||
}
|
||||
|
||||
func NewGithubOAuthService(config config.OAuthServiceConfig) *GithubOAuthService {
|
||||
return &GithubOAuthService{
|
||||
Config: oauth2.Config{
|
||||
config: oauth2.Config{
|
||||
ClientID: config.ClientID,
|
||||
ClientSecret: config.ClientSecret,
|
||||
RedirectURL: config.RedirectURL,
|
||||
@@ -53,8 +53,8 @@ func (github *GithubOAuthService) Init() error {
|
||||
ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient)
|
||||
verifier := oauth2.GenerateVerifier()
|
||||
|
||||
github.Context = ctx
|
||||
github.Verifier = verifier
|
||||
github.context = ctx
|
||||
github.verifier = verifier
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -69,24 +69,24 @@ func (github *GithubOAuthService) GenerateState() string {
|
||||
}
|
||||
|
||||
func (github *GithubOAuthService) GetAuthURL(state string) string {
|
||||
return github.Config.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.S256ChallengeOption(github.Verifier))
|
||||
return github.config.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.S256ChallengeOption(github.verifier))
|
||||
}
|
||||
|
||||
func (github *GithubOAuthService) VerifyCode(code string) error {
|
||||
token, err := github.Config.Exchange(github.Context, code, oauth2.VerifierOption(github.Verifier))
|
||||
token, err := github.config.Exchange(github.context, code, oauth2.VerifierOption(github.verifier))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
github.Token = token
|
||||
github.token = token
|
||||
return nil
|
||||
}
|
||||
|
||||
func (github *GithubOAuthService) Userinfo() (config.Claims, error) {
|
||||
var user config.Claims
|
||||
|
||||
client := github.Config.Client(github.Context, github.Token)
|
||||
client := github.config.Client(github.context, github.token)
|
||||
|
||||
req, err := http.NewRequest("GET", "https://api.github.com/user", nil)
|
||||
if err != nil {
|
||||
|
||||
@@ -24,15 +24,15 @@ type GoogleUserInfoResponse struct {
|
||||
}
|
||||
|
||||
type GoogleOAuthService struct {
|
||||
Config oauth2.Config
|
||||
Context context.Context
|
||||
Token *oauth2.Token
|
||||
Verifier string
|
||||
config oauth2.Config
|
||||
context context.Context
|
||||
token *oauth2.Token
|
||||
verifier string
|
||||
}
|
||||
|
||||
func NewGoogleOAuthService(config config.OAuthServiceConfig) *GoogleOAuthService {
|
||||
return &GoogleOAuthService{
|
||||
Config: oauth2.Config{
|
||||
config: oauth2.Config{
|
||||
ClientID: config.ClientID,
|
||||
ClientSecret: config.ClientSecret,
|
||||
RedirectURL: config.RedirectURL,
|
||||
@@ -48,8 +48,8 @@ func (google *GoogleOAuthService) Init() error {
|
||||
ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient)
|
||||
verifier := oauth2.GenerateVerifier()
|
||||
|
||||
google.Context = ctx
|
||||
google.Verifier = verifier
|
||||
google.context = ctx
|
||||
google.verifier = verifier
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -64,24 +64,24 @@ func (oauth *GoogleOAuthService) GenerateState() string {
|
||||
}
|
||||
|
||||
func (google *GoogleOAuthService) GetAuthURL(state string) string {
|
||||
return google.Config.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.S256ChallengeOption(google.Verifier))
|
||||
return google.config.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.S256ChallengeOption(google.verifier))
|
||||
}
|
||||
|
||||
func (google *GoogleOAuthService) VerifyCode(code string) error {
|
||||
token, err := google.Config.Exchange(google.Context, code, oauth2.VerifierOption(google.Verifier))
|
||||
token, err := google.config.Exchange(google.context, code, oauth2.VerifierOption(google.verifier))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
google.Token = token
|
||||
google.token = token
|
||||
return nil
|
||||
}
|
||||
|
||||
func (google *GoogleOAuthService) Userinfo() (config.Claims, error) {
|
||||
var user config.Claims
|
||||
|
||||
client := google.Config.Client(google.Context, google.Token)
|
||||
client := google.config.Client(google.context, google.token)
|
||||
|
||||
res, err := client.Get("https://www.googleapis.com/userinfo/v2/me")
|
||||
if err != nil {
|
||||
|
||||
@@ -22,9 +22,9 @@ type LdapServiceConfig struct {
|
||||
}
|
||||
|
||||
type LdapService struct {
|
||||
Config LdapServiceConfig
|
||||
Conn *ldapgo.Conn
|
||||
Mutex sync.RWMutex
|
||||
Config LdapServiceConfig // exported so as the auth service can use it
|
||||
conn *ldapgo.Conn
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
func NewLdapService(config LdapServiceConfig) *LdapService {
|
||||
@@ -57,7 +57,8 @@ func (ldap *LdapService) Init() error {
|
||||
}
|
||||
|
||||
func (ldap *LdapService) connect() (*ldapgo.Conn, error) {
|
||||
ldap.Mutex.Lock()
|
||||
ldap.mutex.Lock()
|
||||
defer ldap.mutex.Unlock()
|
||||
|
||||
conn, err := ldapgo.DialURL(ldap.Config.Address, ldapgo.DialWithTLSConfig(&tls.Config{
|
||||
InsecureSkipVerify: ldap.Config.Insecure,
|
||||
@@ -72,10 +73,8 @@ func (ldap *LdapService) connect() (*ldapgo.Conn, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ldap.Mutex.Unlock()
|
||||
|
||||
// Set and return the connection
|
||||
ldap.Conn = conn
|
||||
ldap.conn = conn
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
@@ -92,12 +91,13 @@ func (ldap *LdapService) Search(username string) (string, error) {
|
||||
nil,
|
||||
)
|
||||
|
||||
ldap.Mutex.Lock()
|
||||
searchResult, err := ldap.Conn.Search(searchRequest)
|
||||
ldap.mutex.Lock()
|
||||
defer ldap.mutex.Unlock()
|
||||
|
||||
searchResult, err := ldap.conn.Search(searchRequest)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
ldap.Mutex.Unlock()
|
||||
|
||||
if len(searchResult.Entries) != 1 {
|
||||
return "", fmt.Errorf("multiple or no entries found for user %s", username)
|
||||
@@ -108,12 +108,12 @@ func (ldap *LdapService) Search(username string) (string, error) {
|
||||
}
|
||||
|
||||
func (ldap *LdapService) Bind(userDN string, password string) error {
|
||||
ldap.Mutex.Lock()
|
||||
err := ldap.Conn.Bind(userDN, password)
|
||||
ldap.mutex.Lock()
|
||||
defer ldap.mutex.Unlock()
|
||||
err := ldap.conn.Bind(userDN, password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ldap.Mutex.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -128,12 +128,12 @@ func (ldap *LdapService) heartbeat() error {
|
||||
nil,
|
||||
)
|
||||
|
||||
ldap.Mutex.Lock()
|
||||
_, err := ldap.Conn.Search(searchRequest)
|
||||
ldap.mutex.Lock()
|
||||
defer ldap.mutex.Unlock()
|
||||
_, err := ldap.conn.Search(searchRequest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ldap.Mutex.Unlock()
|
||||
|
||||
// No error means the connection is alive
|
||||
return nil
|
||||
@@ -149,7 +149,7 @@ func (ldap *LdapService) reconnect() error {
|
||||
exp.Reset()
|
||||
|
||||
operation := func() (*ldapgo.Conn, error) {
|
||||
ldap.Conn.Close()
|
||||
ldap.conn.Close()
|
||||
conn, err := ldap.connect()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"tinyauth/internal/config"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
type OAuthService interface {
|
||||
@@ -16,59 +17,60 @@ type OAuthService interface {
|
||||
}
|
||||
|
||||
type OAuthBrokerService struct {
|
||||
Services map[string]OAuthService
|
||||
Configs map[string]config.OAuthServiceConfig
|
||||
services map[string]OAuthService
|
||||
configs map[string]config.OAuthServiceConfig
|
||||
}
|
||||
|
||||
func NewOAuthBrokerService(configs map[string]config.OAuthServiceConfig) *OAuthBrokerService {
|
||||
return &OAuthBrokerService{
|
||||
Services: make(map[string]OAuthService),
|
||||
Configs: configs,
|
||||
services: make(map[string]OAuthService),
|
||||
configs: configs,
|
||||
}
|
||||
}
|
||||
|
||||
func (broker *OAuthBrokerService) Init() error {
|
||||
for name, cfg := range broker.Configs {
|
||||
for name, cfg := range broker.configs {
|
||||
switch name {
|
||||
case "github":
|
||||
service := NewGithubOAuthService(cfg)
|
||||
broker.Services[name] = service
|
||||
broker.services[name] = service
|
||||
case "google":
|
||||
service := NewGoogleOAuthService(cfg)
|
||||
broker.Services[name] = service
|
||||
broker.services[name] = service
|
||||
default:
|
||||
service := NewGenericOAuthService(cfg)
|
||||
broker.Services[name] = service
|
||||
broker.services[name] = service
|
||||
}
|
||||
}
|
||||
|
||||
for name, service := range broker.Services {
|
||||
for name, service := range broker.services {
|
||||
err := service.Init()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msgf("Failed to initialize OAuth service: %s", name)
|
||||
log.Error().Err(err).Msgf("Failed to initialize OAuth service: %T", name)
|
||||
return err
|
||||
}
|
||||
log.Info().Msgf("Initialized OAuth service: %s", name)
|
||||
log.Info().Msgf("Initialized OAuth service: %T", name)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (broker *OAuthBrokerService) GetConfiguredServices() []string {
|
||||
services := make([]string, 0, len(broker.Services))
|
||||
for name := range broker.Services {
|
||||
services := make([]string, 0, len(broker.services))
|
||||
for name := range broker.services {
|
||||
services = append(services, name)
|
||||
}
|
||||
slices.Sort(services)
|
||||
return services
|
||||
}
|
||||
|
||||
func (broker *OAuthBrokerService) GetService(name string) (OAuthService, bool) {
|
||||
service, exists := broker.Services[name]
|
||||
service, exists := broker.services[name]
|
||||
return service, exists
|
||||
}
|
||||
|
||||
func (broker *OAuthBrokerService) GetUser(service string) (config.Claims, error) {
|
||||
oauthService, exists := broker.Services[service]
|
||||
oauthService, exists := broker.services[service]
|
||||
if !exists {
|
||||
return config.Claims{}, errors.New("oauth service not found")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user