Customizing a KiiObject's ACL

You can change the access control applied to a KiiObject by setting its ACL.

KiiObject ACL entries

A KiiObject ACL entry is composed of an action and a subject:

  • Action

    This item defines "what" the target user/group/thing can execute.

    Action Representation in code * What the target user/group/thing can execute
    READ_EXISTING_OBJECT objectActionRead Read the KiiObject.
    WRITE_EXISTING_OBJECT objectActionWrite Update and delete the KiiObject.

    * These symbols are defined in the KiiACLAction enumeration and can be specified like KiiACLAction.objectActionRead.

    Note: The "bucketActionReadObjects" action set to a bucket's ACL allows the subject to unconditionally read all KiiObjects in the bucket, even if they are not permitted the "objectActionRead" action on the KiiObjects in the bucket. For understanding how the action works, see ACL Customization Examples.

  • Subject

    This item defines "who" can execute.

    Subject Who can execute the designated action?
    KiiUser instance The specified user.
    KiiGroup instance The members of the specified group.
    KiiThing instance The specified thing.
    KiiAnyAuthenticatedUser Any authenticated users.
    KiiAnonymousUser Anonymous users.

    See Subject for the definition of the "Any authenticated users" and "Anonymous users".

Managing a KiiObject's ACL

You can add and delete an ACL entry in a KiiObject's ACL. You can also get a list of ACL entries.

Adding a KiiObject ACL entry

Here is an example of permitting the objectActionRead action to KiiAnyAuthenticatedUser.

Swift 3:

  • // Instantiate a KiiObject.
    let object = KiiObject(uri: "Set the URI of an existing KiiObject here")!
    
    var succeeded: NSArray?
    var failed: NSArray?
    
    // Instantiate the ACL of the KiiObject.
    let acl = object.objectACL
    
    // Create an ACL entry.
    let entry = KiiACLEntry(subject: KiiAnyAuthenticatedUser.aclSubject(), andAction: KiiACLAction.objectActionRead)!
    
    // Set the ACL entry to the ACL.
    acl.put(entry)
    
    do {
      // Save the ACL to the server.
      try acl.saveSynchronous(&succeeded, didFail: &failed)
    } catch let error as NSError {
      // Handle the error.
      // Failed to update one ACL entry at least.
      // Check the error description and succeeded/failed arrays.
      return
    }
  • // Instantiate a KiiObject.
    let object = KiiObject(uri: "Set the URI of an existing KiiObject here")!
    
    // Instantiate the ACL of the KiiObject.
    let acl = object.objectACL
    
    // Create an ACL entry.
    let entry = KiiACLEntry(subject: KiiAnyAuthenticatedUser.aclSubject(), andAction: KiiACLAction.objectActionRead)!
    
    // Set the ACL entry to the ACL.
    acl.put(entry)
    
    // Save the ACL to the server.
    acl.save { (acl : KiiACL , succeeded : [Any]?, failed : [Any]?, error : Error?) -> Void in
      if (error != nil) {
        // Handle the error.
        // Failed to update one ACL entry at least.
        // Check the error description and succeeded/failed arrays.
        return
      }
    }

Objective-C:

  • // Instantiate a KiiObject.
    KiiObject *object = [KiiObject objectWithURI:@"Set the URI of an existing KiiObject here"];
    
    NSError *error;
    NSArray *succeeded, *failed;
    
    // Instantiate the ACL of the KiiObject.
    KiiACL *acl = [object objectACL];
    
    // Create an ACL entry.
    KiiACLEntry *entry = [KiiACLEntry entryWithSubject:[KiiAnyAuthenticatedUser aclSubject]
                                             andAction:KiiACLObjectActionRead];
    
    // Set the ACL entry to the ACL.
    [acl putACLEntry:entry];
    
    // Save the ACL to the server.
    [acl saveSynchronous:&succeeded
                 didFail:&failed
                   error:&error];
    
    if (error != nil) {
      // Handle the error.
      // Failed to update one ACL entry at least.
      // Check the error description and succeeded/failed arrays.
      return;
    }
  • // Instantiate a KiiObject.
    KiiObject *object = [KiiObject objectWithURI:@"Set the URI of an existing KiiObject here"];
    
    // Instantiate the ACL of the KiiObject.
    KiiACL *acl = [object objectACL];
    
    // Create an ACL entry.
    KiiACLEntry *entry = [KiiACLEntry entryWithSubject:[KiiAnyAuthenticatedUser aclSubject]
                                             andAction:KiiACLObjectActionRead];
    
    // Set the ACL entry to the ACL.
    [acl putACLEntry:entry];
    
    // Save the ACL to the server.
    [acl saveWithBlock:^(KiiACL *acl, NSArray *succeeded, NSArray *failed, NSError *error) {
      if (error != nil) {
        // Handle the error.
        // Failed to update one ACL entry at least.
        // Check the error description and succeeded/failed arrays.
        return;
      }
    }];
  1. Create a KiiACL instance of the KiiObject by calling the objectACL() method.
  2. Create a KiiACLEntry instance and pass it as the argument of the put(_:) method. Here, a KiiAnyAuthenticatedUser instance is specified as the ACL entry's subject so as to permit the action to any authenticated users. If you set a KiiAnonymousUser instance as the subject instead, you can permit the same action to anonymous users. If you set a specific KiiUser instance, the action will be permitted to that user instance.
  3. Call the save(_:) method to send the request for updating the ACL to Kii Cloud.

