Imports WINDREAMLib
Imports DD_LIB_Standards
Public Class ClassWDRights
#Region "+++++ Konstanten +++++"
    Const REL_Document_AccessRight = "AccessRight"
    Const COL_AccessRight_AccessRightID = "dwAccessRightID"
    Const COL_AccessRight_AccessRight = "dwAccessRight"
    Const REL_AccessRight_UserOrGroup = "AccessRightUserOrGroup"


    Const WMAccessRightUndefined = 0
    Const WMAccessRightRead = 1
    Const WMAccessRightWrite = 2
    Const WMAccessRightReadWrite = 3
    Const WMAccessRightAdmin = 4
    Const WMAccessRightAllRights = 7             ' doc+folder: read, write and admin access

    Const WMUserTypeMain = 1
    Const WMUserTypeNormal = 4
    Const WMUserTypeInactive = 8

    Const WMGroupTypeAdmin = 2

    Const WMEntityGroups = 13
    Const WMEntityUser = 18
    Const WMGroupTypeAll = 127

#End Region
#Region "+++++ Variables +++++"
    Public Shared AD_DOMAIN As String
    Public Shared AD_USER As String
    Public Shared AD_USER_PW As String
    Public Shared AD_SERVER As String
    Public Shared WD_RIGHT_ADMIN As Integer
    Public Shared MSG_RESULT = ""
