* Moving 'type' to the front of the list of things returned by the User data source's 'getField*' methods so that they map more directly to the user field constructor arguments

* Moving 'typeData' around in the order of the user field constructor arguments to match the User data source's 'getField*' methods so that, again, they map more directly
* Renaming the 'getFieldFrom*' methods to 'getFieldBy*' to be consistent with 'getUserBy*'
* Implemented UserFieldFactory.pm
* Implemented Passwords.pm
This commit is contained in:
ian%hixie.ch 2001-05-28 23:43:56 +00:00
Родитель 45a5bcd3fa
Коммит ad978537ad
4 изменённых файлов: 76 добавлений и 11 удалений

Просмотреть файл

@ -105,21 +105,21 @@ sub getFields {
my $self = shift;
my($app) = @_;
$self->notImplemented();
# return [fieldID, category, name, type, data]*
# return [type, fieldID, category, name, typeData]*
}
sub getFieldFromID {
sub getFieldByID {
my $self = shift;
my($app, $fieldID) = @_;
$self->notImplemented();
# return [fieldID, category, name, type, data]
# return [type, fieldID, category, name, typeData]
}
sub getFieldFromCategoryAndName {
sub getFieldByName {
my $self = shift;
my($app, $category, $name) = @_;
$self->notImplemented();
# return [fieldID, category, name, type, data]
# return [type, fieldID, category, name, typeData]
}
sub setField {

Просмотреть файл

@ -39,9 +39,17 @@ sub provides {
return ($service eq 'service.passwords' or $class->SUPER::provides($service));
}
# sanity checking: |$self->checkPassword($self->newPassword())| should
# return a true value if everything is behaving itself
sub newPassword {
my $self = shift;
return (undef, undef); # opaque key (encrypted password), actual password for one-time sending to user
# Returns first an opaque key (the one-way encrypted version of
# the generated password) and second the actual plain-text
# password for a one-time sending to the user.
my $password = $self->generatePassword();
my $crypt = $self->crypt($password);
return ($crypt, password);
}
sub checkPassword {
@ -49,5 +57,54 @@ sub checkPassword {
my($key, $userData) = @_;
# $key is the first value returned from newPassword,
# $userData is the password given by the user.
return 0;
return ($key eq $self->crypt($userData, $key));
}
# internal routines
sub crypt {
my $self = shift;
my($string, $salt) = @_;
if (not defined($salt)) {
$salt = $self->generateSalt();
}
return crypt($string, $salt);
}
sub generatePassword {
# Generates a pseudo-random password that is not predictable, but
# which is memorable. XXX this should be more secure... :-)
my(@adjectives) = ('adorable', 'amazing', 'amusing', 'artistic',
'azure', 'bouncy', 'cheeky', 'cheerful', 'cheery', 'cuddly',
'cute', 'dynamic', 'excited', 'exciting', 'female', 'flash',
'fluffy', 'funny', 'giant', 'good', 'great', 'happy', 'joyful',
'lovely', 'majestic', 'mauve', 'mellow', 'meowing', 'miaowing',
'poetic', 'puffing', 'purring', 'purry', 'relaxed', 'silver',
'sleepy', 'soft', 'special', 'spicy', 'squeaky', 'sweet',
'pink', 'yellow', ); # XXX more (pleasant) suggestions welcome...
my(@nouns) = ('angel', 'bee', 'book', 'bunny', 'cat', 'color',
'colour', 'comedian', 'computer', 'cube', 'date', 'dawn', 'duck',
'ferret', 'fig', 'flower', 'forest', 'fox', 'frog', 'fun', 'girl',
'grass', 'heaven', 'humor', 'humour', 'island', 'jester', 'joy',
'kitten', 'life', 'love', 'ludwig', 'mowmow', 'mouse', 'music',
'party', 'pencil', 'pleasure', 'poem', 'puffin', 'rainbow',
'raindrop', 'science', 'sphere', 'star', 'student', 'summer',
'sunshine', 'tautology', 'teddy', 'time', 'tree', 'voice', );
my $adjective = $adjectives[int(rand($#adjectives))];
my $noun = $nouns[int(rand($#nouns))];
return "$adjective $noun";
}
sub generateSalt {
my $self = shift;
my @salts = ('0'..'9', 'a'..'z', 'A'..'Z', '.', '/');
my $salt = '';
foreach (1..2) {
$salt .= $salts[int(rand($#salts))];
}
return $salt;
}

Просмотреть файл

@ -49,14 +49,14 @@ sub provides {
sub init {
my $self = shift;
my($app, $user, $fieldID, $fieldTypeData, $fieldCategory, $fieldName, $fieldData) = @_;
my($app, $user, $fieldID, $fieldCategory, $fieldName, $fieldTypeData, $fieldData) = @_;
# do not hold on to $user!
$self->app($app);
$self->userID($user->userID); # change this at your peril
$self->fieldID($fieldID); # change this at your peril
$self->typeData($fieldTypeData); # change this at your peril
$self->category($fieldCategory); # change this at your peril
$self->name($fieldName); # change this at your peril
$self->typeData($fieldTypeData); # change this at your peril
$self->data($fieldData); # this is the only thing you should be changing
# don't forget to update the user's 'hash' function if you add more fields
$self->{'_DELETE'} = 0;

Просмотреть файл

@ -52,7 +52,11 @@ sub provides {
sub createFieldByID {
my $self = shift;
my($app, $user, $fieldID, $fieldData) = @_;
return undef; # XXX
my($type, @data) = $app->getService('dataSource.user')->getFieldByID($app, $fieldID);
$app->assert(defined($type), 1, "Database contains a user with a field ID '$fieldID' but that field ID is not defined");
my $field = $app->getServiceInstance("user.field.$type", $user, @data, $fieldData);
$app->assert(defined($field), 1, "Database contains a field of type '$type' but there is no service providing that type");
return $field;
}
# typically used when the field is being created
@ -61,5 +65,9 @@ sub createFieldByName {
my($app, $user, $fieldCategory, $fieldName, $fieldData) = @_;
# fieldData is likely to be undefined, as the field is unlikely to
# exist for this user.
return undef; # XXX
my($type, @data) = $app->getService('dataSource.user')->getFieldByName($app, $fieldCategory, $fieldName);
$app->assert(defined($type), 1, "Database contains a user with a field name '$fieldCategory.$fieldName' but that field is not defined");
my $field = $app->getServiceInstance("user.field.$type", $user, @data, $fieldData);
$app->assert(defined($field), 1, "Database contains a field of type '$type' but there is no service providing that type");
return $field;
}