2023-10-13 11:07:55 +02:00

287 lines
12 KiB
VB.net

Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Base
Namespace SyncUsers
Public Class SyncUsersMSSQL
Implements ISyncUsers
Private _logConfig As LogConfig
Private _logger As Logger
Private _mssql As MSSQLServer
Private Const ADDED_WHO = "Active Directory Sync"
Public Sub New(LogConfig As LogConfig, MSSQL As MSSQLServer)
_logConfig = LogConfig
_logger = LogConfig.GetLogger()
_mssql = MSSQL
End Sub
Public Function SyncUsers(GroupName As String, Users As List(Of ADUser), PropertyMapping As List(Of AttributeMapping)) As List(Of ADUser) Implements ISyncUsers.SyncUsers
Dim oGroupId As Integer
Dim oSyncedUsers As New List(Of ADUser)
Dim oSyncedUserIds As New List(Of Int64)
Dim oCreatedUsers As New List(Of ADUser)
Dim oUpdatedUsers As New List(Of ADUser)
Try
_logger.Debug("Getting group Id for group {0}", GroupName)
oGroupId = GetGroupId(GroupName)
If oGroupId = 0 Then
_logger.Debug("Group {0} does not exist in database. Exiting.", GroupName)
Return oSyncedUsers
End If
_logger.Debug("Using group Id {0}", oGroupId)
Catch ex As Exception
_logger.Error(ex)
Return oSyncedUsers
End Try
For Each oUser In Users
Dim oUserId As Long
Dim oUserExists As Boolean
' Check if user already exists
Try
_logger.Debug("Checking if user [{0}] exists", oUser)
oUserId = GetUserId(oUser.samAccountName)
oUserExists = oUserId > 0
_logger.Debug("User [{0}] exists in database: [{1}]", oUser, oUserExists)
Catch ex As Exception
_logger.Error(ex)
_logger.Warn("Could not get UserId for user. Skipping.")
Continue For
End Try
' Collect user ids from existing users
If oUserExists Then
oSyncedUserIds.Add(oUserId)
End If
' Create or update user
Try
If Not oUserExists Then
_logger.Debug("Creating new user for [{0}]", oUser)
oUserId = CreateUser(oUser)
_logger.Debug("User created with Id [{0}]", oUserId)
_logger.Info("Added new User [{0}]", oUser)
oCreatedUsers.Add(oUser)
Else
_logger.Debug("Updating user [{0}]", oUser)
oUserId = UpdateUser(oUser)
If oUserId <> 0 Then
_logger.Debug("User created with Id [{0}]", oUserId)
_logger.Info("Updated User [{0}]", oUser)
oUpdatedUsers.Add(oUser)
End If
End If
Catch ex As Exception
_logger.Error(ex)
_logger.Warn("Could Not create/update user [{0}]. Skipping.", oUser)
Continue For
End Try
' Add custom attributes to user
Try
AddCustomAttributesToUser(oUser, oUserId)
Catch ex As Exception
_logger.Error(ex)
_logger.Debug("Could Not add custom attributes to user {0}. Continuing.", oUser)
End Try
' Add the user to group
Try
If AddUserToGroup(oUserId, oGroupId) Then
_logger.Info("User [{0}] added to group [{1}]", oUser, GroupName)
End If
Catch ex As Exception
_logger.Error(ex)
_logger.Warn("Could Not add user {0} to group {1}. Skipping.", oUser, GroupName)
Continue For
End Try
oSyncedUsers.Add(oUser)
Next
' Delete users that are assigned to the group but no longer exist in active directory
Dim oUserIdString = String.Join(",", oSyncedUserIds)
If oSyncedUserIds.Count = 0 Then
_logger.Info("Group {0} does not contain any users.", GroupName)
oUserIdString = 0
End If
Dim oSQL As String = $"DELETE FROM TBDD_GROUPS_USER WHERE USER_ID NOT IN ({oUserIdString}) AND GROUP_ID = {oGroupId}"
Dim oDeletedRelations = _mssql.GetScalarValue(oSQL)
If oCreatedUsers.Count > 0 Then
_logger.Info("Created [{0}] new users", oCreatedUsers.Count)
End If
_logger.Info("Updated [{0}] users", oUpdatedUsers.Count)
If oDeletedRelations > 0 Then
_logger.Info("Removed [{0}] users from Group [{1}]", oDeletedRelations, GroupName)
End If
Return oSyncedUsers
End Function
Private Function AddUserToGroup(UserId As Integer, GroupId As Integer) As Boolean Implements ISyncUsers.AddUserToGroup
Try
Dim oSQL = $"SELECT COUNT(*) FROM TBDD_GROUPS_USER WHERE USER_ID = {UserId} And GROUP_ID = {GroupId}"
Dim oResult = True
If _mssql.GetScalarValue(oSQL) = 0 Then
oSQL = $"INSERT INTO TBDD_GROUPS_USER (USER_ID, GROUP_ID, ADDED_WHO) VALUES ({UserId}, {GroupId}, '{ADDED_WHO}')"
oResult = _mssql.ExecuteNonQuery(oSQL)
Else
_logger.Debug($"UserGroup-Relation [{UserId}/{GroupId}] already existing")
Return False
End If
If oResult = False Then
Throw New Exception("Error while adding user to group!")
End If
Return True
Catch ex As Exception
_logger.Error(ex)
Throw ex
End Try
End Function
Private Function GetGroupId(GroupName As String) As Integer Implements ISyncUsers.GetGroupId
Try
Dim oSQL As String = $"SELECT GUID FROM TBDD_GROUPS WHERE UPPER(NAME) = UPPER('{GroupName}') AND AD_SYNC = 1 AND ACTIVE = 1"
Dim oGroupId = _mssql.GetScalarValue(oSQL)
If IsDBNull(oGroupId) OrElse oGroupId = 0 Then
_logger.Debug("Group {0} not found in database.", GroupName)
Return 0
End If
Return oGroupId
Catch ex As Exception
_logger.Error(ex)
Throw ex
End Try
End Function
Private Function GetUserId(UserName As String) As Integer Implements ISyncUsers.GetUserId
Try
Dim oSQL As String = $"SELECT GUID FROM TBDD_USER WHERE UPPER(USERNAME) = UPPER('{UserName}')"
Dim oUserId = _mssql.GetScalarValue(oSQL)
If IsDBNull(oUserId) OrElse IsNothing(oUserId) OrElse oUserId = 0 Then
_logger.Debug("User [{0}] does not exist", UserName)
Return 0
End If
Return oUserId
Catch ex As Exception
_logger.Error(ex)
Throw ex
End Try
End Function
Private Function CreateUser(User As ADUser) As Integer Implements ISyncUsers.CreateUser
Try
If User Is Nothing Then
_logger.Warn("Argument [User] is nothing. Exiting.")
Throw New ArgumentNullException("User")
End If
Dim oUserId As Integer = GetUserId(User.samAccountName)
_logger.Debug("UserId of User [{0}] is [{1}]", User, oUserId)
If oUserId = 0 Then
Dim oPrename = User.GivenName.EscapeForSQL()
Dim oSurname = User.Surname.EscapeForSQL()
Dim oUsername = User.samAccountName.EscapeForSQL()
Dim oEmail = User.Email.EscapeForSQL()
Dim oSQL As String = $"INSERT INTO TBDD_USER (PRENAME, NAME, USERNAME, EMAIL, ADDED_WHO) VALUES ('{oPrename}', '{oSurname}', UPPER('{oUsername}'), '{oEmail}', '{ADDED_WHO}')"
Dim oResult = _mssql.ExecuteNonQuery(oSQL)
If oResult = True Then
oUserId = _mssql.GetScalarValue("SELECT MAX(GUID) FROM TBDD_USER")
Return oUserId
Else
Throw New Exception($"Error while inserting user {User.samAccountName}!")
End If
Else
Return oUserId
End If
Catch ex As Exception
_logger.Error(ex)
Throw ex
End Try
End Function
Private Function UpdateUser(User As ADUser) As Integer
Try
If User Is Nothing Then
_logger.Warn("Error in UpdateUser - User object is nothing")
Return 0
End If
If User.samAccountName Is Nothing Then
_logger.Warn("Error in UpdateUser - User samAccountName is nothing")
Return 0
End If
Dim oUserId As Integer = GetUserId(User.samAccountName)
If Not IsNothing(oUserId) Then
If oUserId > 0 Then
Dim oPrename = User.GivenName.EscapeForSQL()
Dim oSurname = User.Surname.EscapeForSQL()
Dim oEmail = User.Email.EscapeForSQL()
Dim oSQL As String = $"UPDATE TBDD_USER SET PRENAME = '{oPrename}', NAME = '{oSurname}', EMAIL = '{oEmail}', CHANGED_WHO = '{ADDED_WHO}' WHERE GUID = {oUserId}"
Dim oResult = _mssql.ExecuteNonQuery(oSQL)
If oResult = True Then
Return oUserId
Else
Throw New Exception($"Error while updating user {User.samAccountName}!")
End If
Else
Return oUserId
End If
Else
_logger.Warn("Error in UpdateUser - Could not get a userid for samAccountName: " + User.samAccountName)
Return 0
End If
Catch ex As Exception
_logger.Error(ex)
Throw ex
End Try
End Function
Public Sub AddCustomAttributesToUser(User As ADUser, UserId As Integer) Implements ISyncUsers.AddCustomAttributesToUser
Dim oCustomAttributes = User.CustomAttributes
_logger.Debug("Adding {0} Custom Attributes to User {1}", oCustomAttributes.Count, User)
For Each oAttribute In oCustomAttributes
_logger.Debug("Adding Custom Attribute [{0}] with value [{1}] to User [{2}]", oAttribute.MSSQLColumn, oAttribute.Value, User)
Dim oSQL As String = $"UPDATE TBDD_USER SET {oAttribute.MSSQLColumn} = '{oAttribute.Value}', CHANGED_WHO = '{ADDED_WHO}' WHERE GUID = {UserId}"
Dim oResult = _mssql.ExecuteNonQuery(oSQL)
If oResult = False Then
_logger.Debug("Custom Attribute {0} could not be added to user {1}", oAttribute.Name, User.samAccountName)
Continue For
End If
Next
End Sub
End Class
End Namespace