Authorization in Substitute

Hello Friends,
I am facing an problem whenever an user create an substitute for him.
Let me explain the problem.
Suppose user grade is 15 and he is going for leave for 10 days so He want to make a substitue and his substitute's grade is 13 which is lower than 15. His substitute dont have all the required authorization.
Now, we are assinging all the missing roles to his substitute. It is working fine.
But it does not like a good solution Is there any way to do it at the time when user create a substitute for him.
I have a small doubt also.
Suppose an user create a subtitute in active stage for 10 days. and after 10 days, the substitution period get expired but the substitute can also see the workitems which are created during the substitution period. 
Any solution for this problem.
Thanks & Regards,
Manoj

> Let say Some workitem are in process state, They get replaced maunally through SWIA after the substituion period expired. In case, these workitem should not get appeared in Substitute Inbox but it is appearing.
>
SAP obviously do not agree with you
You can observe the same if you as an administrator start executing a work item. If you replace it, you will still be among the agents, even if you weren't originally one of the users receiving the work item. I suppose SAP has been thinking that as long as you have "touched" the work item you are relevant, and that what you observe for substitutes is just a (wanted or unwanted) side-effect.
The user can create many substitutes. You can imagine a situation where a user with high authorization delegates his work items to two people with less authorization. Each of them will see what he/she is authorized to see.
There is a difference between a substitute in SAP Business Workflow and a substitute taking over your job responsibility. The latter needs all the authorizations you had in order to be able to fully replace you, but the workflow substitutes are not necessarily taking over every responsibility you had. It could be they are just off-loading you in one of your roles, in which case you definitely do not want them to get all your authorizations.
Most areas in SAP are capable of handling more complex scenarios than most customers use, and then the solutions sometimes seem to be incorrect - or unnecessarily complex.

