notes.pod is no longer necessary v0.01
Yuval Kogman [Sun, 27 Nov 2005 21:14:18 +0000 (21:14 +0000)]
notes.pod [deleted file]

diff --git a/notes.pod b/notes.pod
deleted file mode 100644 (file)
index 2de9ef9..0000000
--- a/notes.pod
+++ /dev/null
@@ -1,536 +0,0 @@
-=pod
-
-=head1 CORE CONCEPTS
-
-=item authentication
-
-Authentication means ensuring the user is who they claim to be.        
-
-=item authorization
-
-Once a user's identity is known and authenticated, we can decide what they are
-authorized to do.
-
-=head2 Authentication
-
-The process of authenticating the user is, almost always, asking the user to
-prove they know a secret that only the real user would know.
-
-Ways of proving you know a secret are:
-
-=over 4
-
-=item cleartext password
-
-Just tell the secret to the other side to prove you know it.
-
-=item challange/response
-
-Prove you know the secret without revealing it, and without the possibility of
-an attacker gaining access even if they get a copy of the data sent from the
-client.
-
-=over 4
-
-=item 1
-
-The server sends some random data, unique for each request
-
-=item 2
-
-The client combines the random data with the secret, and digests that
-
-=item 3
-
-The server combines the data with the password as well, and makes sure the
-digest is the same as what the user sent.
-
-=back
-
-Can possibly be implemented optionally using javascript on the client side if
-it's enabled.
-
-=item public key cryptography
-
-...
-
-=back
-
-=head2 Authorization
-
-=over 4
-
-=item Role based classification 
-
-Each user plays in several roles. Restricted actions can then check that the
-user belongs to a certain role (for example, for the 'delete' action you might
-want to ensure that a user is an 'editor').
-
-Since users are allowed to be in an arbitrary amount of roles the logic is
-simple and effective.
-
-=item ACLs
-
-Cascading on top of roles, and more tightly coupled with catalyst is the
-possibility of access control lists in two namespaces:
-
-=over 4
-
-=item *
-
-The perl package namespace
-
-=item *
-
-The mapped URI space
-
-=back
-
-For example, you could say that the controller MyApp::C::AdminPanel requires
-the role 'admin'.
-
-This should resemble the way apache can provide access control for
-C<< <Location ...> >> and C<< <Directory ...> >>.
-
-=back
-
-=head1 ASPECTS OF IMPLEMENTATION
-
-=head2 Authentication
-
-Authentication needs to take care of two things:
-
-=over 4
-
-=item *
-
-Storage of the user data
-
-=item *
-
-Authentication of credentials against storage
-
-=back
-
-Ideally the two are decoupled, with the following call chain relationship:
-
-When application asks the authentication plugin to verify credentials, the
-credential verification plugin asks storage retrieve the user based on the user
-ID (the credential plugin knows what part of the credential is a user ID).
-
-A storage must return an object representing the user, whose API is irrelevant
-here.
-
-It is up to the user to synchronize the user info storage with the credential
-plugin, so that the value retrieved from storage is the value the credential
-plugin expects.
-
-For example, the user/password credential plugin will look something like this:
-
-       sub authen_login {
-               my ( $c, %opts ) = @_;
-               my $user = $opts{user} || $c->auth_get_user( %opts ); # note that
-               # credential plugin methods should accept a user object if they are
-               # provided with one
-
-               if ( $user->password eq $opts->{password} ) {
-                       ...
-               }
-       }
-
-A situation where login/password authentication would have to be changed is if
-the credential system uses /etc/passwd storage, for example. Since /etc/passwd
-contains hashes of passwords, we can't compare the password directly. The
-credential system must know to take care of this.
-
-The login/password plugin should probably be a bit more lax, making checks on
-$user to see what the user supports:
-
-       if (my $hash = eval { $user->hashed_password }) {
-               my $digest = Digest->new( $user->hash_algorithm );
-               ...
-               $digest->digest eq $hash; # yes, this is binay, not hex or whatever
-       } elsif (my $crypt = eval { $user->crypted_password }) {
-               return crypt( $password, $crypt ) eq $crypt;
-       } elsif (my $clear = eval { $user->password }) {
-               return $passwd eq $clear;
-       } else {
-               Catalyst::Exception->throw("password storage scheme possibilities exhausted");
-       }
-
-Or less optimistically
-
-       if ( $user->supports(password => "hashed") ) {
-               my $hash = $user->hashed_password;
-               ...
-       }
-
-C<supports> in the user base class should look like this:
-
-       sub supports {
-               my ( $self, @path ) = @_;
-
-               my $cursor = $self->_supports; # this is a nested hash
-
-               while (@path) {
-                       ref $cursor or return undef;
-                       $cursor = $cursor->{ shift @path };
-               }
-
-               return $cursor && !ref($cursor);
-       }
-
-Which just goes through a nested hash, populated by the implementation class.
-
-The structure of this hash should be converged by the community, and should
-look something like this for a plugin that supports everything I can think of:
-
-       {
-               password => {
-                       hash => 1,
-                       crypt => 1,
-                       clear => 1,
-               },
-               key {
-                       gpg => 1,
-                       ssh => 1,
-                       ...
-               },
-               secureid => 1,
-               kerberos => 1, # maybe this needs to be deeper? i dunno
-       },
-
-
-In the event that the storage backend implies a certain format, the credential
-verification and storage plugins should ship together, for convenience.
-
-=head3 Testing for authentication
-
-Once authenticated the authentication plugin sets the C<user> accessor in the
-context object to contain the user object.
-
-=head3 Stores are just models
-
-To make things more flexible, stores are really just models.
-
-To make things easy a "default" auth storage can be [automatically] selected
-for the user for the more common situation of one auth driver per app:
-
-       sub auth_get_user {
-               my ( $c, %opts ) = @_;
-
-               ( $opts->{store} || $c->find_auth_store )->auth_get_user( %opts );
-       }
-
-       sub find_auth_store {
-               my $c = shift;
-
-               $c->config->{auth}{default_store} || ...;
-       }
-
-Ofcourse, %opts should not be just delegated blindly in the production
-versions. Perhaps even L<Params::Validate> is in order.
-
-=head3 Integration with Catalyst::Plugin::Session
-
-If a session plugin is loaded (C<< $c->isa("Catalyst::Plugin::Session) >>), it
-should also store the user ID in C<< $c->session->{user} >> unless
-C<< $c->config->{authentication}{use_session} >> is a false value (true by
-default).
-
-=head2 Authorization
-
-Authorization uses the same storage backend as authentication - that's why they
-are decoupled.
-
-Like the credential verification part, the authorization system simply assumes
-that the necesseary information is in the object representing the user.
-
-The API required should be strictly documented, in order to minimize confusion.
-
-For example, the role authorization plugin may require a C<roles> method:
-
-       use Quantum::Superpositions qw/all any/;
-
-       sub authz_check_roles {
-               my ( $c, @required_roles ) = @_;
-
-               all(@required_roles) == $c->user->roles;
-       }
-
-Which must be arranged by the authentication storage plugin's user class.
-
-In order to facilitate this all storage plugins, either trivial ones, should
-use factory methods for generating the user object. This allows the user to
-override the method, replacing the user class with their own, extended class
-that provides the necessary glue.
-
-=head1 DESIRED PLUGINS
-
-=head2 Credential Verification
-
-=over 4
-
-=item login/password
-
-Requires a C<password> method from the user, checks for equality
-
-=item unix passwd
-
-Requires a C<crypted_passwd> method from the user, checks for equality after crypt
-
-=item challenge response
-
-pretends to be a login/password compatible plugin, and will fall back to it,
-unless the client can use javascript to create a digest of the password and a
-seed instead of sending the actual password.
-
-=item http auth
-
-Send 401 status code, read back authentication headers
-
-=item delegated
-
-a passive authentication plugin that checks whether the user logged in using
-the engine's backend (e.g. apache) and provides a handle object representing
-that user that is not tied to any storage.
-
-=head2 Storage
-
-=over 4
-
-=item DBIC/CDBI
-
-User table, contains arbitrary fields and relationships.
-
-This should simply provide the interface for storage plugins based on a table
-in config.
-
-=item LDAP
-
-FIXME I'm not quite sure how LDAP looks from an OO perspective.
-
-=item htpasswd
-
-Implies credential verification for the various types of passwords htpasswd
-supports.
-
-Can use extra info field for additional interface glue. For example:
-
-       sub roles {
-               my $self = shift;
-               split(",", $self->info);
-       }
-
-=item passwd
-
-A subset of htpasswd, can use comment field for extended info like htpasswd.
-
-=item perl hash of objects
-
-a hash of user object keyed by user ID can prove very convenient for rapid
-development.
-
-=back
-
-=head2 Authorization
-
-=over 4
-
-=item roles
-
-=item ACLs
-
-A complex interface that layers on roles and automatically checks role
-membership for certain areas of an application based on a perl data structure.
-
-=back
-
-=head1 GUIDELINES
-
-Avoid new formats - there are enough standard formats out there that we can
-use. No need for XML, YAML, etc authentication support in the core of these plugins.
-
-These plugins can be supplemented by ::Simple namespaces that have the extra sugar.
-
-This is one of the reasons Authentication::Simple sucked so bad - it's file
-parser was half baked, it was very inefficient, and about 10x as many lines of
-code it could have been if the user simply had to put a perl hash of arrays in
-the config.
-
-
-=head1 TODO
-
-=over 4
-
-=item Look into L<Apache::AuthCookie>
-
- < kgftr|konobi> nothingmuch: Apache::AuthCookie has a really nice way of
- dealing with multiple types of auth (like roles, groups, etc)
-
-=back
-
-
-=head1 API tree
-
-This tree proposes a list the classes in the authentication/authorization
-plugins, as well as their methods.
-
-It's purpose is to help synchronize the authen/authz efforts, and is not to be
-considered a formal spec.
-
-       * Authentication (umbrella plugin)
-               - set_authenticated( $user ) # set $c->user, and $c->session->{user_id} = $user->id
-               - logout # delete $c->user, delete $c->session->{user_id}
-               - user # currently logged in user, if any
-               - prepare (extended) # checks session to see if a user should be logged in
-               * User
-                       - id (the value that can be used to get the user with)
-                       - supports
-                         method name, or hierarchy
-                         The methods listed under a hierarchy mean the methods you can call
-                         if $user->supports( qw/password clear/ ) then you can $user->password safely
-                               * password
-                                       * clear
-                                               - password
-                                       * hashed
-                                               - hashed_password
-                                               - hash_algorithm
-                                       * crypted
-                                               - crypted_password
-                               * roles
-                                       - roles
-                               * ...
-               * Store (plugin)
-                 the storage plugin is a thin wrapper around a store model, that
-                 provides a notion of a default store for easy dwimming.
-                 it's two methods are just dump delegations to $c->config->{authentication}{store}
-                       - get_user( $id )
-                       - user_supports( $id )
-                       * DBIC
-                         generates an object, puts it in $c->{authetnciation}{store}
-                         this object inherits the model class but is not really a model,
-                         instead it delegates to the real DBIC model under it
-                       * ... # each store impl has a dual life as a plugin
-               * Store::...::Model
-                 provides the actual storage model glue. For example, in DBIC get_user
-                 will do a retrieve on the user table.
-                       - get_user( $id ) # $id is username, or other credential a user might type in
-                       - user_supports
-                         like calling ->supports on the user, but applies to all users
-                         if one user supports X but another doesn't, the global check will say they both don't
-                       * Minimal
-                         A nested hash in $c->config->{authentication}{entries}
-                           {
-                             user_id => $user_obj || $hash_ref
-                               }
-                         Hash ref will auto instantiate into a user obj that provides a default
-                         implementation of supports and some accessors, based on the keys
-                       * DBIC
-                         storage dependent
-                               - roles # has_many rel
-                               - password # column
-                               - crypted_password # column
-                               - hashed_password # column
-                               - hash_algorithm # column
-                               - ... # columns
-                       * UNIX (Unix::PasswdFile, Unix::GroupFile)
-                         provides simple role based authentication
-                         implies the Password credential checker
-                               - uid
-                               - name
-                               - crypted_password
-                               - gid
-                               - comment
-                               - home
-                               - shell
-                               - groups/roles # aliases
-                               - add_group/add_role
-                                 uses group password to temporary add a group/role (newgrp)
-                                 stores the added groups in the session data
-                       * Htpasswd (Apache::Htpasswd)
-                         has optional role based authentication in the info field
-                         ($c->config->{authentication}{htpasswd}{role_delimiter} defaults to ',')
-                         implies the Password credential checker
-                               - name
-                               - password # htpasswd -p
-                               - crypted_password # htpasswd -d
-                               - hashed_password # htpasswd -s, htpasswd -m
-                               - hash_algorithm
-               * Credential (plugin)
-                 all $user args can be either user objects, or user ids that will be queried from
-                 $c->config->{authentication}{store}
-                       * Password
-                               - login( $user, $password )
-                                 tries hashed password, crypted password, and password based on caps of user obj
-                       * CRAM (requires session)
-                         challange is the session ID
-                         response is hash( challange + ( password | crypted_password | hashed_password ) )
-                         possibly backed by javascript on the client side
-                               - authenticate_cram( $user, $response )
-                                 hashes $c->sessionid and password variant based on config
-                       * SRP (probably useless, but at least take a look - SSL uses it)
-                         possibly backed by javascript on the client side
-                       * HTTP Auth  (like Catalyst::Plugin::Authentication::CDBI::Basic does)
-                         subclasses Credential::Password, and just calls login automatically from prepare
-                         takes a value to $c->forward to in case the user isn't authenticated, to generate 401
-                       * Apache
-                         logs in a user without a store, by checking apache's authentication data
-                       * Net (chansen)
-                         all of these are Password subclasses
-                               * FTP
-                               * SMTP
-                               * POP3 
-                       * Secure ID
-                       * SSH (chansen)
-               * Store/Credential hybrid
-                       * LDAP
-                         storage dependent... querying the database is tied with credential checking
-                               - roles (memberOf)
-                               - ... (attributes)
-                       * RADIUS (chansen)
-                       * PAM (chansen)
-                       * Service
-                               * OpenID (chansen)
-                               * Passport (hah!)
-                               * TypeKey
-                               * Sxip
-                       * SAML
-                       * LID
-                       * SMB (chansen)
-                       * Kerberos (chansen)
-                       * SASL (Authen::SASL)
-       * Authorization (plugin)
-               * Roles
-                 checks a user's membership in roles
-                 uses has_roles( @roles ) if the user class has that method (assumed to be more efficient)
-                 uses roles and compares on it's own otherwise
-                       - check_user_roles( [ $user ], @roles )
-                         returns boolean, whether $c->user (or supplied user) has specified roles
-                       - assert_user_roles( [ $user ] @roles )
-                         throws an exception if $c->user (or supplied user) doesn't have the specified roles
-               * ACL
-                 allows to add ACL rules to sections of the catalyst app
-                 ACLs apply to perl namespace (MyApp::C::Foo "contains" MyApp::C::Foo::Bar, etc)
-                 or they can apply to URL space (/foo contains /bar)
-                 implies $c->user
-                 takes a value to $c->forward to in case the user isn't authorized (error page)
-                       - restrict_access ( $arg_like_forward_takes, @roles ) # roles to allow
-                       - deny_access ( $arg_like_forward_takes, @roles ) # roles to disallow
-               * SAML
-       * Login Form (plugin)
-         this is the plugin that will be used for CRAM stuff in javascript
-         http://pajhome.org.uk/crypt/ - bsd license hashes in js
-         http://pajhome.org.uk/crypt/md5/chaplogin.html
-         http://perl-md5-login.sourceforge.net/
-         it's just for convenience
-               - login_form( [ $store ] )
-                 uses user_supports and isa checks on credentials to create a form
-                 that makes sense for the store provided if no store is provided uses
-                 $c->config->{authenticion}{store}
-               - process_login
-                 using the same info about stores/credentials, will pick up the data
-                 used to generate a form, and find out what form data to use to login
-               - prepare
-                 if $c->config->{authentication}{auto_login} is on will call process_login automatically
-