Programmatically add direct assignment ADSAccountInADSGroup even as deferred operation

Hi all, Community

I am trying to programmatically set up some deferred operations in order to directly assign an ADSGroup to an AdsAccount. This should be done also for existing indirect assignments.

Usually, if I have to do it “runtime” (not deferred operation), I can execute from the script a sql query (mySQLExec.SqlExecuteNonQuery(“update ADSAccountInADSGroup set XOrigin = x where …. ”) ) but this cannot be done in a deferred operation block as it is executed immediately. In deferred operation block I need to base the updates I want to persist throughout the deferred operation to IsingleObject or Entity, but as I tried to update the field XOrign I keep on getting permission exceptions, no matter what I do.

So, can someone give me some ideas how to solve this problem? Maybe there is a better way than to directly querying the DB. Some method or else linked to ISingleDbObject or Entity …

Thank you in advance to anyone who can provide detail.

 

Alberto

  • Could you describe your use case in more detail? Why do you need to update the XOrigin flag directly? This flag is handled by the object layer and the DB queue processor and you shouldn't mess with it.

  • Hi Markus

    Thank you for interesting to my issue.

    We need to implement a sort of copy ADSAccount. We need to align the ADSAccountInADSGroup of two different accounts when, of course, it is possible. In case, we need to allow user to start this alignment as deferred operations.

    In particular, we have to handle the following case: donor ADSAccount has a direct assignment of a ADSGroup while recipient has not. My clients want me to assign that AdsGroup directly to the recipient too, this means that XOrigin increases, if I am not wrong, from 2 to 3.

    Usually, I handle this kind of requests with an SQLExecutor, by I cannot do that as deferred operation. When I try to use the deferred operation, I need to base the instruction on Entity or ISingleDbObject, but they do not let me modify the XOrigin.

    That’s it.

     

    Thank you in advance.

    Alberto

  • Add a direct membership in ADSAccountInADSGroup is always a simple Insert operation into ADSAcountInADSGroup using the object layer, regardless of the entity is already present with XOrigin = 2 as long as the lowest bit is not set (which represents the direct assignment).

    The same is true for a delete operation. The object layer automatically converts the operation internally to an update of the Xorigin property.

    So in your use case, you just need to create the correct iEntity operations in your deferred block.

    HTH

  • Hi Markus.

     

    I have tried your solution and it seems to work. I cannot understand why I was getting error when I firstly used it. Anyway, please, can you confirm that the following two sets of instructions are both suitable for what I want to achieve (deferred operation xorigin = xorigin +1) ?

    Dim recordToAdd As ISingleDbObject = Me.Connection.CreateSingle("ADSAccountInADSGroup")

    recordToAdd("UID_ADSAccount").NewValue = UID_ADSAccount

    recordToAdd("UID_ADSGroup").NewValue = uid_group

    recordToAdd.Save()

     

    Dim recordToAddEntity As IEntity = Me.Connection.Session.Source.CreateNew("ADSAccountInADSGroup", EntityCreationType.Default)

    recordToAddEntity.PutValue("UID_ADSAccount", UID_ADSAccount)

    recordToAddEntity.PutValue("UID_ADSGroup", uid_group)

    recordToAddEntity.Save(Me.Connection.Session)

     

    Thanks, I owe you once again… Blush

     

    A

  • Yes, this should work. Again, iEntity usage should be preferred.

    Here two samples including the deferred block.

    Sample: Using a Deferred Block for IEntities

    ' Create a new DeferredBlock for a point in time.
    Using New VI.DB.DeferredOperations.DeferredBlock(Session, DateTime.UtcNow.AddDays(45), "Optional description for operation")
        ' Operations done here are done deferred
        Dim dbObj = Session.Source().CreateNew("PersonInOrg")
        dbObj.PutValue("UID_Person""a76311be-c2cd-4be3-be5d-b8d85c3bb863")
        dbObj.PutValue("UID_Org""b0b4be5a-bcc1-453d-aaf5-b5a7d8531224")
     
        Using uow = Session.StartUnitOfWork()
            uow.Put(dbObj)
            uow.Commit()
        End Using
    End Using
    

    Sample: Using a deferred block for ISingleDBObjects

    ' Create a new DeferredBlock for a point in time.
    Using New VI.DB.DeferredOperations.DeferredBlock(Connection, DateTime.UtcNow.AddDays(45), "Optional description for operation")
        ' Operations done here are done deferred
        Dim dbObj = Connection.CreateSingle("PersonInOrg")
        dbObj.PutValue("UID_Person""a76311be-c2cd-4be3-be5d-b8d85c3bb863")
        dbObj.PutValue("UID_Org""b0b4be5a-bcc1-453d-aaf5-b5a7d8531224")
        dbObj.Save()
    End Using
  • Thank you a lot.

    I read your old post but i was getting some error.. Probably it was unrelated. nyway now everything works like a charm! 

    a

  • Wait a minute...

    So if I want to assign an AD group to a user for only one (1) hour, this is the way to do it, or am I getting this wrong?

  • I think you are getting this wrong. this is the code to assign something (for example an ADSAccount to an ADSGroup) in the future. In my sample code, the assignment will be run 45 days from now.

  • Markus

    I am sorry to bother you again with this issue but after a couple of successful tests, it start again the give me the same error of yesterday:

     

    One or more errors occurred.

    Error flushing changes to database.

    Error during execution of statement: insert into ADSAccountInADSGroup (UID_ADSAccount, UID_ADSGroup, XOrigin, xdateinserted, xuserinserted, xdateupdated, xuserupdated, xobjectkey) values ('f7fc38e8-ecb3-4ab1-a567-89aaf19a45fb', 'cccc6aee-0bfa-4619-8a63-0eb00f0b3d2f', 1, GetUTCDate(), N's2e-alberto', GetUTCDate(), N's2e-alberto', '<Key><T>ADSAccountInADSGroup</T><P>f7fc38e8-ecb3-4ab1-a567-89aaf19a45fb</P><P>cccc6aee-0bfa-4619-8a63-0eb00f0b3d2f</P></Key>')

    Database error 2627: Violation of PRIMARY KEY constraint 'PK__ADSAccou__51A5CB301C738950'. Cannot insert duplicate key in object 'dbo.ADSAccountInADSGroup'. The duplicate key value is (f7fc38e8-ecb3-4ab1-a567-89aaf19a45fb, cccc6aee-0bfa-4619-8a63-0eb00f0b3d2f).

    The statement has been terminated.

    Violation of PRIMARY KEY constraint 'PK__ADSAccou__51A5CB301C738950'. Cannot insert duplicate key in object 'dbo.ADSAccountInADSGroup'. The duplicate key value is (f7fc38e8-ecb3-4ab1-a567-89aaf19a45fb, cccc6aee-0bfa-4619-8a63-0eb00f0b3d2f).

    The statement has been terminated.

     

    Again, I am trying to add a direct assignment to an existing indirect assignment. I am using the following code:

    Dim recordToAddEntity As IEntity = Me.Connection.Session.Source.CreateNew("ADSAccountInADSGroup", EntityCreationType.Default)

    recordToAddEntity.PutValue("UID_ADSAccount", Me.Recipient_ADSAccount.UID_ADSAccount)

    recordToAddEntity.PutValue("UID_ADSGroup", uid_group)

    Using uow = Me.Connection.Session.StartUnitOfWork()

                   uow.Put(recordToAddEntity)

                   uow.Commit()

    End Using

     

    Where am I wrong or why does this code works only sometimes (even with there is an indirect assignment) ?

     

    Thank you

    A

  • After a second thought, the Object Layer does the translation from a Delete of direct memberships into an update of XOrigin, if XOrigin is 3 (for example).

    I'll check the insert case and keep you updated.