Files
opencloud/glauth/pkg/server/glauth/server.go
Jörn Friedrich Dreyer c124102df2 Merge pull request #627 from butonic/add-basic-auth-option
add enable basic auth option and check permissions
2020-11-05 16:36:16 +01:00

156 lines
4.0 KiB
Go

package glauth
import (
"errors"
"fmt"
"github.com/GeertJohan/yubigo"
"github.com/glauth/glauth/pkg/config"
"github.com/glauth/glauth/pkg/handler"
"github.com/go-logr/logr"
"github.com/nmcclain/ldap"
"github.com/owncloud/ocis/glauth/pkg/mlogr"
)
// LdapSvc holds the ldap server struct
type LdapSvc struct {
log logr.Logger
ldap *config.LDAP
ldaps *config.LDAPS
backend *config.Config
fallback *config.Config
yubiAuth *yubigo.YubiAuth
l *ldap.Server
}
// Server initializes the ldap server.
// It is a fork github.com/glauth/pkg/server because it would introduce a go-micro dependency upstream.
func Server(opts ...Option) (*LdapSvc, error) {
options := newOptions(opts...)
s := LdapSvc{
log: mlogr.New(&options.Logger),
backend: options.Backend,
fallback: options.Fallback,
ldap: options.LDAP,
ldaps: options.LDAPS,
}
var err error
if len(s.backend.YubikeyClientID) > 0 && len(s.backend.YubikeySecret) > 0 {
s.yubiAuth, err = yubigo.NewYubiAuth(s.backend.YubikeyClientID, s.backend.YubikeySecret)
if err != nil {
return nil, errors.New("yubikey auth failed")
}
}
// configure the backend
s.l = ldap.NewServer()
s.l.EnforceLDAP = true
var bh handler.Handler
switch s.backend.Backend.Datastore {
/* TODO bring back file config
case "config":
bh = handler.NewConfigHandler(
handler.Logger(s.log),
handler.Config(s.c),
handler.YubiAuth(s.yubiAuth),
)
*/
case "ldap":
bh = handler.NewLdapHandler(
handler.Logger(s.log),
handler.Config(s.backend),
)
case "owncloud":
bh = handler.NewOwnCloudHandler(
handler.Logger(s.log),
handler.Config(s.backend),
)
case "accounts":
bh = NewOCISHandler(
AccountsService(options.AccountsService),
GroupsService(options.GroupsService),
Logger(options.Logger),
BaseDN(s.backend.Backend.BaseDN),
NameFormat(s.backend.Backend.NameFormat),
GroupFormat(s.backend.Backend.GroupFormat),
RoleBundleUUID(options.RoleBundleUUID),
)
default:
return nil, fmt.Errorf("unsupported backend %s - must be 'ldap', 'owncloud' or 'accounts'", s.backend.Backend.Datastore)
}
s.log.V(3).Info("Using backend", "backend", s.backend.Backend)
if s.fallback != nil && s.fallback.Backend.Datastore != "" {
var fh handler.Handler
switch s.fallback.Backend.Datastore {
/* TODO bring back file config
case "config":
fh = handler.NewConfigHandler(
handler.Logger(s.log),
handler.Config(s.c),
handler.YubiAuth(s.yubiAuth),
)
*/
case "ldap":
fh = handler.NewLdapHandler(
handler.Logger(s.log),
handler.Config(s.fallback),
)
case "owncloud":
fh = handler.NewOwnCloudHandler(
handler.Logger(s.log),
handler.Config(s.fallback),
)
case "accounts":
fh = NewOCISHandler(
AccountsService(options.AccountsService),
GroupsService(options.GroupsService),
Logger(options.Logger),
BaseDN(s.fallback.Backend.BaseDN),
NameFormat(s.fallback.Backend.NameFormat),
GroupFormat(s.fallback.Backend.GroupFormat),
RoleBundleUUID(options.RoleBundleUUID),
)
default:
return nil, fmt.Errorf("unsupported fallback %s - must be 'ldap', 'owncloud' or 'accounts'", s.fallback.Backend.Datastore)
}
s.log.V(3).Info("Using fallback", "backend", s.fallback.Backend)
bh = NewChainHandler(options.Logger, bh, fh)
}
s.l.BindFunc(s.backend.Backend.BaseDN, bh)
s.l.SearchFunc(s.backend.Backend.BaseDN, bh)
s.l.CloseFunc(s.backend.Backend.BaseDN, bh)
return &s, nil
}
// ListenAndServe listens on the TCP network address s.c.LDAP.Listen
func (s *LdapSvc) ListenAndServe() error {
s.log.V(3).Info("ldap server listening", "address", s.ldap.Listen)
return s.l.ListenAndServe(s.ldap.Listen)
}
// ListenAndServeTLS listens on the TCP network address s.c.LDAPS.Listen
func (s *LdapSvc) ListenAndServeTLS() error {
s.log.V(3).Info("ldaps server listening", "address", s.ldaps.Listen)
return s.l.ListenAndServeTLS(
s.ldaps.Listen,
s.ldaps.Cert,
s.ldaps.Key,
)
}
// Shutdown ends listeners by sending true to the ldap serves quit channel
func (s *LdapSvc) Shutdown() {
s.l.Quit <- true
}