RSS Подписка на статьи RSS Подписка на комментарии Панель инструментов

Блог профессионалов стал частью сайта технической поддержки DocsVision http://support.docsvision.com. Новые материалы будут появляться уже на этом сайте.

Поиск

Ярлыки

авто генерация кода (1) Администрирование DocsVision (60) Атрибутивный поиск (3) База данных (24) Базы знаний (1) Безопасность (1) Бизнес-процессы (20) Блог (2) Вы увидите это первыми (1) Групповые политики (1) Диаграммы (2) Задания (2) Интеграция (2) Карточки DocsVision (14) Конструктор Решений (11) Маркетинг и продажи (4) Навигатор (3) Новое (3) Новости (32) Опрос (4) Опросы DocsVision (4) Оптимизация (3) Отчеты (2) Ошибки (1) Поддержка (14) Полезные ссылки (1) Представления (4) Производительность (5) Разбор полетов (18) Разработка для Workflow (7) разработка карточек (2) Разработка на платформе DocsVision (41) Разработка решений (43) Расширение платформы (1) Расширенные отчеты (9) Решения на платформе DocsVision (6) Сервисы DocsVision (3) Сканеры (3) Справочник сотрудников (1) Справочник типов (1) Установка (1) Утилиты (13) Шлюз в SharePoint (8) Штрихкод (2) Cкрипты карточек (7) DocsVision внутри (1) DocsVision Live (1) FileStream (1) FireFox (2) Opera (1) Powershell (5) Safari (1) SharePoint2007 (1) SharePoint2010 (2) Silverlight (1) UltraViews (1) Vista (1)

Чтение прав карточки в сценарии бизнес-процесса

Для решения одного инцидента нам было необходимо фиксировать какой набор прав установлен на карточке в определенный момент времени. Конкретно, в определенных местах бизнес-процесса. Был разработан скрипт, который делает это.


Данные пишутся в журнал бизнес-процесса, соответственно попадают они и в журнал Workflow в режиме отладочных сообщений. Информация выводится в следующем виде:

Карточка документа: CardID
SecurityDescriptor:
Дескриптор безопасности
Пользователь: учетная запись и SID
AccessMask: Маска доступа и расшифровка
AceFlags: флаги
InheritanceFlags:флаги наследования
IsInherited: унаследованные ли права
PropagationFlags: распространение наследования

В скрипте есть недоработка. Строка
Dim oAccountName As NTAccount = DirectCast(oAce.SecurityIdentifier.Translate(GetType(NTAccount)), NTAccount)
может вызвать ошибку в случае если учетка удалена и у неё остался только SID, - в этом случае нельзя получить по SID имя записи. Надо обернуть в Try - Catch.
Скрипт сделан для платформы DocsVision 4.3

Сценарий бизнес-процесса на vb.net:


Option Explicit On
Option Strict On

' подключение системных библиотек
Imports System
Imports System.Xml
Imports System.Security.AccessControl
Imports System.Security.Principal
Imports System.Collections
Imports Microsoft.VisualBasic.Constants
Imports Microsoft.VisualBasic.Strings

' подключение библиотек СУБП
Imports DocsVision.Workflow.Objects
Imports DocsVision.Workflow.Runtime
Imports DocsVision.Workflow.Gates
Imports DocsVision.Platform.HelperAPI
Imports DocsVision.Platform.SecurityManager