See KiiACLEntry for more information about how you can specify other subjects like users and groups.

When you are adding multiple ACL entries, the entry registration is handled one by one. If an error occurs before all entries are registered, some entries will remain unregistered. In such a situation, you can get a list of ACL entries succeeded and failed to register from the succeeded and failed in the sample code.

Deleting a KiiObject ACL entry

To delete an ACL entry, create a KiiACLEntry instance with its grant set to false and save it. The ACL entry will be deleted from the server.

The following example deletes the ACL entry created in the previous sample code.

Swift 3:

  • // Instantiate a KiiObject.
    let object = KiiObject(uri: "Set the URI of an existing KiiObject here")!
    
    var succeeded: NSArray?
    var failed: NSArray?
    
    // Instantiate the ACL of the KiiObject.
    let acl = object.objectACL
    
    // Create an ACL entry.
    let entry = KiiACLEntry(subject: KiiAnyAuthenticatedUser.aclSubject(), andAction: KiiACLAction.objectActionRead)!
    entry.grant = false
    
    // Set the ACL entry to the ACL.
    acl.put(entry)
    
    do {
      // Save the ACL to the server.
      try acl.saveSynchronous(&succeeded, didFail: &failed)
    } catch let error as NSError {
      // Handle the error.
      // Failed to update one ACL entry at least.
      // Check the error description and succeeded/failed arrays.
      return
    }
  • // Instantiate a KiiObject.
    let object = KiiObject(uri: "Set the URI of an existing KiiObject here")!
    
    // Instantiate the ACL of the KiiObject.
    let acl = object.objectACL
    
    // Create an ACL entry.
    let entry = KiiACLEntry(subject: KiiAnyAuthenticatedUser.aclSubject(), andAction: KiiACLAction.objectActionRead)!
    entry.grant = false
    
    // Set the ACL entry to the ACL.
    acl.put(entry)
    
    // Save the ACL to the server.
    acl.save { (acl : KiiACL , succeeded : [Any]?, failed : [Any]?, error : Error?) -> Void in
      if (error != nil) {
        // Handle the error.
        // Failed to update one ACL entry at least.
        // Check the error description and succeeded/failed arrays.
        return
      }
    }

Objective-C:

  • // Instantiate a KiiObject.
    KiiObject *object = [KiiObject objectWithURI:@"Set the URI of an existing KiiObject here"];
    
    NSError *error;
    NSArray *succeeded, *failed;
    
    // Instantiate the ACL of the KiiObject.
    KiiACL *acl = [object objectACL];
    
    // Create an ACL entry.
    KiiACLEntry *entry = [KiiACLEntry entryWithSubject:[KiiAnyAuthenticatedUser aclSubject]
                                             andAction:KiiACLObjectActionRead];
    entry.grant = NO;
    
    // Set the ACL entry to the ACL.
    [acl putACLEntry:entry];
    
    // Save the ACL to the server.
    [acl saveSynchronous:&succeeded
                 didFail:&failed
                   error:&error];
    
    if (error != nil) {
      // Handle the error.
      // Failed to update one ACL entry at least.
      // Check the error description and succeeded/failed arrays.
      return;
    }
  • // Instantiate a KiiObject.
    KiiObject *object = [KiiObject objectWithURI:@"Set the URI of an existing KiiObject here"];
    
    // Instantiate the ACL of the KiiObject.
    KiiACL *acl = [object objectACL];
    
    // Create an ACL entry.
    KiiACLEntry *entry = [KiiACLEntry entryWithSubject:[KiiAnyAuthenticatedUser aclSubject]
                                             andAction:KiiACLObjectActionRead];
    entry.grant = NO;
    
    // Set the ACL entry to the ACL.
    [acl putACLEntry:entry];
    
    // Save the ACL to the server.
    [acl saveWithBlock:^(KiiACL *acl, NSArray *succeeded, NSArray *failed, NSError *error) {
      if (error != nil) {
        // Handle the error.
        // Failed to update one ACL entry at least.
        // Check the error description and succeeded/failed arrays.
        return;
      }
    }];

