NAME
    RDF::ACL - access control lists for the semantic web

SYNOPSIS
      use RDF::ACL;
  
      my $acl  = RDF::ACL->new('access.ttl');
      my $auth = $acl->allow(
        webid => 'http://example.com/joe#me',
        item  => 'http://example.com/private/document',
        level => ['Read', 'Write'],
        );
      $acl->save('turtle', 'access.ttl');
  
      # later...
  
      if ($acl->check('http://example.com/joe#me',
                      'http://example.com/private/document',
                      'Read'))
      {
        print slurp("private/document");
      }
      else
      {
        print "Denied";
      }
  
      # later...
  
      foreach my $reason ($acl->why('http://example.com/joe#me',
                                    'http://example.com/private/document',
                                    'Read'))
      {
        $acl->deny($reason) if defined $reason;
      }
      $acl->save('turtle', 'access.ttl');

DESCRIPTION
    Note that this module provides access control and does not perform
    authentication!

  Constructors
    `$acl->new($input, %args)`
        Creates a new access control list based on RDF data defined in $input.
        $input can be a serialised string of RDF, a file name, a URI or any
        other input accepted by the `parse` function of
        RDF::TrineX::Functions.

        `new()` can be called with no arguments to create a fresh, clean ACL
        containing no authorisations.

    `$acl->new_remote($endpoint)`
        Creates a new access control list based on RDF data accessed via a
        remote SPARQL Protocol 1.0 endpoint.

  Public Methods
    `$acl->check($webid, $item, $level, @data)`
        Checks an agent's authorisation to access an item.

        $webid is the WebID (URI) of the agent requesting access to the item.

        $item is the URL (URI) of the item being accessed.

        $level is a URI identifying the type of access required. As special
        cases, the case-insensitive string 'read' is expanded to the URI
        <http://www.w3.org/ns/auth/acl#Read>, 'write' to
        <http://www.w3.org/ns/auth/acl#Write>, 'append' to
        <http://www.w3.org/ns/auth/acl#Append> and 'control' to
        <http://www.w3.org/ns/auth/acl#Control>.

        If the access control list is local (not remote), zero or more
        additional RDF graphs can be passed (i.e. @data) containing data to
        take into consideration when checking the agent's authorisation. This
        data is trusted blindly, so should not include data that the user has
        themselves supplied. If the access control list is remote, then this
        method throws an error if any additional data is provided. (A remote
        ACL cannot take into account local data.)

        If $level is provided, this method returns a boolean.

        If $level is undefined or omitted, this method returns a list of URIs
        which each represent a type of access that the user is authorised.

    `$acl->why($webid, $item, $level, @data)`
        Investigates an agent's authorisation to access an item.

        Arguments as per `check`, however $level is required.

        Returns a list of authorisations that justify a user's access to the
        item with the given access level. These authorisations are equivalent
        to $authid values provided by `allow()`.

        In some cases (especially if the authorisation was created by hand,
        and not via `allow()`) an authorisation may not have an identifier. In
        these cases, the list will contain undef.

    `$acl->allow(%args)`
        Adds an authorisation to the ACL. The ACL must be mutable.

        The method takes a hash of named arguments:

          my $authid = $acl->allow(
            webid => 'http://example.com/joe#me',
            item  => 'http://example.com/private/document',
            level => ['Read', 'Write'],
            );

        'item' is the URI of the item to authorise access to. As an
        alternative, 'item_class' may be used to authorise access to an entire
        class of items (using classes in the RDFS/OWL sense of the word). If
        neither of these arguments is provided, then the method will throw an
        error. Both may be provided. Either or both may be an arrayref,
        because an authorisation may authorise access to more than one thing.

        'container' is an alternative to using 'item' or 'item_class'. It
        specifies the URI for a resource which in some way is a container for
        other resources. Setting authorisations for a container allows you to
        set a default authorisation for new items created within that
        container. (You must use the `created()` method to notify the ACL
        about newly created items.)

        'webid' is the WebID (URI) of the person or agent being granted
        access. As an alternative, 'agent_class' may be used to authorise
        access to an entire class of agents. If neither is provided, an
        agent_class of <http://xmlns.com/foaf/0.1/Agent> is assumed. Both may
        be provided. Either or both may be an arrayref, because an
        authorisation may authorise access by more than one agent. (For
        consistency with 'item', 'agent' is supported as a synonym for
        'webid'.)

        'level' is the access level being granted. As with the `check` method,
        the shortcuts 'read', 'write', 'append' and 'control' may be used. An
        arrayref may be used. If no level is specified, 'read' is assumed.

        This authorisation is not automatically saved, so it is probably
        useful to call `save()` after adding authorisations.

        The method returns an identifier for the authorisation. This
        identifier may be needed again if you ever need to `deny()` the
        authorisation.

        This method is aware of `i_am()`/`who_am_i()`.

    `$acl->deny($authid)`
        Completely removes all traces of an authorisation from the ACL.

        The authorisation identifier can be found using `why()` or you may
        have remembered it when you first allowed the access. In some cases
        (especially if the authorisation was created by hand, and not via
        `allow()`) an authorisation may not have an identifier. In these
        cases, you will have to be creative in figuring out how to deny
        access.

        Returns the number of statements removed from the ACL's internal model
        as a result of the removal. (This will normally be at least 3.)

        This authorisation is not automatically saved, so it is probably
        useful to call `save()` after removing authorisations.

        This method is aware of `i_am()`/`who_am_i()`.

    `$acl->created($item, $container)`
        Finds all authorisations which are the default for new items within
        $container and clones each of them for newly created $item.

        Returns a list of authorisation identifiers.

    `$acl->i_am($webid)`
        Tells the ACL object to "act like" the agent with the given WebID.

        If the ACL object is acting like you, then methods that make changes
        to the ACL (e.g. `allow()` and `deny()`) will only work if you have
        'Control' permission over the resources specified.

        $webid can be null to restore the usual behaviour.

        Returns the previous WebID the ACL was acting like as a URI object.

    `$acl->who_am_i`
        Returns the WebID of the agent that ACL is acting like (if any).

    `$acl->save($format, $filename)`
        Serialises a local (not remote) ACL.

        $format can be any format supported by the `serialize` function from
        RDF::TrineX::Functions.

        If $filename is provided, this method writes to the file and returns
        the new file size in bytes.

        If $filename is omitted, this method does not attempt to write to a
        file, and simply returns the string it would have written.

    `$acl->is_remote`
        Returns true if the ACL is remote; false if local.

    `$acl->is_mutable`
        Can this ACL be modified?

    `$acl->model`
        The graph model against which authorisation checks are made.

        Returned as an RDF::Trine::Model object.

    `$acl->endpoint`
        The endpoint URI for remote (non-local) ACL queries.

        Returned as a URI object.

BUGS
    Please report any bugs to <http://rt.cpan.org/>.

SEE ALSO
    Web::ID.

    <http://www.w3.org/ns/auth/acl.n3>.

    <http://www.perlrdf.org/>,
    <http://lists.foaf-project.org/mailman/listinfo/foaf-protocols>.

AUTHOR
    Toby Inkster <tobyink@cpan.org>.

COPYRIGHT AND LICENCE
    This software is copyright (c) 2010-2013 by Toby Inkster.

    This is free software; you can redistribute it and/or modify it under the
    same terms as the Perl 5 programming language system itself.

DISCLAIMER OF WARRANTIES
    THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
    WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
    MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.