Namespace DVScriptHost

    Public Class DVScript
        Dim m_oGate As DVGate
        ' получаем сессию
        Dim m_oSession As DocsVision.Platform.ObjectManager.UserSession
        Dim m_oLastBytes As Byte()

        Private Enum DVRights As Integer

            READ = &H1              ' Чтение, специальное
            WRITE = &H2             ' Изменение
            CREATE_CONTENT = &H4    ' Создание дочерних
            DELETE_CONTENT = &H8    ' Удаление дочерних
            COPY = &H10             ' Копирование

            ' Standard rights
            DELETE = &H10000        ' Удаление
            READ_CONTROL = &H20000  ' Чтение, стандартное
            WRITE_DAC = &H40000     ' Изменение разрешений
            WRITE_OWNER = &H80000   ' Смена владельца
            SYNCHRONIZE = &H100000  ' Не используется

            ACCESS_SYSTEM_SECURITY = &H1000000  ' Изменение параметров безопасности

            ' Generic rights
            GENERIC_ALL = &H10000000        ' Полный доступ
            GENERIC_EXECUTE = &H20000000    ' Выполнение
            GENERIC_WRITE = &H40000000      ' Изменение
            GENERIC_READ = &H80000000       ' Чтение

        End Enum
        Public Sub Execute(ByVal process As ProcessInfo, ByVal passInfo As PassState)

            Try
                ' получаем шлюз
                m_oGate = CType(process.Gates(DVGate.GateID), DVGate)
                ' получаем сессию
                m_oSession = m_oGate.Session

                Dim varDocCard As ProcessVariable
                varDocCard = process.GetVariableByName("Карточка")


                Dim oCard As DVCard = CType(varDocCard.Value, DVCard)

                Dim oAccounts As New ArrayList

                Dim oSecurityDesc As CommonSecurityDescriptor = GetCardDescriptor(process, oCard.ID)

                oAccounts = GetAccountsFromDescriptor(oSecurityDesc)

                process.LogMessage(GetLogMessage(oCard.ID, oAccounts))


            Catch Err As Exception

                ' запись в журнал ошибки исполнения
                process.LogMessage("Ошибка выполнения скрипта:" + Err.Message)

            End Try

        End Sub

        Private Function GetCardDescriptor(ByRef process As ProcessInfo, ByVal CardID As String) As CommonSecurityDescriptor
            Dim oSecureCard As DocsVision.Platform.SecurityManager.ISecureObject = m_oSession.AccessManager.GetSecureCard(CardID)
            Dim oDescBytes As Byte() = DirectCast(oSecureCard.GetSecurity(SecurityInformationEnum.siDacl), Byte())

            ' Получаем объект типа CommonSecurityDescriptor из массива byte() для карточки 
            Dim oSecurityDesc As CommonSecurityDescriptor = New CommonSecurityDescriptor(True, False, oDescBytes, 0)

            m_oLastBytes = oDescBytes
            Return oSecurityDesc

        End Function

        Private Function GetAccountsFromDescriptor(ByVal oSecurityDesc As CommonSecurityDescriptor) As ArrayList
            Dim oAccounts As New ArrayList

            Dim oACL As DiscretionaryAcl = oSecurityDesc.DiscretionaryAcl
            For Each oACE As CommonAce In oACL
                oAccounts.Add(oACE)
            Next
            Return oAccounts
        End Function

        Private Function GetLogMessage(ByVal CardID As String, ByVal oAccounts As ArrayList) As String
            Dim sResult As String = "Карточка документа:" + CardID + vbCrLf
            sResult += "SecurityDescriptor: " + Convert.ToBase64String(m_oLastBytes) + vbCrLf
            For Each oAce As CommonAce In oAccounts
                Dim oAccountName As NTAccount = DirectCast(oAce.SecurityIdentifier.Translate(GetType(NTAccount)), NTAccount)
                sResult += "Пользователь: " + oAccountName.Value.ToString + " (" + oAce.SecurityIdentifier.ToString + ")" + vbCrLf
                sResult += vbTab + "AccessMask:" + vbTab + oAce.AccessMask.ToString + "(" + Decompose(oAce.AccessMask) + ")" + vbCrLf
                sResult += vbTab + "AceFlags:" + vbTab + oAce.AceFlags.ToString + vbCrLf
                sResult += vbTab + "InheritanceFlags:" + vbTab + oAce.InheritanceFlags.ToString + vbCrLf
                sResult += vbTab + "IsInherited:" + vbTab + oAce.IsInherited.ToString + vbCrLf
                sResult += vbTab + "PropagationFlags:" + vbTab + oAce.PropagationFlags.ToString + vbCrLf
            Next

            Return sResult
        End Function

        Private Function Decompose(ByVal iAccessMask As Integer) As String
            Dim sResult As String = vbNullString


            If (iAccessMask And DVRights.ACCESS_SYSTEM_SECURITY) <> 0 Then
                sResult += "+ACCESS_SYSTEM_SECURITY"
            End If



            If (iAccessMask And DVRights.COPY) <> 0 Then
                sResult += "+COPY"
            End If



            If (iAccessMask And DVRights.CREATE_CONTENT) <> 0 Then
                sResult += "+CREATE_CONTENT"
            End If

            If (iAccessMask And DVRights.DELETE) <> 0 Then
                sResult += "+DELETE"
            End If

            If (iAccessMask And DVRights.DELETE_CONTENT) <> 0 Then
                sResult += "+DELETE_CONTENT"
            End If

            If (iAccessMask And DVRights.GENERIC_ALL) <> 0 Then
                sResult += "+GENERIC_ALL"
            End If

            If (iAccessMask And DVRights.GENERIC_EXECUTE) <> 0 Then
                sResult += "+GENERIC_EXECUTE"
            End If

            If (iAccessMask And DVRights.GENERIC_READ) <> 0 Then
                sResult += "+GENERIC_READ"
            End If

            If (iAccessMask And DVRights.GENERIC_WRITE) <> 0 Then
                sResult += "+GENERIC_WRITE"
            End If

            If (iAccessMask And DVRights.READ) <> 0 Then
                sResult += "+READ"
            End If

            If (iAccessMask And DVRights.READ_CONTROL) <> 0 Then
                sResult += "+READ_CONTROL"
            End If

            If (iAccessMask And DVRights.SYNCHRONIZE) <> 0 Then
                sResult += "+SYNCHRONIZE"
            End If

            If (iAccessMask And DVRights.WRITE) <> 0 Then
                sResult += "+WRITE"
            End If

            If (iAccessMask And DVRights.WRITE_DAC) <> 0 Then
                sResult += "+WRITE_DAC"
            End If

            If (iAccessMask And DVRights.WRITE_OWNER) <> 0 Then
                sResult += "+WRITE_OWNER"
            End If

            If sResult <> vbNullString Then sResult = Right(sResult, Len(sResult) - 1)
            Return sResult
        End Function
    End Class

End Namespace


UPD. Убрал лишнее
Читать дальше

2 коммент.:

Unknown комментирует...

А для 4.0 что изменить придется?

Михаил Захаров комментирует...

в 4.0 нужно изменить строки
Dim oSecureCard As DocsVision.Platform.SecurityManager.ISecureObject = m_oSession.AccessManager.GetSecureCard(CardID)
Dim oDescBytes As Byte() = DirectCast(oSecureCard.GetSecurity(SecurityInformationEnum.siDacl), Byte())

на

Dim oSecureCard As DocsVision.Platform.ObjectManager.ISecurable = m_oSession.AccessManager.GetSecureCard(CardID)
Dim oDescBytes As Byte() = DirectCast(oSecureCard.SecurityDescriptor, Byte())

Отправить комментарий