The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
NAME
    CAS - Central Authorization Server

VERSION
    Version 0.89

SYNOPSIS
    CAS is intended to provide cross project (client) and cross platform
    authentication and authorization services. CAS allows a user to have a
    single username and password, which can be granted access to 0 or more
    different clients. Even fine grained access controls can be granted
    differently for any and all of the different clients that use CAS. The
    central object to CAS is client based, and can be used to manage
    multiple users.

      use CAS;

      my $client = CAS->new({CLIENT_ID => $id});

    or

      my $client = new CAS({CLIENT_NAME => 'Project Foo'});

      my $session = $client->authenticate({USERNAME => 'foo',
        PASSWORD => 'foobar'});
      my $can_do = $client->authorize({USER => $session,
        RESOURCE => 'resource1', MASK => 'create'});

    Code problems and mis-configurations should cause the call to die.
    Otherwise methods return undef on failure. Processing statements are
    stored in the calling objects message stack, which is reset with every
    method call.

     unless (defined $session) { die($client->messages) }

DESCRIPTION
    CAS provides a set of tools for accessing a central user database,
    allowing a single username and password to be used by multiple
    applications & sites (clients). Permissions can be granted however
    finely or loosely the developer finds useful. The system also stores
    some very basic session information, providing some very minimal usage
    auditing. A separate distribution, CAS-Apache2, provides a mod_perl 2
    application for protecting web sites from CAS.

  USAGE OVERVIEW
    You first must create a CAS client object. Clients are defined in the
    database in advance by the CAS administrator. You will need to know the
    client ID, name or domain, all of which need to be unique to each
    client.

    Examples:

      my $client = CAS->new({CLIENT_ID => 2});

    or

      my $client = CAS->new({CLIENT_NAME => 'Project Foo'});

    You can fetch information about the client from this object if needed.
    But its main purpose is to authenticate users and check their
    authorizations. As the users can be granted access to any client, the
    specific client used to create this object doesn't matter if you just
    want to authenticate the user.

      my $session = $client->authenticate({});

    The session token is a unique identifier for the particular session. It
    can be returned to the application as a key for session tracking,
    allowing for persistent login sessions and such. It is also used to
    identify the user when checking authorization.

      my $is_authorized = $client->authorize({SESSION => $session,
        RESOURCE => $request, MASK => 8});

    The session token can also be used to fetch a user object, which
    remembers the client under which it was created.

      my $user = $client->user($session);

    This user object, CAS::User, can be used to get information about the
    user. Security of the session token and its use is left to the
    discretion of the caller.

  CLIENT OBJECT ATTRIBUTES
    user_info_fields
        Returns a hash reference containing the field names in the UserInfo
        table.

    supl_user_info_fields
        Returns a hash reference containing the field names in the clients
        supplemental_user_table, if defined.

    supplemental_user_table
        The name of the clients supplemental user table.

    admin_email
        The email address for the user designated as the administrator of
        the client.

    debug
        The debug level for the client object. The default level is
        determined by the CAS configuration file. This is the only CAS
        client object attribute which can be set.

          $client->debug(2);

    id  The ID of the client.

    name
        The name of the client.

    default_group
        The default group assigned to new users registering through the
        client.

    domain
        The domain of the client. This can be used to allow a local
        interface to determine what client to assign based on the IP or such
        of a remote connection.

    base_path
        The base path for this clients application(s) or work space.
        Primarilly used for websites where the project area defined for the
        client is a subsection of a website.

    description
        A description of the client.

    cookie_name
        Primarilly used by CAS-Apache2 for determining the name of the
        cookie in whcih to store or fetch the session token.

    timeout
        The period of incativitiy after which a user is forced to
        re-authenticate.

  MESSAGING
    All methods produce some internal messages while processing. When a
    method is first invoked on a CAS object, any old messages are cleared
    out and its initial result code is set to ERROR (so that if anything
    unexpected happens it has the result we would want - ERROR).

    There are a wide variety of possible result codes that a method could
    use. CAS::Messaging The specific ones that a method might set are
    described in the methods specific documentation. However there are three
    that are the most common, ERROR, BAD_REQUEST and OK which we will use in
    the following examples. The status is set to ERROR both when a method
    first starts and on non-fatal but still critical problems. BAD_REQUEST
    is generally set when a method call was properly constructed, but
    required parameters were missing or in an invalid format. OK is usually
    the status set after it has completed its job sucsesfully, just before
    returning.

   Messaging methods
    response_is
        Used to check the status set by the last method called on the
        object:

          $client->response_is('STATUS_NAME');

    response_code
        Returns the status set by the last method called on the object (as
        text):

          my $status = $client->response_code;

    messages
        Returns all the messages generated by the last method called on the
        object. If called in list context returns a list of the messages. If
        called in scalar context returns a string, starting with the class
        name of the object, followed by all the messages generated joined on
        "; ".

          my $messages = $client->messages;

    Be sure to see CAS::Messaging for more details.

   Example
    Calling authentication with the USERNAME missing:

      %args = get_user_credentials();
      my $session = $client->authenticate(\%args);
      unless (defined $session) {
        if ($client->response_is('BAD_REQUEST')) {
          warn "Can't authenticate - missing required arguments: "
            . $client->messages;
          # try get_user_credentials again?
        } # if bad request
        else {
          my $status = $client->response_code;
          die "Problem with authentication - Status: $status, Messages: " . 
            . $client->messages;
        } # something else went wrong?
      } # unless session token returned

  FUTURE PLANS
    Here is the BIG wish list for CAS. For more humble feature requests, see
    <http://rt.cpan.org/NoAuth/Bugs.html?Dist=CAS>

    XML/YAML/SOAP/JSON
        I'd like to have optional handlers for accepting and replying to
        requests through one or more data exchange formats. Most likely I'll
        do this not through this core distribution, but through special
        mod_perl handlers under the CASS::Apache distribution. This will be
        the way through which not only remote applications access CAS from a
        different system (other than browsers accessing local pages), but
        also how any other languages could potentially use CAS
        authentication and authorization from a central database.

    LDAP & Kerberos
        It would be great to have optional plugins or such that extend CAS
        to work seemlessly along side both LDAP and Kerberos. An earlier
        incarnation of this system actually did interact with Kerberos. If a
        user regestered with their kerberos username and password, CAS
        verified authentication from then on against Kerberos. It even
        fetched some user info from the Kerberos server using ph. The schema
        still has fields for indicating if a user record relates to a
        kerberos or ldap system, but there is no functionality at this time
        for such.

