Разработка
24
Мар
10

Проверка наличия определенной роли у пользователя в плагине

Как ясно из названия, данный пример демонстрирует, как сделать проверку на наличие определенной роли у определенного пользователя в плагине:

  • Создайте новый плагин и повесьте на него такой код:
    using System;
    using Microsoft.Crm.Sdk;
    using Microsoft.Crm.Sdk.Query;
    using Microsoft.Crm.SdkTypeProxy;
    
    namespace CheckRole
    {
        public class HelloWorldPlugin : IPlugin
        {
            public void Execute(IPluginExecutionContext context)
            {
                // Настраиваем CRM Service через контекст плагина
                ICrmService crmService = context.CreateCrmService(true);
    
                // Запрашиваем все роли пользователя вызвавшего плагин
                BusinessEntityCollection Roles = GetUserRoles(context.UserId, crmService);
    
                // Просматриваем все возвращенные роли
                foreach (BusinessEntity role in Roles.BusinessEntities)
                {
                    DynamicEntity DynamicRole = (DynamicEntity)role;
                    string roleName = DynamicRole.Properties["name"].ToString();
    
                    // Если название роли равно определенному значению, то...
                    if (roleName == "Системный администратор")
                    {
                        // Выводим сообщение
                        throw new Exception("Аве Цезарь!");
                    }
                }
            }
    
            // Функция возвращает набор ролей назначенных конкретному пользователю
            public BusinessEntityCollection GetUserRoles(Guid guidUserID, ICrmService serv)
            {
                try
                {
                    QueryExpression qe = new QueryExpression();
                    qe.EntityName = "role";
                    qe.ColumnSet = new AllColumns();
                    
                    LinkEntity le = new LinkEntity();
                    le.LinkFromEntityName = "role";
                    le.LinkFromAttributeName = "roleid";
                    le.LinkToEntityName = "systemuserroles";
                    le.LinkToAttributeName = "roleid";
                    
                    ConditionExpression ce = new ConditionExpression();
                    ce.AttributeName = "systemuserid";
                    ce.Operator = ConditionOperator.Equal;
                    ce.Values = new object[] { guidUserID };
                    
                    LinkEntity le2 = new LinkEntity();
                    le2.LinkFromEntityName = "systemuserroles";
                    le2.LinkFromAttributeName = "systemuserid";
                    le2.LinkToEntityName = "systemuser";
                    le2.LinkToAttributeName = "systemuserid";
                    le2.LinkCriteria = new FilterExpression();
                    le2.LinkCriteria.Conditions.Add(ce);
                    le.LinkEntities.Add(le2);
                    qe.LinkEntities.Add(le);
                    
                    RetrieveMultipleRequest rmRequest = new RetrieveMultipleRequest();
                    rmRequest.ReturnDynamicEntities = true;
                    rmRequest.Query = qe;
                    
                    RetrieveMultipleResponse response = (RetrieveMultipleResponse)serv.Execute(rmRequest);
    
                    if (response.BusinessEntityCollection.BusinessEntities.Count > 0)
                    {
                        return response.BusinessEntityCollection;
                    }
                    else
                    {
                        return null;
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.ToString());
                }
            }
        }
    }
    

    Подправьте в нем искомую роль (ну или добавьте еще какую-нибудь логику 🙂 );

  • Зарегистрируйте плагин в CRM и вызовите событие на которое он зарегистрирован…


Тоже самое можне реализовать и с помощью JavaScript: Отображение и скрытие полей в зависимости от роли пользователя.

Комментарии (10)
  • Vladislav Osmanov 24.03.2010

    Можно написать extension для CrmService с новым методом:
    bool HasRole(Guid sustemuserid, string roleName);

    Расширение для CrmService, т.к. в плагине нам из контекста доступен Guid пользователя, а не сам systemuser. В идеале это должно быть расширеине systemuser’а.

    Ну, а потом из кода:
    if (crmService.UserHasRole(userId, «Системный администратор»))
    {
    // Выводим сообщение

    }

    Да, и имя роли вынести в конфиг и/или заменить на Guid роли : )

    P.S. Вот тут уже поднимался вопрос расширений: http://blog.customereffective.com/blog/2009/11/dynamic-entity-helpers-using-extension-methods.html

  • slivka_83 24.03.2010

    > extension для CrmService
    А можно как-нить попроще объяснить что такое extension для людей не искушенный в программировании? 🙂

    > Расширение для CrmService, т.к. в плагине нам из контекста доступен Guid пользователя, а не сам systemuser
    А что такое systemuser? и чем он отличается от «Guid пользователя» 🙂 И чем нам не подходит «Guid пользователя»? Ведь это Guid юзвера вызвавшего плагин? или нет? 🙂

  • Дима 24.03.2010

    Здравствуйте, заранее извиняюсь за оффтоп, но эта тема мне показалась наиболее близкой к сути вопроса.
    Подскажите пожалуйста, существует ли возможность каким-то образом отслеживать событие изменения перечня ролей пользователей и если да, то какие есть варианты?

  • slivka_83 24.03.2010

    Здрасьте 🙂
    Месседж плагина мне не известен такой. Поэтому на ум приходит только тригер в БД 🙂

  • slivka_83 24.03.2010

    Я тут подумал… с пользователя есть связь с ролями (назвается systemuserroles_association) так что скорее всего Вы сможете отслеживать (плагином) добавление/удаление ролей от картчоки пользователя с помощью сообщений Associate/Disassociate.

  • Дима 24.03.2010

    Спасибо за ответ! Я тоже так думал, но мои попытки воспользоваться этим решением не увенчались успехом, возможно я что-то делал не правильно.. Решение удалось найти по вот этой ссылке — http://www.knowledgeexchanger.com/ms-crm-tips/how-to-audit-privileges-changes-security-role-on-ms-crm-4-0/. Оказывается есть определенный список сообщений, которые просто по сути являются неактивными, среди них оказались и нужные мне: ‘AssignUserRoles’ и ‘RemoveUserRoles’. Воспользовавшись первым предложенным в стастье sql скриптом, мне удалось активировать эти события, ну а дальше дело в шляпе. Еще раз спасибо за ваш ответ.

  • Sergey 24.03.2010

    А как сделать так, чтобы этот плагин отработал, когда я из карточки Бизнес-партнера запускаю создание обращени? Мне нужно по наличию определенной роли у пользователя, заполнить поля в этом обращении. Скажем, для примера, При создании обращения из карточки Бизнес партнера пользователем с ролью «Системный администратор» создавать обращение в котором заголовок автоматом заполнен и равен «Сервисное обращение».

  • slivka_83 24.03.2010

    Ну вешаете на Pre создания обращения плагин. Из контекста получаете GUID текущего пользователя, выозвращаете его Роли и проверяете их. Потом на вход этапа создания подставляете нужные Вам данные.

  • Sergey 24.03.2010

    Насчет первой части, понятно. Я так и сделал. Повесил плагин на Пре в синхронном режиме. Но он отрабатывает только в момент, когда я сохраняю заполненное обращение а не в момент, когда открывается карточка. Как повесить его на вход этапа создания, не совсем понятно?

  • slivka_83 24.03.2010

    Тогда Вам нужно использовать не пагин, а скрипты на онлоад. Проверить есть ли у текущего окна родительское (Бизнес-партнер), и если да то выполнить бизнес-логику.

*

code