Note that the remove(_:) method of the KiiACL just deletes an ACL entry from the local modification list. The method does not delete an ACL entry set on the server. In the above sample code, we first register a request to remove the objectActionRead action from acl on the client and then execute the save(_:) method to reflect the request on the server. If you execute the remove(_:) method, it would remove the request from the ACL modification list, but not from the ACL on the server.

Getting a KiiObject's ACL

You can get the ACL set on a KiiObject. Even if you have not set any ACL entries in a KiiObject's ACL, you can get its default ACL.

Here is the sample code for getting a list of ACL entries as an NSArray.

Swift 3:

  • // Instantiate a KiiObject.
    let object = KiiObject(uri: "Set the URI of an existing KiiObject here")!
    
    // Instantiate the ACL of the KiiObject.
    let acl = object.objectACL
    
    do{
      // Get the ACL entries from the server.
      let aclList = try acl.listACLEntriesSynchronous() as! [KiiACLEntry]
      for entry in aclList{
        let action = entry.action
        let subject = entry.subject
        // Check the ACL entry.
      }
    }catch(let error as NSError){
      // Handle the error.
      return
    }
  • // Instantiate a KiiObject.
    let object = KiiObject(uri: "Set the URI of an existing KiiObject here")!
    
    // Instantiate the ACL of the KiiObject.
    let acl = object.objectACL
    
    // Get the ACL entries from the server.
    acl.listACLEntries { (retAcl : KiiACL, aclList : [Any]?, error : Error?) -> Void in
      if (error != nil) {
        // Handle the error.
        return
      }
      for entry in aclList as! [KiiACLEntry]{
        let action = entry.action
        let subject = entry.subject
        // Check the ACL entry.
      }
    }

Objective-C:

  • // Instantiate a KiiObject.
    KiiObject *object = [KiiObject objectWithURI:@"Set the URI of an existing KiiObject here"];
    
    // Instantiate the ACL of the KiiObject.
    KiiACL *acl = [object objectACL];
    
    NSError *error = nil;
    
    // Get the ACL entries from the server.
    NSArray *aclList = [acl listACLEntriesSynchronous:&error];
    if (error != nil) {
      // Handle the error.
      return;
    }
    for (KiiACLEntry *entry in aclList) {
      KiiACLAction action = entry.action;
      id subject = entry.subject;
      // Check the ACL entry.
    }
  • // Instantiate a KiiObject.
    KiiObject *object = [KiiObject objectWithURI:@"Set the URI of an existing KiiObject here"];
    
    // Instantiate the ACL of the KiiObject.
    KiiACL *acl = [object objectACL];
    
    // Get the ACL entries from the server.
    [acl listACLEntriesWithBlock:^(KiiACL *acl, NSArray *aclList, NSError *error) {
      if (error != nil) {
        // Handle the error.
        return;
      }
      for (KiiACLEntry *entry in aclList) {
        KiiACLAction action = entry.action;
        id subject = entry.subject;
        // Check the ACL entry.
      }
    }];
  1. Create a KiiACL instance of the KiiObject by executing the objectACL() method.
  2. Call the listACLEntries(_:) method to get the KiiObject's ACL as an NSArray of the KiiACLEntry.
  3. Parse through each ACL entry in the NSArray.

Trying to set an existing ACL entry will give you an error. By checking existing ACL entries beforehand as shown in this sample code, you can find which ACL entries should be set.

Troubleshooting

  • I got an error when I run my application multiple times

    The ACL entry should be registered just once (e.g., in the initialization) and should not be registered again in the next run.

    If you try to save an existing ACL entry, you will get an error. If your application runs the same ACL entry registration flow every time, therefore, you will get an error because the application attempts to re-register an already existing ACL entry.

    When you are adding multiple ACL entries, the entry registration is handled one by one. If an error occurs before all entries are registered, some entries will remain unregistered. To recover from such a situation, you will first need to get a list of the existing ACL entries, remove the duplicating ACL entries from the ACL modification list, and then register remaining entries. See Getting a KiiObject's ACL to learn how to get the list of the existing ACL entries.

  • I cannot delete an ACL entry

    You cannot delete default ACL entries applied to scope owners and KiiObject creators. See Cannot delete default ACL entries of scope owners and creators for more details.