144 lines
3.7 KiB
Go
144 lines
3.7 KiB
Go
|
package ldapSync
|
||
|
|
||
|
/*
|
||
|
this file contains functions to sync ldap users and groups to the database
|
||
|
*/
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"github.com/pocketbase/dbx"
|
||
|
"github.com/pocketbase/pocketbase"
|
||
|
"github.com/pocketbase/pocketbase/forms"
|
||
|
"github.com/pocketbase/pocketbase/models"
|
||
|
"gitlab.uni-ulm.de/stuve-it/it-tools/backend/logger"
|
||
|
)
|
||
|
|
||
|
// upsertLDAPGroup This function creates / updates a record in the ldap groups table
|
||
|
func upsertLDAPGroup(app *pocketbase.PocketBase, ldapGroup *LDAPGroup) error {
|
||
|
|
||
|
// find ldapGroups table
|
||
|
collection, err := app.Dao().FindCollectionByNameOrId(ldapGroupsTableName)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
var record *models.Record
|
||
|
|
||
|
// if record exists, update it
|
||
|
if res, _ := app.Dao().FindFirstRecordByFilter(
|
||
|
ldapGroupsTableName,
|
||
|
"gidNumber = {:gidNumber}",
|
||
|
dbx.Params{"gidNumber": ldapGroup.gidNumber},
|
||
|
); res != nil {
|
||
|
record = res
|
||
|
} else { // if record does not exist, create it
|
||
|
record = models.NewRecord(collection)
|
||
|
}
|
||
|
|
||
|
form := forms.NewRecordUpsert(app, record)
|
||
|
|
||
|
var groups []string
|
||
|
|
||
|
// get group ids from group dns
|
||
|
for _, groupDn := range ldapGroup.memberOf {
|
||
|
group, err := GetLdapGroupByDN(app, groupDn)
|
||
|
if err == nil {
|
||
|
groups = append(groups, group.Id)
|
||
|
} else {
|
||
|
logger.LogErrorF("unable to find %s.memberOf: %s", ldapGroup.cn, groupDn)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// load data
|
||
|
err = form.LoadData(map[string]any{
|
||
|
"gidNumber": ldapGroup.gidNumber,
|
||
|
"cn": ldapGroup.cn,
|
||
|
"dn": ldapGroup.dn,
|
||
|
"description": ldapGroup.description,
|
||
|
"memberOf": groups,
|
||
|
})
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// validate and submit (internally it calls app.Dao().SaveRecord(record) in a transaction)
|
||
|
if err := form.Submit(); err != nil {
|
||
|
return fmt.Errorf("failed to upsert group with dn: %s - %w", ldapGroup.dn, err)
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// upsertLDAPUser This function creates / updates a record in the ldap users table
|
||
|
func upsertLDAPUser(app *pocketbase.PocketBase, ldapUser *LDAPUser) error {
|
||
|
|
||
|
// find ldapUsers table
|
||
|
collection, err := app.Dao().FindCollectionByNameOrId(ldapUsersTableName)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
var record *models.Record
|
||
|
|
||
|
// if record exists, update it
|
||
|
if res, _ := app.Dao().FindFirstRecordByFilter(
|
||
|
ldapUsersTableName,
|
||
|
"uidNumber = {:uidNumber}",
|
||
|
dbx.Params{"uidNumber": ldapUser.uidNumber},
|
||
|
); res != nil {
|
||
|
record = res
|
||
|
} else { // if record does not exist, create it
|
||
|
record = models.NewRecord(collection)
|
||
|
}
|
||
|
|
||
|
accountExpires, _ := ldapTimeToUnixTime(ldapUser.accountExpires)
|
||
|
|
||
|
var groups []string
|
||
|
|
||
|
// get group ids from group dns
|
||
|
for _, groupDn := range ldapUser.memberOf {
|
||
|
group, err := GetLdapGroupByDN(app, groupDn)
|
||
|
if err == nil {
|
||
|
groups = append(groups, group.Id)
|
||
|
} else {
|
||
|
logger.LogErrorF("unable to find %s.memberOf: %s", ldapUser.cn, groupDn)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
record.Set("uidNumber", ldapUser.uidNumber)
|
||
|
record.Set("givenName", ldapUser.givenName)
|
||
|
record.Set("sn", ldapUser.sn)
|
||
|
record.Set("username", ldapUser.cn)
|
||
|
record.Set("accountExpires", accountExpires)
|
||
|
record.Set("email", ldapUser.mail)
|
||
|
record.Set("emailVisibility", false)
|
||
|
record.Set("verified", true)
|
||
|
record.Set("dn", ldapUser.dn)
|
||
|
record.Set("cn", ldapUser.cn)
|
||
|
record.Set("memberOf", groups)
|
||
|
|
||
|
record.RefreshTokenKey()
|
||
|
|
||
|
if err := app.Dao().SaveRecord(record); err != nil {
|
||
|
return fmt.Errorf("failed to upsert user with dn: %s - %w", ldapUser.dn, err)
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func GetLdapGroupByDN(app *pocketbase.PocketBase, dn string) (*models.Record, error) {
|
||
|
return app.Dao().FindFirstRecordByFilter(
|
||
|
ldapGroupsTableName,
|
||
|
"dn = {:dn}",
|
||
|
dbx.Params{"dn": dn},
|
||
|
)
|
||
|
}
|
||
|
|
||
|
func GetLdapUserByCN(app *pocketbase.PocketBase, cn string) (*models.Record, error) {
|
||
|
return app.Dao().FindFirstRecordByFilter(
|
||
|
ldapUsersTableName,
|
||
|
"cn = {:cn}",
|
||
|
dbx.Params{"cn": cn},
|
||
|
)
|
||
|
}
|