2020-11-16 16:39:41 -05:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/h44z/wg-portal/internal/ldap"
|
2021-02-24 15:24:45 -05:00
|
|
|
"github.com/h44z/wg-portal/internal/users"
|
2021-02-08 16:56:02 -05:00
|
|
|
"github.com/sirupsen/logrus"
|
2021-02-24 15:24:45 -05:00
|
|
|
"gorm.io/gorm"
|
2020-11-16 16:39:41 -05:00
|
|
|
)
|
|
|
|
|
2021-02-24 15:24:45 -05:00
|
|
|
func (s *Server) SyncLdapWithUserDatabase() {
|
|
|
|
logrus.Info("starting ldap user synchronization...")
|
|
|
|
running := true
|
|
|
|
for running {
|
|
|
|
// Select blocks until one of the cases happens
|
|
|
|
select {
|
|
|
|
case <-time.After(1 * time.Minute):
|
|
|
|
// Sleep for 1 minute
|
|
|
|
case <-s.ctx.Done():
|
|
|
|
logrus.Trace("ldap-sync shutting down (context ended)...")
|
|
|
|
running = false
|
|
|
|
continue
|
2020-11-16 16:39:41 -05:00
|
|
|
}
|
|
|
|
|
2021-02-24 15:24:45 -05:00
|
|
|
// Main work here
|
|
|
|
logrus.Trace("syncing ldap users to database...")
|
|
|
|
ldapUsers, err := ldap.FindAllUsers(&s.config.LDAP)
|
|
|
|
if err != nil {
|
|
|
|
logrus.Errorf("failed to fetch users from ldap: %v", err)
|
|
|
|
continue
|
2020-11-16 16:39:41 -05:00
|
|
|
}
|
|
|
|
|
2021-02-24 15:24:45 -05:00
|
|
|
for i := range ldapUsers {
|
|
|
|
// prefilter
|
|
|
|
if ldapUsers[i].Attributes[s.config.LDAP.EmailAttribute] == "" ||
|
|
|
|
ldapUsers[i].Attributes[s.config.LDAP.FirstNameAttribute] == "" ||
|
|
|
|
ldapUsers[i].Attributes[s.config.LDAP.LastNameAttribute] == "" {
|
|
|
|
continue
|
2020-11-16 16:39:41 -05:00
|
|
|
}
|
2021-02-24 15:24:45 -05:00
|
|
|
|
|
|
|
user, err := s.users.GetOrCreateUserUnscoped(ldapUsers[i].Attributes[s.config.LDAP.EmailAttribute])
|
|
|
|
if err != nil {
|
|
|
|
logrus.Errorf("failed to get/create user %s in database: %v", ldapUsers[i].Attributes[s.config.LDAP.EmailAttribute], err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// check if user should be deactivated
|
|
|
|
ldapDeactivated := false
|
|
|
|
switch s.config.LDAP.Type {
|
|
|
|
case ldap.TypeActiveDirectory:
|
|
|
|
ldapDeactivated = ldap.IsActiveDirectoryUserDisabled(ldapUsers[i].Attributes[s.config.LDAP.DisabledAttribute])
|
|
|
|
case ldap.TypeOpenLDAP:
|
|
|
|
ldapDeactivated = ldap.IsOpenLdapUserDisabled(ldapUsers[i].Attributes[s.config.LDAP.DisabledAttribute])
|
|
|
|
}
|
|
|
|
|
|
|
|
// check if user has been disabled in ldap, update peers accordingly
|
|
|
|
if ldapDeactivated != user.DeletedAt.Valid {
|
|
|
|
if ldapDeactivated {
|
|
|
|
// disable all peers for the given user
|
|
|
|
for _, peer := range s.peers.GetPeersByMail(user.Email) {
|
|
|
|
now := time.Now()
|
|
|
|
peer.DeactivatedAt = &now
|
|
|
|
if err = s.UpdatePeer(peer, now); err != nil {
|
|
|
|
logrus.Errorf("failed to update deactivated peer %s: %v", peer.PublicKey, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// enable all peers for the given user
|
|
|
|
for _, peer := range s.peers.GetPeersByMail(user.Email) {
|
|
|
|
now := time.Now()
|
|
|
|
peer.DeactivatedAt = nil
|
|
|
|
if err = s.UpdatePeer(peer, now); err != nil {
|
|
|
|
logrus.Errorf("failed to update activated peer %s: %v", peer.PublicKey, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sync attributes from ldap
|
|
|
|
if s.UserChangedInLdap(user, &ldapUsers[i]) {
|
|
|
|
user.Firstname = ldapUsers[i].Attributes[s.config.LDAP.FirstNameAttribute]
|
|
|
|
user.Lastname = ldapUsers[i].Attributes[s.config.LDAP.LastNameAttribute]
|
|
|
|
user.Email = ldapUsers[i].Attributes[s.config.LDAP.EmailAttribute]
|
|
|
|
user.Phone = ldapUsers[i].Attributes[s.config.LDAP.PhoneAttribute]
|
|
|
|
user.IsAdmin = false
|
|
|
|
user.Source = users.UserSourceLdap
|
|
|
|
user.DeletedAt = gorm.DeletedAt{} // Not deleted
|
|
|
|
|
|
|
|
for _, group := range ldapUsers[i].RawAttributes[s.config.LDAP.GroupMemberAttribute] {
|
|
|
|
if string(group) == s.config.LDAP.AdminLdapGroup {
|
|
|
|
user.IsAdmin = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-26 17:43:29 -05:00
|
|
|
if err = s.users.UpdateUser(user); err != nil {
|
|
|
|
logrus.Errorf("failed to update ldap user %s in database: %v", user.Email, err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2021-02-24 15:24:45 -05:00
|
|
|
if ldapDeactivated {
|
|
|
|
if err = s.users.DeleteUser(user); err != nil {
|
|
|
|
logrus.Errorf("failed to delete deactivated user %s in database: %v", user.Email, err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
logrus.Info("ldap user synchronization stopped")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s Server) UserChangedInLdap(user *users.User, ldapData *ldap.RawLdapData) bool {
|
|
|
|
if user.Firstname != ldapData.Attributes[s.config.LDAP.FirstNameAttribute] {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
if user.Lastname != ldapData.Attributes[s.config.LDAP.LastNameAttribute] {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
if user.Email != ldapData.Attributes[s.config.LDAP.EmailAttribute] {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
if user.Phone != ldapData.Attributes[s.config.LDAP.PhoneAttribute] {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
ldapDeactivated := false
|
|
|
|
switch s.config.LDAP.Type {
|
|
|
|
case ldap.TypeActiveDirectory:
|
|
|
|
ldapDeactivated = ldap.IsActiveDirectoryUserDisabled(ldapData.Attributes[s.config.LDAP.DisabledAttribute])
|
|
|
|
case ldap.TypeOpenLDAP:
|
|
|
|
ldapDeactivated = ldap.IsOpenLdapUserDisabled(ldapData.Attributes[s.config.LDAP.DisabledAttribute])
|
|
|
|
}
|
|
|
|
if ldapDeactivated != user.DeletedAt.Valid {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
ldapAdmin := false
|
|
|
|
for _, group := range ldapData.RawAttributes[s.config.LDAP.GroupMemberAttribute] {
|
|
|
|
if string(group) == s.config.LDAP.AdminLdapGroup {
|
|
|
|
ldapAdmin = true
|
|
|
|
break
|
2020-11-16 16:39:41 -05:00
|
|
|
}
|
|
|
|
}
|
2021-02-24 15:24:45 -05:00
|
|
|
if user.IsAdmin != ldapAdmin {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
2020-11-16 16:39:41 -05:00
|
|
|
}
|