Imports System.DirectoryServices
Imports System.DirectoryServices.ActiveDirectory
Imports System.DirectoryServices.AccountManagement
Imports System.IO

Public Class frmUserKonfig_AddUsers
    'Private DT_GROUPS_EXCLUSIVE As DataTable
    Private DT_ADD_USER As DataTable
    Private Sub frmUserKonfig_AddUsers_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
        Try
            Dim Filename As String = String.Format("{0}-UserLayout.xml", GridViewUsers.Name)
            Dim XMLPath = System.IO.Path.Combine(Application.UserAppDataPath(), Filename)
            GridViewUsers.SaveLayoutToXml(XMLPath)
        Catch ex As Exception
            MsgBox("Error in SaveGrid_Layout:" & vbNewLine & ex.Message)
        End Try

    End Sub

    Private Sub formUserConfig_AddUsers_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Try
            Cursor = Cursors.WaitCursor


            'Dim sql = "SELECT * FROM TBPMO_AD_GROUP_EXCLUSIVE"
            'DT_GROUPS_EXCLUSIVE = MYDB_ECM.GetDatatable(sql)
            GetGroups(USER_USERNAME)
        Catch ex As Exception
            MsgBox("Error in Load Groups:" & vbNewLine & ex.Message, MsgBoxStyle.Critical)
        End Try
        Try
            Dim Filename As String = String.Format("{0}-UserLayout.xml", GridViewUsers.Name)
            Dim XMLPath = System.IO.Path.Combine(Application.UserAppDataPath(), Filename)
            If File.Exists(XMLPath) Then
                GridViewUsers.RestoreLayoutFromXml(XMLPath)
                'grvwGrid.ClearGrouping()
                GridViewUsers.ClearSelection()
            End If
        Catch ex As Exception
            MsgBox("Error in Load Grid_Layout:" & vbNewLine & ex.Message)
        End Try
        Cursor = Cursors.Default

    End Sub

    Function GetActiveDirectoryGroups() As List(Of String)
        Try
            Dim groups As List(Of String) = New List(Of String)
            Dim ctx As PrincipalContext = New PrincipalContext(ContextType.Domain)
            Dim group As GroupPrincipal = New GroupPrincipal(ctx)
            Dim srch As PrincipalSearcher = New PrincipalSearcher(group)
            For Each g In srch.FindAll()
                If GetUsersForGroup(g.ToString()).Count <> 0 Then
                    If Not g.ToString.StartsWith("WinRMR") And Not g.ToString.StartsWith("Priv") And Not g.ToString.StartsWith("Gäst") And Not g.ToString.StartsWith("Druck") And Not g.ToString.StartsWith("Sicherungs") And Not g.ToString.StartsWith("Replikations") And Not g.ToString.StartsWith("Netzwerkskon") _
                    And Not g.ToString.StartsWith("Reporting") And Not g.ToString.StartsWith("Leistungs") And Not g.ToString.StartsWith("Distributed COM") And Not g.ToString.StartsWith("IIS_") And Not g.ToString.StartsWith("Kryptografie") And Not g.ToString.StartsWith("Ereignis") And Not g.ToString.StartsWith("Zertifikat") _
                     And Not g.ToString.StartsWith("RDS-") And Not g.ToString.StartsWith("Hyper-V") And Not g.ToString.StartsWith("Zugriffssteuerungs") And Not g.ToString.StartsWith("Remoteverwaltungs") And Not g.ToString.StartsWith("Domänencomput") And Not g.ToString.StartsWith("Domänen-Gäste") _
                     And Not g.ToString.StartsWith("Richtlinien-Ersteller") And Not g.ToString.StartsWith("RAS- und IAS-Server") And Not g.ToString.StartsWith("Server-Operatore") And Not g.ToString.StartsWith("Konten-Oper") And Not g.ToString.StartsWith("Prä-Windows") _
                     And Not g.ToString.StartsWith("SQLAcce") And Not g.ToString.StartsWith("Einstellungen eingehender") And Not g.ToString.StartsWith("Windows-Auth") And Not g.ToString.StartsWith("Terminalserver-Liz") And Not g.ToString.StartsWith("Zulässige") And Not g.ToString.StartsWith("Abgelehnte") And Not g.ToString.StartsWith("Schreibgeschützte Domänen") _
                     And Not g.ToString.StartsWith("Klonbare") And Not g.ToString.StartsWith("Protected User") And Not g.ToString.StartsWith("Dns") And Not g.ToString.StartsWith("DHCP") And Not g.ToString.StartsWith("IIS_IUSR") And Not g.ToString.StartsWith("Richtlinien-Ersteller") _
                     And Not g.ToString.StartsWith("Abgelehnte RODC-Kenn") Then
                        groups.Add(g.ToString)
                    End If
                End If
            Next
            Return groups
        Catch ex As Exception
            MsgBox("Error in GetActiveDirectoryGroups:" & vbNewLine & ex.Message, MsgBoxStyle.Critical)
            Return Nothing
        End Try
    End Function
    Function GetUsersForGroup(g As String) As List(Of UserPrincipal)
        Dim users As List(Of UserPrincipal) = New List(Of UserPrincipal)
        Dim ctx As PrincipalContext = New PrincipalContext(ContextType.Domain)
        Dim group As GroupPrincipal = GroupPrincipal.FindByIdentity(ctx, g)

        Dim u = group.GetMembers(True)

        For Each user In u
            If user.GetType().Name = "UserPrincipal" Then
                users.Add(user)
            End If
        Next

        Return users
    End Function

    Private Sub lbGroups_SelectedIndexChanged(sender As Object, e As EventArgs) Handles lbGroups.SelectedIndexChanged
        Dim group As String = lbGroups.SelectedItem
        Dim users As List(Of UserPrincipal) = GetUsersForGroup(group)
        DD_ECMAdmin.TBAD_Users.Clear()
        Me.Cursor = Cursors.WaitCursor
        For Each user In users
            Dim newUserRow As DD_ECMAdmin.TBAD_UsersRow
            newUserRow = DD_ECMAdmin.TBAD_Users.NewTBAD_UsersRow
            Try
                Dim userldap As UserPrincipal = user
                Dim PRENAME As String = userldap.GivenName
                Dim NAME As String = userldap.Surname
                Dim USERNAME As String = userldap.SamAccountName
                Try
                    newUserRow.Username = userldap.SamAccountName
                Catch ex As Exception
                    newUserRow.Username = user.ToString
                End Try
                Dim email As String = userldap.EmailAddress
                newUserRow.Prename = IIf((IsDBNull(PRENAME) Or IsNothing(PRENAME)), "", PRENAME)
                newUserRow.Surname = IIf((IsDBNull(NAME) Or IsNothing(NAME)), "", NAME)
                newUserRow.Email = IIf((IsDBNull(email) Or IsNothing(email)), "", email)
            Catch ex As Exception
                LOGGER.Warn("Unexpected Error in Read User LDAP-Configurations: " & vbNewLine)
            End Try
            DD_ECMAdmin.TBAD_Users.Rows.Add(newUserRow)
        Next
        Me.Cursor = Cursors.Default
    End Sub

    Private Sub btnAddUsers_Click(sender As Object, e As EventArgs) Handles btnAddUsers.Click
        Dim _Step
        Try
            'Dim items As CheckedListBox.CheckedItemCollection = clbUsers.CheckedItems
            Dim usersAdded As Integer = 0
            Dim usersRefreshed As Integer = 0
            'If items.Count = 0 Then
            '    MsgBox("Keine Benutzer ausgewählt!", MsgBoxStyle.Information)
            '    Exit Sub
            'End If

            For Each row As DataRow In DD_ECMAdmin.TBAD_Users.Rows
                If row.Item(0) = CBool(True) Then

                    _Step = 1
                    Dim oUSERNAME As String
                    oUSERNAME = row.Item(1)
                    LOGGER.Info($"Working on User: {oUSERNAME}")
                    _Step = 2
                    Dim PRENAME As String
                    Try
                        PRENAME = row.Item(2)
                        _Step = 3
                    Catch ex As Exception
                        PRENAME = ""
                    End Try
                    Dim NAME As String
                    _Step = 4
                    Try
                        NAME = row.Item(3)
                        'IIf(IsDBNull(row.Item(3)), NAME = "", NAME = row.Item(3))
                        _Step = 5
                    Catch ex As Exception
                        NAME = ""
                    End Try

                    Dim oEmail As String
                    Try
                        oEmail = row.Item(4)
                        ' IIf(IsDBNull(row.Item(4)), email = "", email = row.Item(4))
                        _Step = 6
                    Catch ex As Exception
                        oEmail = ""
                    End Try
                    Dim SQL
                    If UserExists(oUSERNAME) = False Then
                        _Step = 7
                        SQL = "INSERT INTO TBDD_USER(PRENAME, NAME, USERNAME, EMAIL, LANGUAGE, ADDED_WHO) VALUES('" & PRENAME & "', '" & NAME & "', '" & oUSERNAME & "','" & oEmail & "','" &
                            USER_LANGUAGE & "','" & USER_USERNAME & "')"
                        _Step = 8
                        If MYDB_ECM.ExecuteNonQuery(SQL) = True Then
                            Dim oUserID = MYDB_ECM.GetScalarValue("SELECT MAX(GUID) FROM TBDD_USER")
                            Try

                                SQL = $"INSERT INTO TBDD_USER_MODULES (USER_ID,MODULE_ID,ADDED_WHO) VALUES
                                ({oUserID},(SELECT T.GUID FROM TBDD_MODULES T WHERE T.SHORT_NAME = 'ADDI'),'{Environment.UserName}')"
                                MYDB_ECM.ExecuteNonQuery(SQL)
                            Catch ex As Exception

                            End Try

                            _Step = 9
                            Dim msg = String.Format("USER {0}, {1} - {2} ADDED TO CONFIGURATION", NAME, PRENAME, oUSERNAME)
                            _Step = 10
                            LOGGER.Info(msg)
                            ClassHelper.InsertEssential_Log(oUserID, "USER-ID", msg)
                            usersAdded += 1
                        Else
                            MsgBox("Unexpected Error In Adding User (" & oUSERNAME & ") : " & "Check the log!", MsgBoxStyle.Exclamation)
                        End If
                    Else
                        _Step = 11
                        SQL = $"IF NOT EXISTS(SELECT T.GUID FROM TBDD_USER_MODULES T INNER JOIN TBDD_USER T1 ON T.USER_ID = T1.GUID INNER JOIN TBDD_MODULES T2 ON T.MODULE_ID = T2.GUID WHERE T2.SHORT_NAME = 'ADDI' AND T1.USERNAME = '{oUSERNAME}')
	INSERT INTO TBDD_USER_MODULES (USER_ID,MODULE_ID,ADDED_WHO) VALUES
		((SELECT GUID FROM TBDD_USER WHERE USERNAME = '{oUSERNAME}'),(SELECT T.GUID FROM TBDD_MODULES T WHERE T.SHORT_NAME = 'ADDI'),'{Environment.UserName}')"
                        _Step = 12
                        If MYDB_ECM.ExecuteNonQuery(SQL) = True Then
                            usersRefreshed += 1
                        End If
                    End If
                End If

            Next
            'For Each item As UserPrincipal In items
            '    Dim user As UserPrincipal = item
            '    Dim PRENAME As String = user.GivenName
            '    Dim NAME As String = user.Surname
            '    Dim USERNAME As String = user.SamAccountName
            '    Dim email As String = user.EmailAddress
            '    Dim SQL

            'Next
            If USER_LANGUAGE = "de-DE" Then
                MsgBox(usersAdded & " Benutzer hinzugefügt." & vbNewLine & usersRefreshed & " Benutzer aktualisiert.", MsgBoxStyle.Information)
            Else
                MsgBox(usersAdded & " user(s) added." & vbNewLine & usersRefreshed & " user(s) refreshed.", MsgBoxStyle.Information)
            End If
        Catch ex As Exception
            MsgBox("Unexpected Error In Adding User (Step " & _Step.ToString & ") : " & vbNewLine & ex.Message)
        End Try

    End Sub

    Private Function UserExists(username As String) As Boolean
        Try
            Dim SQL = "SELECT * FROM TBDD_USER WHERE UPPER(USERNAME) = UPPER('" & username & "')"
            Dim result As DataTable = MYDB_ECM.GetDatatable(sql)

            Select Case result.Rows.Count
                Case 0
                    Return False
                Case 1
                    Return True
                Case Else
                    MsgBox("Could not check whether user '" & username & "' exists!" & vbNewLine & SQL, MsgBoxStyle.Exclamation)
            End Select

        Catch ex As Exception
            MsgBox("Error in UserExists: " & vbNewLine & ex.Message)
            Return False
        End Try
    End Function

    Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click
        Me.Close()
    End Sub

    Private Sub tbSelectEverything_Click(sender As Object, e As EventArgs) Handles tbSelectEverything.Click
        For Each row As DataRow In DD_ECMAdmin.TBAD_Users.Rows
            row.Item(0) = CBool(True)
        Next


    End Sub

    Private Sub tbSelectNone_Click(sender As Object, e As EventArgs) Handles tbSelectNone.Click
        For Each row As DataRow In DD_ECMAdmin.TBAD_Users.Rows
            row.Item(0) = CBool(False)
        Next
    End Sub

    'Private Sub clbUsers_SelectedIndexChanged(sender As Object, e As EventArgs)
    '    ToolTipController1.HideHint()
    '    Dim userstring As String = clbUsers.SelectedItem.ToString
    '    Dim userldap As UserPrincipal = clbUsers.SelectedItem
    '    Dim PRENAME As String = userldap.GivenName
    '    Dim NAME As String = userldap.Surname
    '    Dim USERNAME As String = userldap.SamAccountName
    '    Dim email As String = userldap.EmailAddress
    '    ToolTipController1.ShowHint("Used ldap paramters:", userstring & USERNAME & vbNewLine & email, DevExpress.Utils.ToolTipLocation.RightCenter)
    'End Sub

    Private Sub RBCheck2_CheckedChanged(sender As Object, e As EventArgs) Handles RBCheck2.CheckedChanged
        If RBCheck2.Checked Then
            GetGroups(USER_USERNAME)
        End If
    End Sub
    Public Sub GetGroups(ByVal samAccountName As String)
        Try
            'If IsNothing(DT_GROUPS_EXCLUSIVE) Then
            '    Exit Sub
            'End If
            Cursor = Cursors.WaitCursor
            lbGroups.Items.Clear()
            Dim domainConnection = New DirectoryEntry()
            domainConnection.AuthenticationType = System.DirectoryServices.AuthenticationTypes.Secure
            Dim samSearcher = New DirectorySearcher()
            samSearcher.SearchRoot = domainConnection
            samSearcher.Filter = "(samAccountName=" & samAccountName & ")"
            samSearcher.PropertiesToLoad.Add("displayName")
            Dim samResult = samSearcher.FindOne()
            If samResult IsNot Nothing Then
                Dim theUser = samResult.GetDirectoryEntry()
                theUser.RefreshCache(New String() {"tokenGroups"})
                For Each resultBytes As Byte() In theUser.Properties("tokenGroups")
                    Dim SID = New System.Security.Principal.SecurityIdentifier(resultBytes, 0)
                    Dim sidSearcher = New DirectorySearcher()
                    sidSearcher.SearchRoot = domainConnection
                    sidSearcher.Filter = "(objectSid=" & SID.Value & ")"
                    sidSearcher.PropertiesToLoad.Add("name")
                    Dim sidResult = sidSearcher.FindOne()
                    If sidResult IsNot Nothing Then
                        Dim groupname = CStr(sidResult.Properties("name")(0))
                        'If Not IsNothing(DT_GROUPS_EXCLUSIVE) Then
                        '    If DT_GROUPS_EXCLUSIVE.Rows.Count > 0 Then
                        '        For Each GROUP_EXCL As DataRow In DT_GROUPS_EXCLUSIVE.Rows
                        '            If GROUP_EXCL.Item("GROUP_NAME").ToString.ToUpper = groupname.ToUpper Then
                        '                lbGroups.Items.Add(groupname)
                        '            End If
                        '        Next
                        '    Else
                        If Not groupname.StartsWith("WinRMR") And Not groupname.StartsWith("Gäst") And Not groupname.StartsWith("Druck") And Not groupname.StartsWith("Sicherungs") And Not groupname.StartsWith("Replikations") And Not groupname.StartsWith("Netzwerkskon") _
                                   And Not groupname.StartsWith("Leistungs") And Not groupname.StartsWith("Distributed COM") And Not groupname.StartsWith("IIS_") And Not groupname.StartsWith("Kryptografie") And Not groupname.StartsWith("Ereignis") And Not groupname.StartsWith("Zertifikat") _
                                    And Not groupname.StartsWith("RDS-") And Not groupname.StartsWith("Hyper-V") And Not groupname.StartsWith("Zugriffssteuerungs") And Not groupname.StartsWith("Remoteverwaltungs") And Not groupname.StartsWith("Domänencomput") And Not groupname.StartsWith("Domänen-Gäste") _
                                    And Not groupname.StartsWith("Richtlinien-Ersteller") And Not groupname.StartsWith("SQLAccess") And Not groupname.StartsWith("RAS- und IAS-Server") And Not groupname.StartsWith("Server-Operatore") And Not groupname.StartsWith("Konten-Oper") And Not groupname.StartsWith("Prä-Windows") _
                                    And Not groupname.StartsWith("Einstellungen eingehender") And Not groupname.StartsWith("Windows-Auth") And Not groupname.StartsWith("Terminalserver-Liz") And Not groupname.StartsWith("Zulässige") And Not groupname.StartsWith("Abgelehnte") And Not groupname.StartsWith("Schreibgeschützte Domänen") _
                                    And Not groupname.StartsWith("Klonbare") And Not groupname.StartsWith("PrivUser") And Not groupname.StartsWith("Protected User") And Not groupname.StartsWith("Dns") And Not groupname.StartsWith("DHCP") And Not groupname.StartsWith("IIS_IUSR") And Not groupname.StartsWith("Richtlinien-Ersteller") _
                                    And Not groupname.StartsWith("Abgelehnte RODC-Kenn") And Not groupname.StartsWith("Reporting") Then
                                    '  Console.WriteLine(CStr(sidResult.Properties("name")(0)))
                                    lbGroups.Items.Add(groupname)
                                End If
                        '    End If
                        'End If



                    End If
                Next resultBytes
                lblgroup_refresh()
            End If
        Catch ex As Exception
            MsgBox("Error in GetGroups:" & vbNewLine & ex.Message, MsgBoxStyle.Critical)
        End Try
        Cursor = Cursors.Default
    End Sub

    Private Sub RBCheck1_CheckedChanged(sender As Object, e As EventArgs) Handles RBCheck1.CheckedChanged
        If RBCheck1.Checked Then
            Try
                Cursor = Cursors.WaitCursor
                Dim groups = GetActiveDirectoryGroups()
                lbGroups.Items.Clear()
                If Not IsNothing(groups) Then
                    For Each group In groups
                        'If Not IsNothing(DT_GROUPS_EXCLUSIVE) Then
                        '    If DT_GROUPS_EXCLUSIVE.Rows.Count > 0 Then
                        '        For Each GROUP_EXCL As DataRow In DT_GROUPS_EXCLUSIVE.Rows
                        '            If GROUP_EXCL.Item("GROUP_NAME").ToString.ToUpper = group.ToUpper Then
                        '                lbGroups.Items.Add(group)
                        '            End If
                        '        Next
                        '    Else
                        lbGroups.Items.Add(group)
                        '    End If
                        'End If
                    Next
                    lblgroup_refresh()
                End If
            Catch ex As Exception
                MsgBox("Error in Load Groups:" & vbNewLine & ex.Message, MsgBoxStyle.Critical)
            End Try
            Cursor = Cursors.Default
        End If
    End Sub
    Sub lblgroup_refresh()
        'If Not IsNothing(DT_GROUPS_EXCLUSIVE) Then
        '    If DT_GROUPS_EXCLUSIVE.Rows.Count > 0 Then
        '        lbllimited.Text = String.Format("AD-Groups are limited through configuration to '{0}' group(s)!", DT_GROUPS_EXCLUSIVE.Rows.Count)
        '        lbllimited.Visible = True
        '    Else
        '        lbllimited.Visible = False
        '    End If
        'Else
        lbllimited.Visible = False
        ' End If

    End Sub
End Class