METHODS
  new
    Create a new client object.

    PARAMETERS:

    CLIENT_ID: The database ID of the client which is seeking to connect to
    CAS.

    CLIENT_NAME: The name of the client which is seeking to connect to CAS.

    CLIENT_DOMAIN: The domain of the client which is seeking to connect to
    CAS.

    You can use any one. If more than one is defined they are checked in the
    order listed.

    OPTIONS:

    CONFIG: Alternate configuration file. Defaults to '/etc/CAS.yaml'.

    DEBUG: Set the DEBUG level for this object.

  authenticate
    This function is called to verify the username and password provided by
    the user. It will imediatly return undef and set the response code to
    BAD_REQUEST unless both the username and password were provided (well,
    technically, evaluate to true). It then checks that the password
    provided matches the one stored for that user.

    Perls crypt function is called using the suplied password as the word
    and the password from the db as the salt. If the result matches the
    stored password, access will be granted. A session key is generated
    using md5_hex and the user ID and time are stored in the db on that key.
    Also stored are either the users IP address (if supplied) or the root
    caller() otherwise.

    If authentication fails, NOT_FOUND is returned. If authentication
    succedes the md5_hex key is returned. The key is intended to be used by
    CAS as a session token for authorize after first authenticated. Any
    error message can be found in $client->errstr.

    PARAMETERS:

    USERNAME: The username.

    PASSWORD: The users password.

    OPTIONS:

    IP: The remote connection IP. If present at authentication, the IP will
    be required to be provided and match during any subsiquent authorization
    check.

  authorize
    This checks the database to see if the user is currently logged in and
    if they are allowed to use the specified resource.

    PARAMETERS:

    SESSION: The session token returned by CAS when the user was
    authenticated and logged in. This is used to get the user information
    required for checking that user is logged in and that their session has
    not timed out. ***SECURITY*** It is up to you to make sure that this
    value is kept private and secure during the session.

    USER: Alias for SESSION.

    RESOURCE: This is the resource definition that will be checked in the
    database.

    PERMISSIONS: This is the type of action you want to check if the user
    has permission for relative to the RESOURCE. The allowed values are
    read, modify, create and delete. Create refers to permision to create a
    new record which uses the refered to resource as a foreign key, or is
    under the refered resource 'tree'.

    OPTIONS:

    MASK: This is an integer mask of permissions to be checked for the
    specified RESOURCE. This can optionaly be used instead of PERMISSIONS,
    and is the only way to specify requests on more than one type of
    permission at the same time. The Values are 8 = read, 4 = modify, 2 =
    create, 1 = delete. To check for multiple permissions at the same time
    simply sum all the permissions you want to check. For example, to check
    for read and modify permision, provide 12 (8+4) as the value for MASK.
    MASK overides PERMISSIONS if both are specified.

    MATCHKEY: A matchkey can be used to specify a specific element or key
    match required. For example, RESOURCE my specify a particular table in a
    database, with MATCHLEY specifying the primary key match required. Or if
    RESOURCE was a web page, MATCHKEY may indicate a specific form element.

    IP: The remote IP of the user. If this was provided during
    authentication then it is REQUIRED for authorization and the IP's must
    match.

  user
    Access the user object (CAS::User) for authenticated users. Method takes
    a single argument, the authenticated users session token.