#End Region
    Public Shared Function Init()
        Try
            MSG_RESULT = ""
            LOGGER.Debug(String.Format("Init ClassWDRights started - " & Now & " ..."))
            Dim DT_KONFIG As DataTable = MYDB_ECM.GetDatatable("SELECT * FROM TBPMO_SERVICE_RIGHT_CONFIG WHERE GUID = 1")
            AD_DOMAIN = DT_KONFIG.Rows(0).Item("AD_DOMAIN")
            AD_USER = DT_KONFIG.Rows(0).Item("AD_USER")
            WD_RIGHT_ADMIN = DT_KONFIG.Rows(0).Item("WD_RIGHT")
            If clsDatabase.DB_PROXY_INITIALIZED = True And ClassProxy.MyLinkedServer <> String.Empty Then
                LOGGER.Info("User configured a proxy: " & ClassProxy.MyLinkedServer)
                AD_SERVER = ClassProxy.MyLinkedServer
            Else
                AD_SERVER = DT_KONFIG.Rows(0).Item("AD_SERVER")
            End If

            Dim PWplainText As String
            Dim wrapper As New ClassEncryption("!35452didalog=")
            ' DecryptData throws if the wrong password is used.
            Try
                PWplainText = wrapper.DecryptData(DT_KONFIG.Rows(0).Item("AD_USER_PW"))
            Catch ex As Exception
                LOGGER.Warn("The Userpassword could not be decrypted")
                PWplainText = ""
            End Try
            AD_USER_PW = PWplainText

            LOGGER.Debug(String.Format("ClassWDRights Init'ed - AD_DOMAIN: '{0}', AD_USER: '{1}', AD_SERVER: '{2}'", AD_DOMAIN, AD_USER, AD_SERVER))
            Return True
        Catch ex As Exception
            LOGGER.Warn("Unexpected Error in ClassRights Init: " & vbNewLine & ex.Message)
            Return False
        End Try
    End Function
    Public Shared Function Doc_Renew_Rights(doc_id As Integer, reldocpath As String, deleterights As Boolean) As Boolean
        Try
            LOGGER.Debug(String.Format("Working on rights for file: {0}", reldocpath))
            Dim DT_USER_RIGHT As DataTable
            Dim DT_GROUP_RIGHT As DataTable
            Dim oSession
            Dim oWMObject As WINDREAMLib.WMObject
            Dim UserGroupRelation
            Dim UserOrGroup
            Dim oUSer
            reldocpath = ClassHelper.GetRelPath(reldocpath)

            Try
                'Dedizierte Session herstellen
                oSession = GetWMSessionAsUser(AD_DOMAIN, AD_SERVER, AD_USER, AD_USER_PW)
            Catch ex As Exception
                Dim msg = "Error in Doc_Renew_Rights-GetWMSessionAsUser : " & ex.Message
                LOGGER.Warn(msg)
                Return False
            End Try

            If Not IsNothing(oSession) Then
                LOGGER.Debug("Session created.")
                Dim sql = String.Format("SELECT * FROM [dbo].[FNPMO_GET_RIGHTS_FOR_DOC] ({0}) where USER_OR_GROUP = 'USER'", doc_id)
                DT_USER_RIGHT = MYDB_ECM.GetDatatable(sql)
                sql = String.Format("SELECT * FROM [dbo].[FNPMO_GET_RIGHTS_FOR_DOC] ({0}) where USER_OR_GROUP = 'GROUP'", doc_id)
                DT_GROUP_RIGHT = MYDB_ECM.GetDatatable(sql)
                If IsNothing(DT_USER_RIGHT) Then
                    Dim msg = "Error while receiving rights for DocID"
                    clsLogger.Add(msg)
                    Return False
                Else
                    LOGGER.Debug(String.Format("Amount of Userrights: {0}", DT_USER_RIGHT.Rows.Count))
                End If
                LOGGER.Debug(String.Format("Amount of Grouprights: {0}", DT_GROUP_RIGHT.Rows.Count))
                Try
                    'Object definieren
                    oWMObject = oSession.GetWMObjectByPath(1, reldocpath)
                    LOGGER.Debug("Object created.")
                Catch ex As Exception
                    Dim msg = "Error GetWMObjectByPath: (FDSR) " & reldocpath & vbNewLine & Err.Description
                    LOGGER.Warn(msg)
                    Return False
                End Try
                Dim lret
                Try
                    ' Objekt muss zur Rechteänderung gelockt werden
                    lret = oWMObject.LockRights()
                Catch ex As Exception
                    Dim msg = "Error while locking file" & ex.Message
                    LOGGER.Warn(msg)
                    Return False
                End Try

                LOGGER.Debug("Object locked.")
                If CBool(lret) = False Then
                    Dim msg = "Error in setting lock .LockRights - Err.Number: " & Err.Number & vbCrLf & Err.Description
                    LOGGER.Warn(msg)
                    Return False
                End If

                ' Rechteträger-Liste holen
                Dim AccessRights
                AccessRights = oWMObject.GetWMObjectRelationByName(REL_Document_AccessRight)
                LOGGER.Debug("AccessRights created.")
                'Bei Fehler in Rechteauswertung
                If Err.Number <> 0 Then
                    Dim msg = "Error in setting REL_Document_AccessRight - Err.Number: " & Err.Number & vbCrLf & Err.Description
                    LOGGER.Warn(msg)
                    Return False
                End If
                '############################# Rechte löschen ################################################################################
                '#############################################################################################################################
                If deleterights = True Then
                    LOGGER.Debug("rights for document will now be deleted.")
                    'Erst einmal alle anderen Rechte löschen
                    Dim i As Integer = 1
                    ' und nun jeden Rechteträger verarbeiten
                    For Each aRightRelation In AccessRights

                        ' Auflistung der Rechteträger-Informationen holen
                        UserGroupRelation = aRightRelation.GetWMObjectRelationByName(REL_AccessRight_UserOrGroup)
                        If Err.Number <> 0 Then
                            Dim msg = "Error in setting REL_AccessRight_UserOrGroup - Err.Number: " & Err.Number & vbCrLf & Err.Description
                            LOGGER.Warn(msg)
                            Return False
                        End If

                        ' Zugriff auf das Benutzer/Gruppen-Objekt
                        UserOrGroup = UserGroupRelation.item(0)
                        Dim _msg As String

                        If (UserOrGroup.aWMEntity = WMEntityGroups) Then
                            _msg = "Right for Group '" & UserOrGroup.aName & "'"""
                        Else
                            _msg = "Right for User: '" & UserOrGroup.aName & "'"""
                        End If
                        LOGGER.Debug(String.Format("[{0}] will now be deleted.", _msg))
                        If Err.Number <> 0 Then
                            Dim msg = "Error in setting UserGroupRelation - Err.Number: " & Err.Number & vbCrLf & Err.Description
                            LOGGER.Warn(msg)
                            Return False
                        End If

                        'einem Rechteträger ALLE Rechte zu entziehen 
                        'entfernt ihn gleichzeitig aus der Auflistung der Rechteträger
                        Try
                            AccessRights.Delete2(UserOrGroup, WMAccessRightAllRights)
                        Catch ex As Exception
                            Dim msg = "Error in AccessRights.Delete2 (Doc_RenewRights)  Doc-ID: " & doc_id & " - UserGroup: " & UserOrGroup.aName & " - ErrorMsg: " & ex.Message
                            LOGGER.Warn(msg)
                            Continue For
                        End Try
                        i += 1
                        _msg = _msg.Replace(" '", "")
                        LOGGER.Debug(String.Format("{0} was deleted.", _msg))
                    Next
                    LOGGER.Debug("All rights for doc were deleted....")
                End If

                Err.Clear()
                ' Wenn ALLE Rechteträger entfernt werden (FOR EACH), 
                ' dann muss mindestens EIN Rechteträger mit dem Recht zur Rechteänderung 
                ' wieder zugefügt werden!!!!! Dies ist der OrgFlow-Right User!
                'Für jeden User das Recht einzeln hinzufügen
                For Each User_Row As DataRow In DT_USER_RIGHT.Rows
                    Dim fileright 'Recht als Integer
                    Dim StringUserRight
                    Try
                        StringUserRight = AD_DOMAIN & "\" & User_Row.Item("USR_NAME")
                        fileright = User_Row.Item("USR_RIGHT")
                        LOGGER.Debug(String.Format("Working on right for user-right: {0}-{1}", StringUserRight, fileright))
                        Try
                            ' User holen
                            oUSer = oSession.GetWMObjectByName(WMEntityUser, StringUserRight)
                            LOGGER.Debug("got oUSer...")
                        Catch ex As Exception
                            Dim msg = String.Format("Could not create windream-Usersession for user '{0}' - check whether user is part of windream-group!", StringUserRight)
                            LOGGER.Warn(msg)
                            MSG_RESULT &= msg & vbNewLine
                            Continue For
                        End Try
                        If Not IsNothing(oUSer) Then
                            Try
                                AccessRights.Insert2(oUSer, fileright) 'WMAccessRightAllRights)
                                LOGGER.Debug("Right was set...")
                            Catch ex As Exception
                                Dim msg = String.Format("Could not set right for user {0} - AccessRights.Insert2: {1}", StringUserRight, ex.Message)
                                LOGGER.Warn(msg)
                                Continue For
                            End Try
                        End If

                    Catch ex As Exception
                        Dim _right
                        Select Case fileright
                            Case WMAccessRightRead
                                _right = "READ"
                            Case WMAccessRightWrite
                                _right = "WRITE"
                            Case WMAccessRightAdmin
                                _right = "ADMIN"
                            Case WMAccessRightAllRights
                                _right = "ALL RIGHTS"
                            Case WMAccessRightReadWrite
                                _right = "READ WRITE"
                        End Select
                        MSG_RESULT &= String.Format("Error while working on RightChange:" & vbNewLine & "Fileright: {0}" & vbNewLine & "User: {1} " & vbNewLine & "File: {2}", _right, StringUserRight, reldocpath) & vbNewLine
                        LOGGER.Warn(ex.Message)
                    End Try
                Next

                'Für jede Gruppe das Recht einzeln hinzufügen

                For Each Group_Row As DataRow In DT_GROUP_RIGHT.Rows
                    Dim fileright 'Recht als Integer
                    Dim StringGroupRight
                    Dim _oGroup
                    Try
                        StringGroupRight = AD_DOMAIN & "\" & Group_Row.Item("USR_NAME")
                        fileright = Group_Row.Item("USR_RIGHT")
                        LOGGER.Debug(String.Format("Working on right for group-right: {0}-{1}", StringGroupRight, fileright))
                        Try
                            ' User holen
                            _oGroup = oSession.GetWMObjectByName(WMEntityGroups, StringGroupRight)

                            LOGGER.Debug("got Group...")
                        Catch ex As Exception
                            Dim msg = String.Format("Could not create windream-Usersession for group '{0}' - check whether group exists in windream!", StringGroupRight)
                            clsLogger.Add(msg)
                            MSG_RESULT &= msg & vbNewLine
                            Continue For
                        End Try
                        If Not IsNothing(_oGroup) Then
                            Try
                                AccessRights.Insert2(_oGroup, fileright) 'WMAccessRightAllRights)
                                LOGGER.Debug("Right was set...")
                            Catch ex As Exception
                                Dim msg = String.Format("Could not set right for docID: {0} group {1} - AccessRights.Insert2: {2}", doc_id, StringGroupRight, ex.Message)
                                clsLogger.Add(msg)
                                Continue For
                            End Try
                        End If

                    Catch ex As Exception
                        Dim _right
                        Select Case fileright
                            Case WMAccessRightRead
                                _right = "READ"
                            Case WMAccessRightWrite
                                _right = "WRITE"
                            Case WMAccessRightAdmin
                                _right = "ADMIN"
                            Case WMAccessRightAllRights
                                _right = "ALL RIGHTS"
                            Case WMAccessRightReadWrite
                                _right = "READ WRITE"
                        End Select
                        MSG_RESULT &= String.Format("Error while working on RightChange2:" & vbNewLine & "Fileright: {0}" & vbNewLine & "Group: {1} " & vbNewLine & "File: {2}", _right, StringGroupRight, reldocpath) & vbNewLine
                        clsLogger.Add(ex.Message)
                    End Try
                Next

                Try
                    'Speichern nicht vergessen
                    oWMObject.Save()
                    LOGGER.Debug("Doc was saved...")
                Catch ex As Exception
                    Dim msg = String.Format("Error at Object2Change.Save - DocID ({0}): {1}", doc_id, ex.Message)
                    LOGGER.Warn(msg)
                    If oWMObject.aLocked = True Then
                        oWMObject.unlock()
                        LOGGER.Debug("Doc unlocked after error!")
                    End If
                    Return False
                End Try

                'und der Vollständigkeit halber auch ein Unlock
                If oWMObject.aLocked = True Then
                    Try
                        oWMObject.unlock()
                        LOGGER.Debug("Doc was unlocked...")
                    Catch ex As Exception
                        Dim msg = "Fehler bei Unlock - Error: " & ex.Message
                        LOGGER.Warn(msg)
                        Return False
                    End Try
                End If
                ClassHelper.InsertEssential_Log(doc_id, "DOC-ID", "Rights for doc successfully renewed - Doc_Renew_Rights")
                'jetzt True zurückgeben
                Return True
            Else
                Dim msg = "ERROR : no session could be created (3)!"
                LOGGER.Warn(msg)
                Return False
            End If
        Catch ex As Exception
            LOGGER.Warn(String.Format("Unexpected Error while Doc_Renew_Rightss DocID: {0}", doc_id))
            Dim msg = "ErrorMessage: " & vbNewLine & ex.Message
            LOGGER.Warn(msg)
            Return False
        End Try
    End Function

    Public Shared Function GetWMSessionAsUser(Domain, ServerName, UserName, Password)
        Try
            Dim SessionAsUser
            Dim aConnect, aUserId, aSession

            ' Hilfsobjekte erschaffen, um eine Verbindung zum windream Server herzustellen
            ' mit der gewünschten Benutzer-Identität
            aConnect = CreateObject("Windream.WMConnect")
            'Bei einer impersonifizierten Session ist zu beachten, dass die ModuleID 9 zu nutzen ist. 
            'Wird keine Session-ID angegeben, hat die Session die ID 0 (‚Default‘).
            aConnect.ModuleId = 9
            If Err.Number <> 0 Then
                Dim msg = "Error in CreateObject (aConnect) - Err.Number: " & Err.Number & vbNewLine & Err.Description
                LOGGER.Warn(msg)

                SessionAsUser = Nothing
                Return SessionAsUser
            End If

            aUserId = CreateObject("WMOTool.WMUserIdentity")
            If Err.Number <> 0 Then
                Dim msg = "Error in CreateObject('WMOTool.WMUserIdentity') - Err.Number: " & Err.Number & vbNewLine & Err.Description
                LOGGER.Warn(msg)
                SessionAsUser = Nothing
                Return SessionAsUser
            End If

            aUserId.aDomain = Domain
            aUserId.aServerName = ServerName
            aUserId.aUserName = UserName
            aUserId.aPassword = Password

            aSession = aConnect.Login(aUserId)


            If Err.Number <> 0 Then
                Dim msg = "Error in Connect.Login(aUserId) - Err.Number: " & Err.Number & vbNewLine & Err.Description
                LOGGER.Warn(msg)
                SessionAsUser = Nothing
                Return SessionAsUser
            Else
                SessionAsUser = aSession
                If aSession.aLoggedin = True Then
                    Return SessionAsUser
                End If

            End If
        Catch ex As Exception
            Dim msg = "Unexpected Error in DDLibraries-GetWMSessionAsUser: " & ex.Message & vbNewLine & _
                String.Format("Domain: {0}, ServerName: {1}, UserName: {2}, Password: {3},", Domain, ServerName, UserName, Password)
            LOGGER.Warn(msg)
            Return Nothing
        End Try

    End Function
End Class
