* Plugins and actions need to work better
* Plugins should be able to create model classes
* So should applications
* Plugins can add columns to model classes
* Plugins can add logic to model classes (before_*, after_* hooks)
* Plugins should be able to add properties to columns
* The app always overrides plugins
* Plugins are loaded and evaluated in order
* Models should become mixins when appropriate
- But if the app doesn't define one, they can create classes/tables #'
The plugins we want in our ponyverse:
* ::Users
* ::Users::Identity::EmailedToken
* ::UsernamePassword
* ::OpenID
* ::Certs
* ::{Assertion,Kerberos,...}
* ::ResetIdentity (change password for any identity once logged in / add identity)
* ::Users::Signup
* ::Users::Login
* ::Users::EmailAddress
::Users
* unique ID
* created_date, update_date, created_by, updated_by
* display_name field (which you can force to something -- e.g. email, openid, name from cert)
* (Jifty::Record _brief_description returns this?)
* last_login (?)
* Do superuser and nobody live in the database? (That's authz)
Where do identity plugins hook?
* Add columns
* Get credentials, return:
* These are valid
* These are invalid
* Other auth error ``I don't know''
* bounce trips go through continuations
* load_by_unique_id
* ::Login
* /login =>
* list of identity types
* for each, fields for login columns declared by the ::Identity::Foo plugin
* submit button
* Login action
* load_by_unique_id
* if the user doesn't exist, callback (to signup) or error
* Passes credentials to the identity plugin's auth method
* Identities that need confirmation error here if needed
* frob the session as appropriate
* frob CurrentUser
* Adds Dispatcher variables
* Logout action
* frob the session and current user
* dispatcher rule on /logout redirects
* ::Signup
* Signup action
* verifies credentials - validates fields (inc. uniqueness)
* Creates a record
* Add a message, and push the user to the login page with a filled-out login action
* What do ``mixins'' *mean*?
* We want injection, not actual mixins
----- Where is this going to be hard? -----
* Mixing columns into users
* Getting the autogenerated actions to DTRT
* hooks look kinda like Plagger
* If there are multiple plugin models with no app model,
they all get mixed into the null model
----- Username/password plugin ------
# Model (Jifty::Plugin::User::Identity::UsernamePassword::Model::User)
column 'username' =>
type is 'text',
is unique;
column 'password' =>
type is 'text',
render_as 'Password',
filters are qw(Jifty::DBI::Filter::SaltHash);
sub password_is {
my $self = shift;
my $pass = shift;
return undef unless $self->_value('password');
my ($hash, $salt) = @{$self->_value('password')};
return 1 if ( $hash eq Digest::MD5::md5_hex($pass . $salt) );
return undef;
}
# ``exports''
sub load_by_unique_id {
my $self = shift;
my %args = (username => undef, @_);
return $self->load_by_columns(username => $args{username});
}
sub validate_credentials {
my $self = shift;
my %args = (username => undef, @_);
return unless $self->id;
return $self->password_is($args{password});
}
# Jifty::Plugin::User::Identity::UsernamePassword::Action::Login
param username =>
render_as 'Text';
param password =>
render_as 'Password';
# Login plugin Action::Login
sub check_credentials {
my $self = shift;
my $userobj = MyApp::Model::User->new;
my $user;
foreach my $identity_type ($userobj->identity_plugins) {
if($userobj->($identity_type . "::load_by_unique_id")($self->argument_values)) {
if($userobj->($identity_type . "::validate_credentials")($self->argument_values)) {
...
} else {
...
}
}
}
}