INSTALLING
    There are a few steps you will need to handle before you can proceed to
    the usual CPAN distribution make, make test, make install magic.
    Primarilly, you need to create the CAS database before any tests beyond
    syntax checking will pass.

    % tar -xzf CAS-x.xx.tar.gz % cd CAS-x.xx % pwd /path/to/CAS-x.xx % mysql
    -u root -p password: mysql> CREATE DATABASE CAS; mysql> USE CAS; mysql>
    source /path/to/CAS-x.xx/CAS.sql mysql> GRANT ALL ON CAS.* TO CAS_query
    IDENTIFIED BY 'local_passwd' mysql> GRANT ALL ON CAS.* TO
    CAS_query@localhost IDENTIFIED BY 'local_passwd' mysql> exit % perl
    Makefile.PL % make % make test % make install

    When running Makefile.PL for the first time you will be asked a bunch of
    questions. Answer them appropriately for your system. The DB_* items all
    relate to the information you provided mysql when setting up the
    database. If at any time you want to regenerate the configuration file,
    just delete it and rerun Makefile.PL.

AUTHOR
    Sean P. Quinlan, "<gilant at gmail.com>"

development notes
  groups
    Groups are always associated with a client. However, groups from one
    client can be granted permissions on any other client. Generally all
    groups are owned by the CAS Admin client but it is possible to have
    admin tools on another client and allow them to manage their own
    group(s). The admin user for any client can alter/drop existing groups
    under that client. Additionally groups can have a 'Owner' specified.
    This is generally a user who also has rights to modify the group and
    add/remove members, but not to delete it.

BUGS
    Please report any bugs or feature requests to "bug-cas at rt.cpan.org",
    or through the web interface at
    <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=CAS>. I will be
    notified, and then you'll automatically be notified of progress on your
    bug as I make changes.

