KiiObject の ACL のカスタマイズ

KiiObject の ACL を設定することにより、Bucket 内の KiiObject それぞれに対するアクセス権を変更できます。

KiiObject の ACL エントリー

KiiObject の ACL エントリーに指定可能な項目は以下のとおりです。

  • アクション(アクセス制御)

    対象のユーザー/グループ/Thing が「何をできるか」を指定します。

    アクション コードでの指定 ※ 対象ユーザー/グループ/Thing ができること
    READ_EXISTING_OBJECT objectActionRead KiiObject の読み取り。
    WRITE_EXISTING_OBJECT objectActionWrite KiiObject の更新と削除。

    ※ これらのシンボルは、列挙型 KiiACLAction で定義されています。KiiACLAction.objectActionRead のように指定できます。

    注意Bucket のアクションである bucketActionReadObjects アクションを許可されているサブジェクトは、objectActionRead アクションを許可されているかどうかにかかわらず、Bucket 内の全ての KiiObject を無条件で読み取れます。動作例は ACL の変更の例 を参照してください。

  • サブジェクト(対象)

    「誰が」実行できるようになるかを指定します。

    サブジェクト 誰が実行可能か
    KiiUser インスタンス 指定されたユーザー。
    KiiGroup インスタンス 指定されたグループのメンバー。
    KiiThing インスタンス 指定された Thing。
    KiiAnyAuthenticatedUser ログイン済みの全ユーザー。
    KiiAnonymousUser 匿名ユーザー。

    ログイン済みの全ユーザーと匿名ユーザーの定義については、サブジェクト をご覧ください。

KiiObject の ACL の管理

KiiObject の ACL にエントリーを追加または削除できます。ACL エントリーの一覧を取得することもできます。

KiiObject に ACL エントリーを追加する

ACL エントリーを KiiObject に追加する例として、objectActionRead アクションを KiiAnyAuthenticatedUser に許可するサンプルコードを示します。

Swift:

  • // 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. objectACL() メソッドをコールして KiiACL のインスタンスを生成します。
  2. KiiACLEntry を生成して、 put(_:) メソッドの引数として渡します。この例では KiiAnyAuthenticatedUser インスタンスをサブジェクトとして設定し、ログイン済みの全ユーザーにアクセス権限を与えています。同様に KiiAnonymousUser を指定すれば匿名ユーザーに、特定の KiiUser を指定すれば、そのユーザーにアクセス権限を付与できます。
  3. save(_:) メソッドをコールして ACL の変更要求を Kii Cloud に送信します。

ACL エントリーにユーザーやグループなど、他のサブジェクトを指定する方法の詳細は KiiACLEntry を参照してください。

複数の ACL エントリーを追加する場合、SDK はそれらを 1 件ずつ処理するため、一部の ACL エントリーの処理が失敗する可能性があります。ACL の設定に失敗したときは、サンプルコード上の succeededfailed によって、成功した ACL エントリーの一覧と成功した ACL エントリーの一覧を取得できます。

KiiObject の ACL エントリーを削除する

設定されている ACL エントリーを削除するには、KiiACLEntrygrant を false にしたエントリーを作成して保存します。サーバー上の ACL から指定した ACL エントリーが削除されます。

以下は、上のサンプルコードによって作成された ACL エントリーを削除する例です。

Swift:

  • // 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;
      }
    }];

KiiACLremove(_:) メソッドは、クライアント側で準備中の「ACL の 変更リスト」のエントリーを削除するもので、サーバー上の ACL エントリーを削除するものではない点にご注意ください。上記のコードでは、クライアント上の acl に対して、objectActionRead アクションを伴う ACL エントリーの削除要求を登録してから、save(_:) でサーバーに反映しています。remove(_:) は、この ACL エントリーを変更リストから削除するためのもので、サーバー上の ACL を直接操作するためのものではありません。

KiiObject の ACL を取得する

KiiObject に設定されている ACL を取得できます。ACL エントリーを明示的に設定していない場合でも、デフォルトの ACL を取得することができます。

以下のように、ACL は ACL エントリーの NSArray として取得できます。

Swift:

  • // 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. objectACL() メソッドをコールして KiiACL のインスタンスを生成します。
  2. listACLEntries(_:) メソッドをコールして、登録されている ACL を KiiACLEntry の NSArray として取得します。
  3. NSArray の各エントリーを確認することで目的の処理を実行します。

ACL 設定の際、設定済みの ACL エントリーをさらに追加しようとするとエラーとなります。ここに示す方法で ACL を事前にチェックすることによって、必要な ACL エントリーの変更差分を作成できます。

期待どおりに動作しない場合

  • 複数回実行するとエラーになる

    ACL エントリーは初期化処理等で 1 回だけ書き換え、次回の実行時には再設定しないような実装が必要です。

    保存しようとしている ACL エントリーがすでに設定されていた場合、エラーになります。特に、同じ登録処理を複数回実行すると、登録しようとしている ACL エントリーがすでに存在することになるため、エラーになる点に注意が必要です。

    なお、複数の ACL エントリーは 1 件ずつサーバーに反映するため、途中でエラーが発生すると不完全な形で ACL エントリーが保存されます。このような状況から回復するには、既存の ACL をサーバーから一旦取得し、重複している ACL エントリーを削除してから登録するような処理が必要です。取得方法の詳細は KiiObject の ACL を取得する をご覧ください。

  • ACL エントリーを削除できない

    KiiObject 作成者やスコープオーナーにデフォルトで許可されるアクションの ACL エントリーは削除できません。詳細は スコープオーナーや作成者の ACL エントリーは削除できません をご覧ください。