Similar Messages

  • HOW TO Developing an Authorization plug-in

    #if defined (_WIN32)
    #pragma warning(disable : 4996)
    BOOL WINAPI DllMain(
        HINSTANCE hinstDLL,  // handle to DLL module
        DWORD fdwReason,     // reason for calling function
        LPVOID lpReserved )  // reserved
    return TRUE;
    #endif
    How to create here
    /*----------------------------------------------------------------------------+
    |       ___     _       _                                                    |
    |      /   |   | |     | |                                                   |
    |     / /| | __| | ___ | |__   ___                                           |
    |    / /_| |/ _  |/ _ \|  _ \ / _ \                                          |
    |   / ___  | (_| | (_) | |_) |  __/                                          |
    |  /_/   |_|\__,_|\___/|____/ \___|                                          |
    |                                                                            |
    |                                                                            |
    |  ADOBE CONFIDENTIAL                                                        |
    |  __________________                                                        |
    |                                                                            |
    |  Copyright (c) 2003 - 2010, Adobe Systems Incorporated.                    |
    |  All rights reserved.                                                      |
    |                                                                            |
    |  NOTICE:  All information contained herein is, and remains the property    |
    |  of Adobe Systems Incorporated and its suppliers, if any. The intellectual |
    |  and technical concepts contained herein are proprietary to Adobe Systems  |
    |  Incorporated and its suppliers and may be covered by U.S. and Foreign     |
    |  Patents, patents in process, and are protected by trade secret or         |
    |  copyright law. Dissemination of this information or reproduction of this  |
    |  material is strictly forbidden unless prior written permission is         |
    |  obtained from Adobe Systems Incorporated.                                 |
    |                                                                            |
    |          Adobe Systems Incorporated       415.832.2000                     |
    |          601 Townsend Street              415.832.2020 fax                 |
    |          San Francisco, CA 94103                                           |
    |                                                                            |
    +----------------------------------------------------------------------------*/
    #include "StdAfx.h"
    #include "FmsAuthAdaptor.h"
    #include "FmsAuthActions.h"
    #include "FmsMedia.h"
    #include <stdio.h>
    #include <fcntl.h>
    #include <string.h>
    #include "hash.h"
    #include <sstream>
    #if defined (_WIN32)
    #pragma warning(disable : 4996)
    BOOL WINAPI DllMain(
        HINSTANCE hinstDLL,  // handle to DLL module
        DWORD fdwReason,     // reason for calling function
        LPVOID lpReserved )  // reserved
    return TRUE;
    #endif
    // Flag to process SWF Verification in this auth sample.  A real SWF file
    // must be targeted in the SWFVerification code below for the example to work.
    static const bool kAuthorizeSwfVerification = false;
    class FmsAuthAdaptor : public IFmsAuthAdaptor
    public:
      FmsAuthAdaptor(IFmsAuthServerContext2* pFmsAuthServerContext)
       : m_pFmsAuthServerContext(pFmsAuthServerContext) {}
      virtual ~FmsAuthAdaptor() {}
      void authorize(IFmsAuthEvent* pAev);
      void notify(IFmsAuthEvent* pAev);
      void getEvents(I32 aevBitAuth[], I32 aevBitNotf[], unsigned int count);
    private:
      bool getStats(I64 clientStatsHandle, FmsClientStats& baseStats);
      void processStats(IFmsAuthEvent* pAev);
      IFmsAuthServerContext2* m_pFmsAuthServerContext;
    // Utils
    // Note: Do not delete the return value.  The return value is a buffer
    // allocated in FMS memory space, and FMS will manage the memory.
    static char* getStringField(const IFmsAuthEvent* pEv, IFmsAuthEvent::Field prop)
    FmsVariant field;
    if (pEv->getField(prop, field) == IFmsAuthEvent::S_SUCCESS && field.type == field.kString)
      return reinterpret_cast<char*>(field.str);
    return 0;
    // Note: Do not delete the return value.  The return value is a buffer
    // allocated in FMS memory space, and FMS will manage the memory.
    static U8* getBufferField(const IFmsAuthEvent* pEv, IFmsAuthEvent::Field prop)
    FmsVariant field;
    if (pEv->getField(prop, field) == IFmsAuthEvent::S_SUCCESS && field.type == field.kBuffer)
      return field.buf;
    return 0;
    static bool getI8Field(const IFmsAuthEvent* pEv, IFmsAuthEvent::Field prop, I8& iValue)
    FmsVariant field;
    if (pEv->getField(prop, field) == IFmsAuthEvent::S_SUCCESS && field.type == field.kI8)
      iValue = field.i8;
      return true;
    return false;
    static bool getI32Field(const IFmsAuthEvent* pEv, IFmsAuthEvent::Field prop, I32& iValue)
    FmsVariant field;
    if (pEv->getField(prop, field) == IFmsAuthEvent::S_SUCCESS && field.type == field.kI32)
      iValue = field.i32;
      return true;
    return false;
    static bool getI64Field(const IFmsAuthEvent* pEv, IFmsAuthEvent::Field prop, I64& iValue)
    FmsVariant field;
    if (pEv->getField(prop, field) == IFmsAuthEvent::S_SUCCESS && field.type == field.kI64)
      iValue = field.i64;
      return true;
    return false;
    static bool getFloatField(const IFmsAuthEvent* pEv, IFmsAuthEvent::Field prop, float& fValue)
    FmsVariant field;
    if (pEv->getField(prop, field) == IFmsAuthEvent::S_SUCCESS && field.type == field.kFloat)
      fValue = field.f;
      return true;
    return false;
    static bool getU16Field(const IFmsAuthEvent* pEv, IFmsAuthEvent::Field prop, U16& iValue)
    FmsVariant field;
    if (pEv->getField(prop, field) == IFmsAuthEvent::S_SUCCESS && field.type == field.kU16)
      iValue = field.u16;
      return true;
    return false;
    static bool setStringField(IFmsAuthEvent* pEv, IFmsAuthEvent::Field prop, char* pValue)
    FmsVariant field;
    field.setString(reinterpret_cast<I8*>(pValue));
    return pEv->setField(prop, field) == IFmsAuthEvent::S_SUCCESS;
    static bool setI8Field(IFmsAuthEvent* pEv, IFmsAuthEvent::Field prop, I8 iValue)
    FmsVariant field;
    field.setI8(iValue);
    return pEv->setField(prop, field) == IFmsAuthEvent::S_SUCCESS;
    static bool setU8Field(IFmsAuthEvent* pEv, IFmsAuthEvent::Field prop, U8 iValue)
    FmsVariant field;
    field.setU8(iValue);
    return pEv->setField(prop, field) == IFmsAuthEvent::S_SUCCESS;
    static bool setI32Field(IFmsAuthEvent* pEv, IFmsAuthEvent::Field prop, I32 iValue)
    FmsVariant field;
    field.setI32(iValue);
    return pEv->setField(prop, field) == IFmsAuthEvent::S_SUCCESS;
    static bool setI64Field(IFmsAuthEvent* pEv, IFmsAuthEvent::Field prop, I64 iValue)
    FmsVariant field;
    field.setI64(iValue);
    return pEv->setField(prop, field) == IFmsAuthEvent::S_SUCCESS;
    static bool setFloatField(IFmsAuthEvent* pEv, IFmsAuthEvent::Field prop, float fValue)
    FmsVariant field;
    field.setFloat(fValue);
    return pEv->setField(prop, field) == IFmsAuthEvent::S_SUCCESS;
    static bool isADPCMSupported(int iAudioCodecs)
    return (iAudioCodecs & SUPPORT_SND_ADPCM) != 0;
    static bool isVP6Supported(int iVideoCodecs)
    int iAllVP6 = ( SUPPORT_VID_VP6ALPHA | SUPPORT_VID_VP6 );
    return (iVideoCodecs & iAllVP6) != 0;
    static bool isService(int iType)
    return (iType & TYPE_SERVICE) != 0;
    static bool isAMF3(unsigned char uEncod)
    return (uEncod == ENCODE_AMF3);
    // This class will process all authorization events
    class MyFmsAuthorizeEvent
    public:
    MyFmsAuthorizeEvent(IFmsAuthEvent* pAev, IFmsAuthServerContext2* pFmsAuthServerContext)
      : m_pAev(pAev), m_pFmsAuthServerContext(pFmsAuthServerContext) {}
    virtual ~MyFmsAuthorizeEvent() {}
    void authorize();
    private:
    IFmsAuthEvent*   m_pAev;
    IFmsAuthServerContext2* m_pFmsAuthServerContext;
    void MyFmsAuthorizeEvent::authorize()
    bool bAuthorized = true;  // default authorization state
    switch(m_pAev->getType())
      case IFmsAuthEvent::E_CONNECT:
       // only E_CONNECT allows changes to the following fields:
       // F_CLIENT_AUDIO_SAMPLE_ACCESS
       // F_CLIENT_AUDIO_SAMPLE_ACCESS_LOCK
       // F_CLIENT_READ_ACCESS
       // F_CLIENT_READ_ACCESS_LOCK
       // F_CLIENT_VIDEO_SAMPLE_ACCESS
       // F_CLIENT_VIDEO_SAMPLE_ACCESS_LOCK
       // F_CLIENT_WRITE_ACCESS_LOCK
       // F_CLIENT_WRITE_ACCESS
       I8 iValue;
       if (getI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_WRITE_ACCESS, iValue))
        setI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_WRITE_ACCESS, iValue);
       // redirect connection example
       char* pUri = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_URI);
       if (pUri && !strcmp(pUri, "rtmp://localhost/streamtest"))
        setStringField(m_pAev, IFmsAuthEvent::F_CLIENT_REDIRECT_URI,
         "rtmp://localhost:1935/streamtest");
        bAuthorized = false;
       // set DiffServ fields based on a client IP
       // char* pIp = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_IP);
       // if (pIp && !strcmp(pIp, "192.168.1.1"))
        // set the DSCP bits and mask
        U8 m_diffServBits = 170;
        U8 m_diffServMask = 252;
        setU8Field(m_pAev, IFmsAuthEvent::F_CLIENT_DIFFSERV_BITS, m_diffServBits);
        setU8Field(m_pAev, IFmsAuthEvent::F_CLIENT_DIFFSERV_MASK, m_diffServMask);
        bAuthorized = true;
      break;
      case IFmsAuthEvent::E_PLAY:
       char* pStreamName = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME);
       if (pStreamName)
        setStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME, pStreamName);
       char* pStreamType = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE);
       if (pStreamType)
        setStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE, pStreamType);
       char* pStreamQuery = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_QUERY);
       if (pStreamQuery)
        setStringField(m_pAev, IFmsAuthEvent::F_STREAM_QUERY, pStreamQuery);
       I8 iValue;
       if (getI8Field(m_pAev, IFmsAuthEvent::F_STREAM_RESET, iValue))
        // If iValue is 1 (true) the playlist will be reset and the
        // stream will be the only stream in the playlist; otherwise
        // 0 (false) means the stream will be added to the existing
        // playlist.
        setI8Field(m_pAev, IFmsAuthEvent::F_STREAM_RESET, iValue);
       if (getI8Field(m_pAev, IFmsAuthEvent::F_STREAM_IGNORE, iValue))
        // If iValue is 1 (true) the stream timestamps will be ignored;
        // otherwise 0 (false) means the timestamps will be handled.
        setI8Field(m_pAev, IFmsAuthEvent::F_STREAM_IGNORE, iValue);
       char* pStreamTransition = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_TRANSITION);
       if (pStreamTransition && strlen(pStreamTransition))
        // MBR transition example
        if (!strcmp(pStreamTransition, "switch") ||
         !strcmp(pStreamTransition, "swap"))
         // get the old stream's properties
         char* pOldStreamName = getStringField(m_pAev, IFmsAuthEvent::F_OLD_STREAM_NAME);
         char* pOldStreamType = getStringField(m_pAev, IFmsAuthEvent::F_OLD_STREAM_TYPE);
         char* pOldStreamQuery = getStringField(m_pAev, IFmsAuthEvent::F_OLD_STREAM_QUERY);
         // if pOldStream is empty (optional for switch) current stream is in play
         // do we really want stream transition? 
          // no we do not allow transition
          // bAuthorized = false;
          // now transition will be turned off and old stream continue playing
          // break;    
         // doing nothing will execute transition mode as is
         // or you could modify transition by changing transition properties
         // set it to 1 to indicate they will be hooking up the stream,
         // but that it does not currently exist
         setI32Field(m_pAev, IFmsAuthEvent::F_STREAM_LIVE_PUBLISH_PENDING, 1);
        // get the offset value if transition is set to offset mode for reconnect
        if (!strcmp(pStreamTransition, "resume"))
         float fValue;
         if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_OFFSET, fValue))
          float offset = fValue; //offset value in seconds
       else
        // This is a regular play waiting for approval, which may be converted
        // into a play2 command by changing transition properties
      break;
      case IFmsAuthEvent::E_PUBLISH:
       char* pStreamName = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME);
       if (pStreamName)
        setStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME, pStreamName);
       char* pStreamType = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE);
       if (pStreamType)
        setStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE, pStreamType);
       I32 iValue;
       if (getI32Field(m_pAev, IFmsAuthEvent::F_STREAM_PUBLISH_TYPE, iValue))
        // publish types:
        // 0 : record
        // 1 : append
        // 2 : appendWithGap
        // -1 : live
        setI32Field(m_pAev, IFmsAuthEvent::F_STREAM_PUBLISH_TYPE, iValue);
      break;
      case IFmsAuthEvent::E_FILENAME_TRANSFORM:
        I64 iValue;
        if (getI64Field(m_pAev, IFmsAuthEvent::F_CLIENT_ID, iValue))
         // some fields are not eligible to be modified. The return
         // value will be false when trying to modify the F_CLIENT_ID.
         bool bSet = setI64Field(m_pAev, IFmsAuthEvent::F_CLIENT_ID, iValue);
        char* pStreamName = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME);
        if (pStreamName)
         // some fields are not eligible to be modified. The return
         // value will be false when trying to modify the F_STREAM_NAME.
         bool bSet = setStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME, pStreamName);
        char* pStreamPath = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_PATH);
        if (pStreamPath)
         setStringField(m_pAev, IFmsAuthEvent::F_STREAM_PATH, pStreamPath);
        char* pStreamType = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE);
        if (pStreamType)
         setStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE, pStreamType); 
      break;
      case IFmsAuthEvent::E_PAUSE:
       bAuthorized = false; // block all E_PAUSE events.
       float fValue;
       if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_PAUSE_TIME, fValue))
        float fPauseTime = fValue; // in seconds
       I8 iValue;
       if (getI8Field(m_pAev, IFmsAuthEvent::F_STREAM_PAUSE, iValue))
        // 1 (true) means PAUSE
        // 0 (false) means UNPAUSE
        bool boolPause = iValue != 0;
       if (getI8Field(m_pAev, IFmsAuthEvent::F_STREAM_PAUSE_TOGGLE, iValue))
        // 1 (true) means PAUSE_TOGGLE
        // 0 (false) means no PAUSE_TOGGLE was set
        bool boolPauseToggle = iValue != 0;
       FmsVariant field;
       // Notify Action example: An IFmsNofifyAction is created to notify
       // server side action script (SSAS) of the E_PAUSE event by calling
       // the function name "method" in the script.  In this example two
       // variables will be passed to "method" by calling addParam(field)
       // on the action.
       if (m_pAev->getField(IFmsAuthEvent::F_CLIENT_ID, field) == IFmsAuthEvent::S_SUCCESS)
        I64 clientId = field.i64;
        IFmsNotifyAction* pAction = m_pAev->addNotifyAction("Notified by adaptor");
        pAction->setClientId(field);
        const char mtd[] = "method";
        field.setString(reinterpret_cast<I8*>(const_cast<char*>(mtd)));
        pAction->setMethodName(field);
        // create and insert a U16 "12345" as the first parameter
        field.setU16(12345);
        pAction->addParam(field);
        // create and insert clientId as a double as the second parameter
        field.setDouble((double)clientId);
        pAction->addParam(field);
        // Note: SSAS does not work with I64 or Buffer variants
        // field.setI64(clientId);
        // pAction->addParam(field); // incorrect
      break;
      case IFmsAuthEvent::E_SEEK:
       bAuthorized = false; // block all E_SEEK events
       float fValue;
       if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_SEEK_POSITION, fValue))
        // Modification of the seek position example:
        // fValue + 3; will add 3 seconds to the initial seek posistion
        float fSeekTime = fValue; // value in seconds
        setFloatField(m_pAev, IFmsAuthEvent::F_STREAM_SEEK_POSITION, fSeekTime);
      break;
      case IFmsAuthEvent::E_LOADSEGMENT:
       // bAuthorized = false; // block all E_LOADSEGMENT events
       // E_LOADSEGMENT is a read only event that substitutes E_PLAY on
       // FMS Origin servers for recorded streams.
       I64 iValue;
       if (getI64Field(m_pAev, IFmsAuthEvent::F_SEGMENT_START, iValue))
        I64 iStart = iValue; // in bytes
       if (getI64Field(m_pAev, IFmsAuthEvent::F_SEGMENT_END, iValue))
        I64 iEnd = iValue; // in bytes
      break;
      case IFmsAuthEvent::E_RECORD:
       // bAuthorized = false; // block all E_RECORD events
       float fValue;
       if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_RECORD_MAXSIZE, fValue))
        float recMaxSize = fValue; // in kilobytes
        setFloatField(m_pAev, IFmsAuthEvent::F_STREAM_RECORD_MAXSIZE, recMaxSize);
       if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_RECORD_MAXDURATION, fValue))
        float recMaxDuration = fValue; // in seconds
        setFloatField(m_pAev, IFmsAuthEvent::F_STREAM_RECORD_MAXDURATION, recMaxDuration);
      break;
      case IFmsAuthEvent::E_SWF_VERIFY:
       // SWF Verification example:
       // kAuthorizeSwfVerification is assigned false by default.  The
       // target SWF file must be updated for this to work.
       if(kAuthorizeSwfVerification)
        I8 swfvVersion = 0;
        if(getI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_VERSION, swfvVersion))
         std::stringstream stream;
         stream << "Swf verification version is " << static_cast<int>(swfvVersion);
         m_pFmsAuthServerContext->log(stream.str().c_str(), IFmsServerContext::kInformation, false);
        I64 swfvDepth;
        if(getI64Field(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_DEPTH, swfvDepth))
         I32 swfvTTL;
         if(getI32Field(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_TTL, swfvTTL))
          swfvTTL /= 2;
          setI32Field(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_TTL, swfvTTL);
         U8 digest[kSHA256DigestLen];
         // Target a real SWF file instead of sample.swf
         hashSwfFileAtDepth("C:\\sample.swf", swfvDepth, digest);
         FmsVariant field;
         field.setBuffer(digest, kSHA256DigestLen);
         m_pAev->setField(IFmsAuthEvent::F_CLIENT_SWFV_DIGEST, field);
      break;
      case IFmsAuthEvent::E_APPSTART:
      case IFmsAuthEvent::E_APPSTOP:
      case IFmsAuthEvent::E_DISCONNECT:
      case IFmsAuthEvent::E_STOP:
      case IFmsAuthEvent::E_UNPUBLISH:
      case IFmsAuthEvent::E_ACTION:
      case IFmsAuthEvent::E_CODEC_CHANGE:
      case IFmsAuthEvent::E_RECORD_STOP:
      case IFmsAuthEvent::E_CLIENT_PAUSE:
      case IFmsAuthEvent::E_SWF_VERIFY_COMPLETE:
      case IFmsAuthEvent::E_CLIENT_SEEK:
      case IFmsAuthEvent::E_START_TRANSMIT:
      case IFmsAuthEvent::E_STOP_TRANSMIT:
      case IFmsAuthEvent::E_MAXEVENT:
      break;
    IFmsAuthServerContext2::AuthFailureDesc* desc = NULL;
    if(!bAuthorized)
      desc = new IFmsAuthServerContext2::AuthFailureDesc("Blocked by auth adaptor",
       IFmsAuthServerContext2::kDefaultStatus, -1);
    char buf[1024];
    const char* const action = bAuthorized ? "approved" : "rejected";
    sprintf(buf, "Received authorization type=%d id=%p %s\n", m_pAev->getType(),
      m_pAev, action);
    // log to the configured FMS log directory. If the third parameter is true,
    // also send the log to the system event log.
    m_pFmsAuthServerContext->log(buf, IFmsServerContext::kInformation, false);
    m_pFmsAuthServerContext->onAuthorize(m_pAev, bAuthorized, desc);
    delete desc;
    class MyFmsNotifyEvent
    public:
      MyFmsNotifyEvent(IFmsAuthEvent* pAev, IFmsAuthServerContext2* pFmsAuthServerContext)
       : m_pAev(pAev), m_pFmsAuthServerContext(pFmsAuthServerContext) {}
      virtual ~MyFmsNotifyEvent() {}
      void notify() const;
    private:
      IFmsAuthEvent* m_pAev;
      IFmsAuthServerContext2* m_pFmsAuthServerContext;
    void MyFmsNotifyEvent::notify() const
    switch(m_pAev->getType())
      case IFmsAuthEvent::E_PLAY:
       char* pAppName = getStringField(m_pAev, IFmsAuthEvent::F_APP_NAME);
       char* pAppInst = getStringField(m_pAev, IFmsAuthEvent::F_APP_INST);
       char* pAppUri = getStringField(m_pAev, IFmsAuthEvent::F_APP_URI);
       char* pClIp = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_IP);
       char* pClUri = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_URI);
       char* pClNewUri = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_REDIRECT_URI);
       char* pClVhost = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_VHOST);
       char* pClRef = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_REFERRER);
       char* pClPurl = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_PAGE_URL);
       char* pClAgent = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_USER_AGENT);
       char* pClRAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_READ_ACCESS);
       char* pClWAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_WRITE_ACCESS);
       char* pClAudioAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_AUDIO_SAMPLE_ACCESS);
       char* pClVideoAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_VIDEO_SAMPLE_ACCESS);
       char* pClProto = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_PROTO);
       char* pClUstem = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_URI_STEM);
       char* pStreamName = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME);
       char* pStreamType = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE);
       char* pStreamQuery = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_QUERY);
       char* pStreamPath = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_PATH);
       I32 iValue;
       if (getI32Field(m_pAev, IFmsAuthEvent::F_CLIENT_AUDIO_CODECS, iValue))
        bool bADPCM = isADPCMSupported(iValue);
       if (getI32Field(m_pAev, IFmsAuthEvent::F_CLIENT_VIDEO_CODECS, iValue))
        bool bVP6 = isVP6Supported(iValue);
       if (getI32Field(m_pAev, IFmsAuthEvent::F_CLIENT_TYPE, iValue))
        bool bService = isService(iValue);
       if (getI32Field(m_pAev, IFmsAuthEvent::F_STREAM_ID, iValue))
        I32 iStreamId = iValue;
       float fValue;
       if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_LENGTH, fValue))
        float fLength = fValue; // in seconds
       if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_POSITION, fValue))
        float iPosition = fValue; // in seconds
       I64 lValue;
       if (getI64Field(m_pAev, IFmsAuthEvent::F_CLIENT_ID, lValue))
        I64 iClientId = lValue; 
       I8 sValue;
       if (getI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_SECURE, sValue))
        bool bSecure = sValue != 0;
       if (getI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_AMF_ENCODING, sValue))
        bool bAMF3 = isAMF3(sValue);
       if (getI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_READ_ACCESS_LOCK, sValue))
        bool bRead = sValue != 0;
       if (getI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_WRITE_ACCESS_LOCK, sValue))
        bool bWrite = sValue != 0;
       if (getI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_AUDIO_SAMPLE_ACCESS_LOCK, sValue))
        bool bAudioRead = sValue != 0;
       if (getI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_VIDEO_SAMPLE_ACCESS_LOCK, sValue))
        bool bVideoRead = sValue != 0;
       if (getI8Field(m_pAev, IFmsAuthEvent::F_STREAM_RESET, sValue))
        bool bReset = sValue != 0;
       if (getI8Field(m_pAev, IFmsAuthEvent::F_STREAM_IGNORE, sValue))
        bool bIgnore = sValue != 0;
      break;
      case IFmsAuthEvent::E_SEEK:
       float fValue;
       if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_SEEK_POSITION, fValue))
        float fSeekTime = fValue;
       // Disconnect Action example: disconnect the client that was
       // specified by the E_SEEK notify event
       FmsVariant field;
       if (m_pAev->getField(IFmsAuthEvent::F_CLIENT_ID, field) == IFmsAuthEvent::S_SUCCESS)
        IFmsDisconnectAction* pAction =
         const_cast<IFmsAuthEvent*>(m_pAev)->
          addDisconnectAction("Seek is not allowed. Blocked by adaptor");
        pAction->setClientId(field);
      break;
      case IFmsAuthEvent::E_CODEC_CHANGE:
       char* pAppName = getStringField(m_pAev, IFmsAuthEvent::F_APP_NAME);
       char* pAppInst = getStringField(m_pAev, IFmsAuthEvent::F_APP_INST);
       char* pAppUri = getStringField(m_pAev, IFmsAuthEvent::F_APP_URI);
       char* pClIp = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_IP);
       char* pClUri = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_URI);
       char* pClNewUri = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_REDIRECT_URI);
       char* pClVhost = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_VHOST);
       char* pClRef = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_REFERRER);
       char* pClPurl = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_PAGE_URL);
       char* pClAgent = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_USER_AGENT);
       char* pClRAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_READ_ACCESS);
       char* pClWAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_WRITE_ACCESS);
       char* pClAudioAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_AUDIO_SAMPLE_ACCESS);
       char* pClVideoAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_VIDEO_SAMPLE_ACCESS);
       char* pClProto = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_PROTO);
       char* pClUstem = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_URI_STEM);
       char* pStreamName = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME);
       char* pStreamType = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE);
       char* pStreamQuery = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_QUERY);
       char* pStreamPath = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_PATH);
       U16 fType;
       if (getU16Field(m_pAev, IFmsAuthEvent::F_STREAM_CODEC_TYPE, fType))
        U16 streamCodecType = fType;
        if (streamCodecType == kVIDEO_CODEC)
         U16 fValue;
         if (getU16Field(m_pAev, IFmsAuthEvent::F_STREAM_CODEC, fValue))
          U16 streamCodecValue = fValue;
          if (streamCodecValue == VIDEO_CODEC_SORENSON)
           // Disconnect Action example: Disallow clients trying
           // to publish content with the sorenson video codec.
           FmsVariant field;
           if (m_pAev->getField(IFmsAuthEvent::F_CLIENT_ID, field) == IFmsAuthEvent::S_SUCCESS)
            IFmsDisconnectAction* pAction =
             const_cast<IFmsAuthEvent*>(m_pAev)->
             addDisconnectAction("Sorenson is not allowed. Blocked by adaptor");
            pAction->setClientId(field);
      break;
      case IFmsAuthEvent::E_RECORD_STOP:
       char* pAppName = getStringField(m_pAev, IFmsAuthEvent::F_APP_NAME);
       char* pAppInst = getStringField(m_pAev, IFmsAuthEvent::F_APP_INST);
       char* pAppUri = getStringField(m_pAev, IFmsAuthEvent::F_APP_URI);
       char* pClIp = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_IP);
       char* pClUri = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_URI);
       char* pClNewUri = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_REDIRECT_URI);
       char* pClVhost = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_VHOST);
       char* pClRef = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_REFERRER);
       char* pClPurl = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_PAGE_URL);
       char* pClAgent = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_USER_AGENT);
       char* pClRAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_READ_ACCESS);
       char* pClWAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_WRITE_ACCESS);
       char* pClAudioAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_AUDIO_SAMPLE_ACCESS);
       char* pClVideoAccess = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_VIDEO_SAMPLE_ACCESS);
       char* pClProto = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_PROTO);
       char* pClUstem = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_URI_STEM);
       char* pStreamName = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME);
       char* pStreamType = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE);
       char* pStreamQuery = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_QUERY);
       char* pStreamPath = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_PATH);
       float fValue;
       if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_RECORD_MAXSIZE, fValue))
        float recMaxSize = fValue; // in kilobytes
       if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_RECORD_MAXDURATION, fValue))
        float recMaxDuration = fValue; // in seconds
      break;
      case IFmsAuthEvent::E_SWF_VERIFY_COMPLETE:
       char* pClIp = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_IP);
       I8 version; // version of SWF verification
       getI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_VERSION, version);
       I64 depth; // depth in the SWF file hashed
       getI64Field(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_DEPTH, depth);
       I32 ttl; // time to live of the SWF hash provided
       getI32Field(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_TTL, ttl);
       // digest provided to match against
       U8* buffer = getBufferField(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_DIGEST);
       // result of the attempted match-- see FmsAuthEvents.h enum
       // eSWFMatch for the meaning of this field
       I32 match;
       getI32Field(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_RESULT, match);
       std::stringstream stream;
       stream << "swf verification for client: "
         << std::string(pClIp)
         << " is complete, the result is: " << match;
       m_pFmsAuthServerContext->log(stream.str().c_str(), IFmsServerContext::kInformation, false);
      break;
      case IFmsAuthEvent::E_APPSTART:
      case IFmsAuthEvent::E_APPSTOP:
      case IFmsAuthEvent::E_CONNECT:
      case IFmsAuthEvent::E_DISCONNECT:
      case IFmsAuthEvent::E_FILENAME_TRANSFORM:
      case IFmsAuthEvent::E_STOP:
      case IFmsAuthEvent::E_PAUSE:
      case IFmsAuthEvent::E_PUBLISH:
      case IFmsAuthEvent::E_UNPUBLISH:
      case IFmsAuthEvent::E_LOADSEGMENT:
      case IFmsAuthEvent::E_ACTION:
      case IFmsAuthEvent::E_RECORD:
      case IFmsAuthEvent::E_CLIENT_PAUSE:
      case IFmsAuthEvent::E_SWF_VERIFY:
      case IFmsAuthEvent::E_CLIENT_SEEK:
      case IFmsAuthEvent::E_START_TRANSMIT:
      case IFmsAuthEvent::E_STOP_TRANSMIT:
      case IFmsAuthEvent::E_MAXEVENT:
      break;
    char buf[1024];
    sprintf(buf, "Received notification type=%d id=%p\n", m_pAev->getType(), m_pAev);
    // log to the configured FMS log directory. If the third parameter is true,
    // also send the log to the system event log.
    m_pFmsAuthServerContext->log(buf, IFmsServerContext::kInformation, false);
    m_pFmsAuthServerContext->onNotify(m_pAev);
    /* All authorization events flow through this wrapper function.
    * Note: This sample auth adaptor has MyFmsAppAuthEvent allocated on the
    * stack, but time intensive implementations may warrant authorization to
    * be allocated on the heap so work may be passed to a thread pool.  This
    * prevents starvation of the calling FMS threads in custom code that may
    * have processing delays (ie database calls, network filesystem access, etc..).
    void FmsAuthAdaptor::authorize(IFmsAuthEvent* pAev)
      MyFmsAuthorizeEvent(pAev, m_pFmsAuthServerContext).authorize();
    /* All notification events flow through this wrapper function.
    * Note: This sample auth adaptor has MyFmsNotifyEvent allocated on the
    * stack, but time intensive implementations may warrant notifications to
    * be allocated on the heap so work may be passed to a thread pool.  This
    * prevents starvation of the calling FMS threads in custom code that may
    * have processing delays (ie database calls, network filesystem access, etc..).
    void FmsAuthAdaptor::notify(IFmsAuthEvent* pAev)
      processStats(pAev);
      MyFmsNotifyEvent(pAev, m_pFmsAuthServerContext).notify();
    * Get client statistics.
    bool FmsAuthAdaptor::getStats(I64 clientStatsHandle, FmsClientStats& baseStats)
    bool bValue= m_pFmsAuthServerContext->getClientStats(clientStatsHandle, baseStats);
    return bValue;
    * Example obtainting client stats from an E_CONNECT or E_STOP event
    void FmsAuthAdaptor::processStats(IFmsAuthEvent* pAev)
      I64 statsHandle;
      FmsClientStats baseStats;
      if (!getI64Field(pAev, IFmsAuthEvent::F_CLIENT_STATS_HANDLE, statsHandle))
       return;
      char* pAppName = getStringField(pAev, IFmsAuthEvent::F_APP_NAME);
      if (pAev->getType() == IFmsAuthEvent::E_CONNECT)
       getStats(statsHandle, baseStats);
       // log data
       char buf[1024];
       char hashKey[9];
       memset(hashKey, 0, 9);
       memcpy(hashKey, &statsHandle, sizeof(statsHandle));
       sprintf(buf, "client Stats Handle= %s, bytes_in= %f, bytes_out= %f\n", hashKey,
        static_cast<double>(baseStats.bytes_in), static_cast<double>(baseStats.bytes_out));
       m_pFmsAuthServerContext->log(buf, IFmsServerContext::kInformation, false);
      else if (pAev->getType() == IFmsAuthEvent::E_STOP)
       getStats(statsHandle, baseStats);
    /* By default, all authorization and notifications events will be sent.
    * Call excludeEvents with the bit set to 1, to stop recieving events.
    * Note: The events:
    * E_APPSTART, E_APPSTOP, E_DISCONNECT, E_STOP, E_UNPUBLISH, E_CODEC_CHANGE
    * are excluded by default and are not authorizable.
    void FmsAuthAdaptor::getEvents(I32 aevBitAuth[], I32 aevBitNotf[], unsigned int count)
    // exclude certain auth events
    IFmsAuthEvent::EventType authExcludeEvent[] = { IFmsAuthEvent::E_SEEK };
    // set E_SEEK to a non authorizable event
    m_pFmsAuthServerContext->excludeEvents(aevBitAuth, count, authExcludeEvent, 1);
    // Warning: if E_CODEC_CHANGE event is not excluded, all messages will be
    // scanned to detect codec change. Subscribe to this event only as needed.
    // Example that excludes certain notify events. (E_PAUSE, E_CODEC_CHANGE)
    IFmsAuthEvent::EventType notifyExcludeEvent[] =
      { IFmsAuthEvent::E_PAUSE, IFmsAuthEvent::E_CODEC_CHANGE };
    m_pFmsAuthServerContext->excludeEvents(aevBitNotf, count, notifyExcludeEvent, 2);
    extern "C" void FCExport FmsCreateAuthAdaptor3(IFmsAuthServerContext2* pAuthServerCtx,
                  IFmsAuthAdaptor*& pFmsAuthAdaptor, U32& iVersion)
    pFmsAuthAdaptor = new FmsAuthAdaptor(pAuthServerCtx);
    U32 version = pAuthServerCtx->getVersion();
    U16 w2 = LWORD(version);
    U16 w1 = HWORD(version);
    iVersion = MKLONG(INTERFACE_MINOR_VERSION, INTERFACE_MAJOR_VERSION);
    char buf[1024];
    char *ptr = buf;
    int valueLen = pAuthServerCtx->getConfig("UserKey1", &ptr, sizeof(buf));
    if (!valueLen)
      valueLen = pAuthServerCtx->getConfig("UserKey2", &ptr, sizeof(buf));
      if (!valueLen)
       return;
      if (valueLen < 0)
       // failed to find this key
       return;
    if (valueLen < 0)
      // failed to find this key
      return;
    // value length is bigger then the buffer size, and a real adaptor should
        // allocate valueLen + 1 bytes and call again
    extern "C" void FCExport FmsDestroyAuthAdaptor3(IFmsAuthAdaptor* pAuthAdaptor )
    delete pAuthAdaptor;

    There is no API to Acrobat's document compare feature.
    It is certainly possible for an experienced plug-in programmer to
    create a new compare plug-in. For example, extract text from two PDFs
    and compare it. Comparison algorithms have been much studied so should
    be findable in academic literature.
    Going beyond text comparison would be a major exercise.
    Aandi Inston

  • Substitute tasks not shown in UWL but available in SBWP

    Hi, I am trying to test substitute functionality in our custom iview. I have added code(available in attached file) in UWL XML which shows Manage Substitution button and substitute tasks are shown in SBWP but not in UWL.  What else I need so tasks show up in UWL? Thanks in advance

    Nilesh Telkikar wrote:
    Is there any authorizations required in portal to add substitution?
    page 14, http://www.sap-press.de/download/dateien/1461/146_leseprobe.pdf
    Nilesh Telkikar wrote:
    I see entries in SAP table HRUS_D2 but portal table KMC_WF_SUBSTITUTE is empty when I add substitution.
    sorry, Im not familiar with the table. But regarding your expectation of new entries, did you saw that already?:
    UWL FAQ - Business Process Expert - SCN Wiki
    Substitution - Getting Started - Using SAP Software - SAP Library
    regards

  • Current Setting in Collection Mgt Authorization should give to User?

    Hi All,
    In SAP Easy access of collection management current setting three T.codes - UDM_STRATEGY - Strategies , UDM_GROUP - Groups, UDM_GROUP2SGMT - Assign Groups to Segments.
    when these T.codes we are using and saving the activities system prompt customization request,  should give authorization to user?
    Regards
    Arun

    Hi Arun,
    The Tcodes you have mentioned are solely the function of a Collection supervisor and not team members. However, if you still want to give limited access then consider the below points for individual Tcodes -
    UDM_GROUP - Out of the 3 mentioned above, you may want to give this T-code to team members only for assigning substitute person in case somebody is absent. You can look at transaction variant (SHD0) to make other screens as display only.
    UDM_GROUP2SGMT - This is not required on a daily  basis and authorization can be left with the IT team only.
    UDM_STRATEGY - This is best handled by the Collection Supervisor or Team Lead of AR and care must be taken that there are no logical misses in the rules.
    Regards,
    Abhishek Jain

  • Transaction based security vs. Authorization based security

    Hi All just a general question does any one know any pro's and con's about implementing transaction based security vs. authorization object based
    Thanks Mike

    Well, the Tcode goes into an authoruization object as well, namely S_TCODE, so it always boils down to authorization objects. When properly configured, PFCG will propose all necessary authorization objects once you put a transaction in the role menu. On a new system, have a look at SU25 and it's documentation to setup PFCG.
    In my opinion putting the relevant transactions in the roles first and fine tuning the authorization values afterwards is the right way to go. Tracing may help but is no substitute for testing.

  • How to use authorization object P_PERNR ?

    Hi, Gurus~
    In our system, there is a user whose User ID is "00041", and she can modify her own 0008, we want to control it so that she can only display her own 0008, but process 0008 for all other employees
    So, i use the authorization object P_PERNR to do this, i set the fields value like this (totally copy from the SAP help for P_PERNR....):
    Authorization level:  W,S,D,E
    Infotype: 0008
    Interpretation of assignment personnel number: E
    Subtype: *
    and then, i maintain her master data 0105's subtype 0001-system user name as 00041
    i think she shouldn't maintain her own 0008 now ,but she still can maintain it
    i want to know why and how to solve it, did i do it in the right way?
    Thank you in advance!

    P_PERNR   HR: Master Data - Personnel Number Check
    You use the HR: Master Data - Personnel Number Check authorization object if you want to assign users different authorizations for accessing their own personnel number. If this check is active and the user is assigned a personnel number in the system, it can directly override all other checks with the exception of the test procedures.
    The following values are possible for the PSIGN field:
    I   =          Authorization for personnel number assigned, that is for own personnel number
    E  =          Authorization for all personnel numbers excluding own personnel number
    You can assign a user a personnel number using infotype 0105, subtype 0001 (in earlier releases using the V_T513A view).
    This check does not take place if the user has not been assigned a personnel number, or if the user accesses a personnel number other than his or her own. In other words, this check is completely irrelevant for personnel numbers that are not assigned to the user.
    Example of Personnel Number Check P_PERNR
    The authorization checks for P_ORGIN and P_PERNR are activated in the system. In addition, there are user assignments for some personnel numbers.
    The user in our example is assigned a personnel number and is administrator responsible for the Basic Pay infotype (0008) of a personnel area (that is, the user has the corresponding P_ORGIN authorization). The employee should also be able to display his or her own data but not change his or her basic pay, irrespective of the personnel area for which the employee is responsible. The corresponding authorizations for the P_PERNR authorization object must be set up as follows: AUTHC = R, M
    PSIGN = I
    INFTY = *
    SUBTY = * AUTHC = W, S, D, E
    PSIGN = E
    INFTY = 0008
    SUBTY = *
    In our example, the user is an administrator responsible for the basic pay (infotype 0008) of a personnel area (since the administrator has the corresponding HR: Master Data authorization). The employee should also be able to display his or her own data at all times but not change his or her basic pay, irrespective of the personnel area for which the employee is responsible. You need to set up the appropriate authorizations for the HR: Personnel Number Check object as shown in this example.
    The first authorization grants the employee read authorization for all infotypes that are stored under the employee's personnel number. The second authorization denies write access to all data records of infotype 0008 for the employee's own personnel number in case the administrator is responsible at some point in the future for the personnel area to which he or she belongs.
    As the following examples illustrate, inconsistent authorizations can be granted.
    Example 1:
    AUTHC = *
    PSIGN = I
    INFTY = 0014
    SUBTY = M* AUTHC = W, S, D, E
    PSIGN = E
    INFTY = 0014
    SUBTY = *
    The first authorization grants the employee read authorization (AUTHC = R) for the Recurrent Payments/Deductions infotype (0014), subtype M120, which allows the employee to access the data stored under his or her personnel number. In this case, the second authorization is irrelevant.
    The first authorization grants the employee write authorization (AUTHC = W) for the Recurrent Payments/Deductions infotype (0014), subtype B030, which denies the employee access to the data stored under his or her personnel number. In this case, the first authorization is irrelevant.
    The first authorization grants the employee write authorization for the Recurrent Payments/Deductions infotype (0014), subtype M120, the second authorization denies the employee this authorization. The desired system response is unclear from this example. According to the documentation, the system response is undefined in such situations. In reality, the authorization check always denies authorization in unclear situations, that is E is stronger than I and therefore the authorization is not granted.
    Example 2:
    AUTHC = *
    PSIGN = *
    INFTY = *
    SUBTY = *
    This type of authorization is required by superusers with unlimited access, for example. The above authorization is appropriate if an employee wants to access an infotype. However, since PSIGN = * and * can be substituted for any value, PSIGN and E can also be interpreted as I. This can also lead to an undefined situation. In earlier releases, the authorization was denied on the basis of the rule E is stronger than I. This meant that superusers with assigned personnel numbers were not able to access their own personnel number. The programs have since been changed and now * is interpreted as I and is stronger than E. In other words, * is stronger than E and E is stronger than I, whereby * is interpreted as I.
    As already indicated in Example 1, the combination of different authorizations can produce a complicated result. We therefore recommend that you avoid combinations where P_PERNR authorizations can be interpreted differently for the same combination of AUTHC(Authorization Level), INFTY(Infotype) and SUBTY (Subtype).
    Misunderstandings arising from the complex situations described above are not the most frequent causes of customer inquiries, however. The most frequent cause is the incorrect assumption that authorizations by personnel number affect authorizations for non-assigned personnel numbers. This is not the case at all.
    If you use authorizations by personnel number, you should always first set up all non-personnel number-related authorizations. As soon as you have done this, you should create different access authorizations for the personnel numbers that are assigned to users using appropriate P_PERNR authorizations. This is always possible since the P_PERNR authorizations override all other authorizations directly (except Test Procedures).
    P_PERNR authorization checks cannot bypass test procedures directly. For instance, a test procedure is only carried out on the Recurring Payments/Deductions infotype (0014) if a corresponding P_PERNR authorization (with PSIGN = I) exists. If an appropriate authorization for the corresponding subtype of the infotype 0130 exists, it can be used effectively to carry out the test procedures.

  • No authorization to add transaction to role menu

    MODS: IF YOU ARE GOING TO DELETE MY POSTS..AT LEAST EMAIL ME TO LET ME KNOW WHY YOU ARE DELETING THEM SO I CAN RE-WORD IT TO ACCOMMODATE YOUR ISSUE. THIS IS THE THIRD TIME YOU HAVE DELETED ONE OF MY POSTS WITH NO EXPLANATION AND IF THIS FORUM ISNT FOR ASKING QUESTIONS LIKE THIS...THEN WHAT IS IT FOR?
    To the question:
    I am able to do add a transaction to a role in our production environment without issue. Trying to add it in in Development system gives me the following error:
    No authorization to add transaction <transaction name> to role menu.
    When I look at SU53 it tells me that it failed on Authorization Object s_user_tcd Field TCD value Z_RICKTEST
    It then shows me 4 profiles with that auth object and field and a value of PFCG.
    I can run the program Z_RICKTEST with no issue in either system.
    Can anyone shed some light on why this is happening?

    The reject mail contains a link to the forum rules. If you (had) read that you would understand.
    Reason is that you have no basic training, make no effort to read the application documentation and then make changes in production and want to know from us how it works.
    Imagine if everyone did that? Imagine what the systems would all look like?
    These discussion areas are not a substitute for basic training!
    Thread locked!

  • Is there any SAP substitute role to create expense report for executives?

    Hello,
    In an organization there are executives like MD, CEO and they need to submit their expenses. This activity is basically needs to be done by their secretary (substitute). So is there any SAP provided roles to do this activity?
    I have seen SAP_FI_TV_WEB_ASSISTANT used for My Employees/POWL. Apart from this role do we have any other way for executives?
    Appreciate your help.
    Thanks,
    Chandra.

    Hi ,
    You can create travel request from PR05 from ECC or if you have ESS and you want administrators to create on behalf of others provide the below role and you can create from My Employees or you can customize a role specific for administrators using structural authorizations.
    SAP_FI_TV_WEB_ASSISTANT
    Hope this helps,
    Regards,
    S.Srikanth
    Edited by: SrikanthS on May 10, 2011 6:32 AM

  • User has no authorization for function group SWRS

    Dear SRM Gurus,
    We are facing an issue u201CUser has no authorization for function group SWRSu201D.
    Hope the user has no authorization to access function group SWRS and this function group is saying that workflow substitution.
    Can you any one have any idea what scenario are we using Workflow substitution?
    Is there any Roles need to be assigned?
    I would be appreciating if you could let us know more detail on this.
    Thanks.
    Regards,
    Magesh Basavaraj.

    Hi,
       The authorization object is 'S_WF_SUBST' for substitute role..try to assign this object and check..
    Saravanan

  • Transfer authorisation while maintaining substitute

    Hi All,
    I have a requirement for substitutes in PO approval workflow.
    Sceanario is:
    If approver is on leave, substitute should approve the PO, however, substitute do not have authorisation to approve it.
    Is there any way through which we can transfer role to approve PO when substitution is made active.
    Can we use Substitution profile here? e.g. create a profile with authorisation to Approve PO and attach that profile when creating substitution.
    Any other way to achieve this would be helpful.
    Regards,
    Sangvir Singh

    Hi,
    There is no connection between WF substitution profile and the user authorizations,
    so no authorizations are added to a substituting user.
    However, you can change the WF so the approver will approve the PO in a decision task,
    but a background task (for example PurchaseOrder.Release of object BUS2012)
    will perform the actual approval.
    The background task uses the WF-BATCH user and passes all authority checks.
    The substitution will be for the decision task and will require no auth as well,
    so the substituting user can approve the PO.
    You should, if you use this way, check the return of the release task to make sure there are no errors (PO locked for example).
    Ronen

  • Personnel substitution - temporary inheritance of authorization

    Hello all,
    I'm in need of finding a solution for HR substitution, meaning that the person substituting for a colleague will temporarily inherit his/her authorization.
    The required functionality should be an automated process/program where managers can organize their own substitutions.
    For now I have tested this functionality and it only seems to work when adding relation A008 for the substitute to the respective role. But this may have undesired implications regarding payroll because of the changed IT0001...
    I would like to know if there's a tried and 'standard' procedure/solution for this.
    The client is using CUA with structural authorization and context solution.
    If you need any additional info, let me know!
    points are rewarded!
    Thanks!

    thanks for your reply, David.
    In fact, the situation as desired by the client is as follows : all line managers and HR managers should be able to organize their own substitutes through the portal.
    The easiest way to go about doing so would be to add a (time-delimited) relationship between the substitute and the position to be substituted.  As far as the 'inheritance' of authorization is concerned, this is working. I'm stil not completely sure what the impact is regarding payroll or anything else.
    the structural authorizations are inherited through the top org. unit a user belongs to.
    Ideally, after the substitution the substitute should be authorized to access both org. units : his own and the one he's substituting.
    I hope to have clarified my situation a litlle...

  • Personnel substitution - temporary inheritance of authorization  (D.O.A.)

    Hello all,
    I'm in need of finding a solution for HR substitution, meaning that the person substituting for a colleague will temporarily inherit his/her authorization.
    The required functionality should be an automated process/program where managers can organize their own substitutions.
    For now I have tested this functionality and it only seems to work when adding relation A008 for the substitute to the respective role. But this may have undesired implications regarding payroll because of the changed IT0001...
    I would like to know if there's a tried and 'standard' procedure/solution for this.
    The client is using CUA with structural authorization and context solution.
    If you need any additional info, let me know!
    points are rewarded!
    Thanks!
    In addition to the above, I would like to ask whether the relation between the role and the position is the best way to go or perhaps I should consider using the job object (C) to avoid the before-mentioned implications with IT0001.
    Any help would be greatly appreciated....
    <b>reply by David Coleman</b>:
    I assume you are concerned with Structural authorisations here. The "evaluation" is controlled by an evaluation path. I think that you can use another releationship (B205 springs to mind for some reason) for the work flow substitution and also add it into the eval path. Hence all workflows and auths would be "inherited" by the subsitute.
    sorry for vague details
    thanks for your reply, David.
    In fact, the situation as desired by the client is as follows : all line managers and HR managers should be able to organize their own substitutes through the portal.
    The easiest way to go about doing so would be to add a (time-delimited) relationship between the substitute and the position to be substituted. As far as the 'inheritance' of authorization is concerned, this is working. I'm stil not completely sure what the impact is regarding payroll or anything else.
    the structural authorizations are inherited through the top org. unit a user belongs to.
    Ideally, after the substitution the substitute should be authorized to access both org. units : his own and the one he's substituting.
    I hope to have clarified my situation a litlle...
    p.s.: I initially posted this in the HCM forum only realizing that this place is more suited for these type of questions. That's also the reasopn why I pasted all posts into this one.  If this is not according to the COC, kindly let me know.

    thanks for your reply, David.
    In fact, the situation as desired by the client is as follows : all line managers and HR managers should be able to organize their own substitutes through the portal.
    The easiest way to go about doing so would be to add a (time-delimited) relationship between the substitute and the position to be substituted.  As far as the 'inheritance' of authorization is concerned, this is working. I'm stil not completely sure what the impact is regarding payroll or anything else.
    the structural authorizations are inherited through the top org. unit a user belongs to.
    Ideally, after the substitution the substitute should be authorized to access both org. units : his own and the one he's substituting.
    I hope to have clarified my situation a litlle...

  • Applying Authorization on Standard CSV Export

    Is there a way to apply an authorization scheme to the standard csv export? Maybe I am
    just not able to find a way to do it. I would know how to do that using custom export but
    this is not the way to go since too many reports need to have that option turned on.
    Denes Kubicek
    http://deneskubicek.blogspot.com/
    http://www.opal-consulting.de/training
    http://apex.oracle.com/pls/otn/f?p=31517:1
    -------------------------------------------------------------------

    Hello Marc,
    Thanks for your answer. Maybe I explain what the problem is:
    1. one of my customers (with many users) has an apex application with many reports showing customer data coming from SAP,
    2. the number of rows you can query is limited to a certain number they can adjust,
    3. the number of records per page is also limited,
    4. they want to explicitly allow or dissalow the export of the results
    5. users are allowed to view the data but may not be allowed to export it
    Their request makes sense.
    I solved the problem using id's for the span tags containing the link substitute and
    hiding or showing the span tag with javascript, depending on the authorization. However, like all the
    proposed workarrounds here, this is not realy secure.
    I hope in one of the next releases, you will find a solution.
    Denes Kubicek
    http://deneskubicek.blogspot.com/
    http://www.opal-consulting.de/training
    http://apex.oracle.com/pls/otn/f?p=31517:1
    -------------------------------------------------------------------

  • Namespace to direct Authorizer to Service Form

    Namespace to direct Authorizer to Service Form
    How can I take the Authorizer directly to the service form with the link on the email notification they receive?
    Step 1:
    In the email template body that is assigned to the approval task use the following source code for the URL:
    &lt;a   href="#Site.URL#myservices/navigate.do?query=requisitionentrystatus&amp;reqid=#Service.Requisition.RequisitionID#&amp;reqentryid=#Service.RequisitionEntryID#&amp;formAction=displayEntryStatus&amp;serviceid=#Service.ServiceID#&amp;requisitionId=#Service.Requisition.RequisitionID#&amp;waiting=0&amp;authTaskType=4&amp;activityId=#ActivityID#&amp;buttonsPresent=true&amp;"&gt;Click  Here to View the Service Request&lt;/a&gt;
    Please note  that the Authorization Task Type is hard-coded in the URL above to be  utilized in a Service Group Authorization.  If the email template is  utilized in a different type of Authorization substitute the appropriate  Task Type as noted in the table below.

    Using RC2008.3
    This is pretty cool.  I've been wanting to do this since we first started using RC and was told it wasn't possible. 
    I've tried this out and now have a concern though.  The page loads correctly and the options are there for approve/reject, but there is no navigation available to get up to the summary screen (where approval links normally go).  So there is no way for an approver to review or update the comments & history.  Also no way to review any attachments.  Any known tr

  • Authorization on Manage Substituion Rules

    Hi Experts,
    On MSS under Manage Substitution Rules, manager can assign his one or all tasks to another employee who can do tasks on his behalf.
    Does the person who gets one or all tasks, need to have authorization in back end prior to that or it inherits when he gets assignment ?
    Would appreciate prompt response.
    Cheers,
    Aashish

    Yes, they need authorizations. No, they aren't just magically copied over when substitution is set. Substitution allows another user to have access to all of the work items (via UWL for example) for the manager. When exectuing those work items, the "substitute" will need the authorization to perform those tasks.

Maybe you are looking for