mirror of
https://github.com/parkan/go-hauk.git
synced 2026-05-08 16:47:46 +02:00
add auth layer
This commit is contained in:
9
auth/auth.go
Normal file
9
auth/auth.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
var ErrAuthFailed = errors.New("authentication failed")
|
||||||
|
|
||||||
|
type Authenticator interface {
|
||||||
|
Authenticate(user, pass string) error
|
||||||
|
}
|
||||||
41
auth/htpasswd.go
Normal file
41
auth/htpasswd.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HtpasswdAuth struct {
|
||||||
|
path string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHtpasswdAuth(path string) *HtpasswdAuth {
|
||||||
|
return &HtpasswdAuth{path: path}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *HtpasswdAuth) Authenticate(user, pass string) error {
|
||||||
|
f, err := os.Open(h.path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(f)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := strings.TrimSpace(scanner.Text())
|
||||||
|
parts := strings.SplitN(line, ":", 2)
|
||||||
|
if len(parts) != 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if parts[0] == user {
|
||||||
|
if bcrypt.CompareHashAndPassword([]byte(parts[1]), []byte(pass)) == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return ErrAuthFailed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ErrAuthFailed
|
||||||
|
}
|
||||||
80
auth/ldap.go
Normal file
80
auth/ldap.go
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/go-ldap/ldap/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LDAPAuth struct {
|
||||||
|
uri string
|
||||||
|
baseDN string
|
||||||
|
bindDN string
|
||||||
|
bindPass string
|
||||||
|
userFilter string
|
||||||
|
startTLS bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLDAPAuth(uri, baseDN, bindDN, bindPass, userFilter string, startTLS bool) *LDAPAuth {
|
||||||
|
return &LDAPAuth{
|
||||||
|
uri: uri,
|
||||||
|
baseDN: baseDN,
|
||||||
|
bindDN: bindDN,
|
||||||
|
bindPass: bindPass,
|
||||||
|
userFilter: userFilter,
|
||||||
|
startTLS: startTLS,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *LDAPAuth) Authenticate(user, pass string) error {
|
||||||
|
if pass == "" {
|
||||||
|
return ErrAuthFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, err := ldap.DialURL(l.uri)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("ldap connect: %w", err)
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
if l.startTLS {
|
||||||
|
if err := conn.StartTLS(nil); err != nil {
|
||||||
|
return fmt.Errorf("ldap starttls: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := conn.Bind(l.bindDN, l.bindPass); err != nil {
|
||||||
|
return fmt.Errorf("ldap admin bind: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
filter := strings.Replace(l.userFilter, "%s", ldap.EscapeFilter(user), 1)
|
||||||
|
req := ldap.NewSearchRequest(
|
||||||
|
l.baseDN,
|
||||||
|
ldap.ScopeWholeSubtree,
|
||||||
|
ldap.NeverDerefAliases,
|
||||||
|
0, 0, false,
|
||||||
|
filter,
|
||||||
|
[]string{"dn"},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
|
||||||
|
res, err := conn.Search(req)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("ldap search: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(res.Entries) == 0 {
|
||||||
|
return ErrAuthFailed
|
||||||
|
}
|
||||||
|
if len(res.Entries) > 1 {
|
||||||
|
return fmt.Errorf("ldap: ambiguous user filter matched %d users", len(res.Entries))
|
||||||
|
}
|
||||||
|
|
||||||
|
userDN := res.Entries[0].DN
|
||||||
|
if err := conn.Bind(userDN, pass); err != nil {
|
||||||
|
return ErrAuthFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
18
auth/password.go
Normal file
18
auth/password.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import "golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
|
type PasswordAuth struct {
|
||||||
|
hash []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPasswordAuth(hash string) *PasswordAuth {
|
||||||
|
return &PasswordAuth{hash: []byte(hash)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *PasswordAuth) Authenticate(_, pass string) error {
|
||||||
|
if err := bcrypt.CompareHashAndPassword(p.hash, []byte(pass)); err != nil {
|
||||||
|
return ErrAuthFailed
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user