Показать сообщение отдельно
Старый 19.11.2014, 19:36   #14  
Ivanhoe is offline
Ivanhoe
Участник
Аватар для Ivanhoe
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
4,143 / 2155 (80) +++++++++
Регистрация: 29.09.2005
Адрес: Санкт-Петербург
Утилита хороша, но как проверить в ней пересечение нескольких ролей?

Привожу код метода, который у меня работал и на R2, и сейчас работает на R3.

X++:
public boolean runas(UserId _userId)
{
    UserInfo                            locUserInfo;
    UserInfo                            tmpUserInfo;

    UserInfo                            userInfoRunAs;
    UserInfo                            tmpUserInfoRunAs;

    FileName                            fileConfiguration;
    int                                 iResult;
    int64                               numSessions;
    SysClientSessions                   sysClientSessions;
    int                                 timeStart;
    OverwriteSystemfieldsPermission     permission;
    xInfo                               xInfo = new xInfo();

    #WinAPI
    #Admin
    ;

    if(_userid == curuserid() || _userId == #AdminUser || curuserid() == #AdminUser)
    {
        throw error("!!!"); // тут метка про невозможность запуска
    }

    permission = new OverwriteSystemfieldsPermission();
    permission.assert();

    tmpUserInfo.setTmp();  //  для временного хранения текущего состояния
    tmpUserInfoRunAs.setTmp();
    try
    {
        ttsbegin;
        locUserInfo = xUserInfo::find(true, curuserid());
        tmpUserInfo.data(locUserInfo);

        userInfoRunAs = xUserInfo::find(true, _userId);
        tmpUserInfoRunAs.data(userInfoRunAs);

        //  подменить network привязку login'а
        userInfoRunAs.networkDomain = locUserInfo.networkDomain;
        userInfoRunAs.networkAlias = locUserInfo.networkAlias;
        userInfoRunAs.sid = locUserInfo.sid;
        userInfoRunAs.enable = NoYes::Yes;

        if(userInfoRunAs.validateWrite())
           userInfoRunAs.update();

        //  отключить активность текущего пользователя
        locUserInfo.sid = '';
        locUserInfo.enable = NoYes::No;

        if(locUserInfo.validateWrite())
           locUserInfo.update();
        ttscommit;
    }
    catch
    {
        return false;
    }


    fileConfiguration = '"' + xInfo::configuration() + '"';
    if (!WinApi::fileExists(fileConfiguration))
    {
        fileConfiguration = '-aos2=' + strreplace(conpeek(SysEmailSMTPPassword::currentAOSInstance(), 1), '@', ':');
    }
    select count(RecId) from sysClientSessions
        where sysClientSessions.userId    == userInfoRunAs.Id   &&
              sysClientSessions.sid       == userInfoRunAs.sid  &&
              sysClientSessions.Status    == 1;
    numSessions = sysClientSessions.RecId;
    iResult = WinAPI::shellExecute(xInfo::componentName(), fileConfiguration, '', #ShellExeOpen, #SW_SHOWNORMAL, false);

    if (iResult)
    {
        sysClientSessions.disableCache(true);
        timeStart = timenow();
        do
        {
            select count(recId) from sysClientSessions
                where sysClientSessions.userId    == userInfoRunAs.Id   &&
                      sysClientSessions.sid       == userInfoRunAs.sid  &&
                      sysClientSessions.Status    == 1;
            if (abs(timenow() - timeStart) > 10)
            {
                if (box::yesNo("...", DialogButton::No) == DialogButton::Yes) // тут текст, что клиент не успел стартовать - ждать еще или нет
                {
                    timeStart = timenow();
                }
                else
                {
                    break;
                }
            }
        }
        while (sysClientSessions.RecId <= numSessions);
    }

    //  восстановить исходное состояние данных
    ttsbegin ;
    locUserInfo        = xUserInfo::find(true, curuserid());
    locUserInfo.enable = tmpUserInfo.enable;
    locUserInfo.sid    = tmpUserInfo.sid;
    locUserInfo.defaultPartition = tmpUserInfo.defaultPartition;

    if(locUserInfo.validateWrite())
       locUserInfo.update();

    userInfoRunAs                   = xUserInfo::find(true, _userId);
    userInfoRunAs.networkDomain     = tmpUserInfoRunAs.networkDomain;
    userInfoRunAs.networkAlias      = tmpUserInfoRunAs.networkAlias;
    userInfoRunAs.sid               = tmpUserInfoRunAs.sid;
    userInfoRunAs.enable            = tmpUserInfoRunAs.enable;
    userinfoRunAs.defaultPartition  = tmpUserInfoRunAs.defaultPartition;

    if(userInfoRunAs.validateWrite())
       userInfoRunAs.update();
    ttscommit;

    CodeAccessPermission::revertAssert();

    return !iResult;
}
__________________
Ivanhoe as is..
За это сообщение автора поблагодарили: Oz (2), Logger (1).