HISTORY
    0.01    Original version; created by module-starter

    0.1     Initial code port from CAS. History below to .30_2 ported from
            CAS.

    0.2     Basic required functionality for check auths in place. Apache
            auth handlers done as well as simple Login handler. Core tests
            written and passing, user tests of Apache handlers pass basic
            required functionality.

    0.21    User module functional and all basic methods in place. No
            automated tests for it yet but that will be my next task before
            moving on to the Apache handlers for registering a new user and
            a user view edit account handler. Also started working on the
            docs.

    0.22    Added tests for user object and disable/enable methods. Small
            additions to docs, like fixing my email address in this package!
            ;)

    0.23    Most of the basic Apache stuff has been worked out. The CAS.yaml
            file was expanded and commented. I made a CAS.conf for all our
            Apache config stuff so admins can just Include it rather than
            edit the main conf. So far registering a new user & logging are
            functional if not quite complete or pretty.

    0.3_1   The internals of this module are pretty stable now. I added the
            krb5_authentication function and added code to
            check_authentication to check krb5 auth if required in conf or
            specified in user table.

    0.30_2  Ported to stub distribution generated by module-starter. Split
            Apache and core CAS functionality into two dists. Started
            removing krb5 support from core modules. If I continue to
            support it, it will be as an optional extension.

    0.40    Entered heavy development - many change entries were not made.
            Guessing from here to version .89

    0.41    Finished post-port cleanup. Added some very simple tests.

    0.42    Split out Messaging.pm and did a little more cleanup on CAS.pm

    0.43    Reworked parts of Messaging.pm, updated everything to use
            messaging.

    0.44    Did some code cleanup on Users.pm, improved AUTOLOADS, adding
            %allowed with bitmasks. Added a few more tests, most of which
            fail.

    0.50    Started working on API and getting tests to pass. Small
            adjustments to schema.

    0.52    Debugging. Tests passing.

    0.60    Completely changed object relations, making the CAS object all
            about the client and adding user caching. User.pm is no longer a
            subclass of CAS and authentication happens through the client
            object.

    0.61    Updated tests and made some changes to API based on working out
            tests.

    0.80    Wrote a slew more tests, got all the client and user tests
            passing.

    0.81    Added generation of CAS.yaml to Makefile.PL and wrote
            post_install.prl.

    0.82    Refined CAS.yaml generation some and tripled the number of
            tests.

    0.83    Got auth tests passing!

    0.86    All basic tests pass for existing funtionality. Can add, load,
            edit & disable users. Client object can handle multiple users,
            caching user objects by session token and authenticate and
            authorize against permissions in database.

    0.87    Improved some error statements. Updated MANIFEST so the new
            modules were included in the distribution. (d'oh!) Allowed
            caller to supply ID to User->new to support installs where there
            is already a database of users (or employees) where use of
            pre-existing IDs is important.

    0.88    Broke up Config.pm, mainly to separate database connection from
            load and to use a database connection routine that captured the
            db password in a closure. This was required to support
            CAS-Apache2, where storing the database connection in the global
            client object caused 'Command out of sync' errors on some
            otherwise valid setups.

    0.89    Updated the documentation. Made the fields in the clients table
            attributes of the client object. Added some info on the caller
            to messages when debuging.

SUPPORT
    You can find documentation for this module with the perldoc command.

        perldoc CAS

    On most Unix systems you can probably also find the documentation under
    the man pages.

    shell> man CAS

    Please join the CAS mailing list and suggest a final release name for
    the package.

    http://mail.grendels-den.org/mailman/listinfo/CAS_grendels-den.org

    You can also look for information at:

    * AnnoCPAN: Annotated CPAN documentation
        <http://annocpan.org/dist/CAS>

    * CPAN Ratings
        <http://cpanratings.perl.org/d/CAS> =item * Search CPAN

        <http://search.cpan.org/dist/CAS>

  BUGS
    For bugs, bug reporting and feature requests, see CPAN's request tracker

    <http://rt.cpan.org/NoAuth/Bugs.html?Dist=CAS>

ACKNOWLEDGEMENTS
    The Bioinformatics Group at Massachusetts General Hospital during my
    tenure there for development assistance and advice, particularly the QA
    team for banging on the project code.

COPYRIGHT & LICENSE
    Copyright 2004-2007 Sean P. Quinlan, all rights reserved.

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