| File: | lib/Yukki/Model/User.pm |
| Coverage: | 57.3% |
| line | stmt | bran | cond | sub | pod | time | code |
|---|---|---|---|---|---|---|---|
| 1 | package Yukki::Model::User; | ||||||
| 2 | |||||||
| 3 | 2 2 | 971 7 | use v5.24; | ||||
| 4 | 2 2 2 | 5 3 10 | use utf8; | ||||
| 5 | 2 2 2 | 23 4 7 | use Moo; | ||||
| 6 | |||||||
| 7 | extends 'Yukki::Model'; | ||||||
| 8 | |||||||
| 9 | 2 2 2 | 455 2 15 | use Yukki::Types qw( LoginName ); | ||||
| 10 | 2 2 2 | 773 2 11 | use Yukki::TextUtil qw( load_file ); | ||||
| 11 | |||||||
| 12 | 2 2 2 | 470 3 10 | use Type::Params qw( validate ); | ||||
| 13 | 2 2 2 | 316 3 9 | use Type::Utils; | ||||
| 14 | 2 2 2 | 1955 4 14 | use Types::Path::Tiny; | ||||
| 15 | 2 2 2 | 384 3 12 | use Types::Standard qw( slurpy Dict ); | ||||
| 16 | |||||||
| 17 | 2 2 2 | 1234 4 24 | use Yukki::User; | ||||
| 18 | |||||||
| 19 | 2 2 2 | 15 3 13 | use namespace::clean; | ||||
| 20 | |||||||
| 21 | # ABSTRACT: lookup users | ||||||
| 22 | |||||||
| 23 - 46 | =head1 SYNOPSIS
my $users = $app->model('User');
my $user = $users->find('bob');
my $login_name = $user->login_name;
my $password = $user->password;
my $name = $user->name;
my $email = $user->email;
my @groups = $user->groups->@*;
=head1 DESCRIPTION
Read access to the current list of authorized users.
=head1 METHODS
=head2 set_password
$users->set_password($user, $cleartext);
Given a password in cleartext, this will hash the password using the application's hasher. The second argument containing the cleartext password is optional. When omitted, the value returned by the C<password> accessor of the C<$user> object will be used instead.
=cut | ||||||
| 47 | |||||||
| 48 | sub set_password { | ||||||
| 49 | 0 | 1 | 0 | my ($self, $user, $clear_password) = @_; | |||
| 50 | 0 | 0 | $clear_password //= $user->password; | ||||
| 51 | |||||||
| 52 | 0 | 0 | my $digest = $self->app->hasher; | ||||
| 53 | 0 | 0 | $digest->add($clear_password); | ||||
| 54 | 0 | 0 | $user->password($digest->generate); | ||||
| 55 | |||||||
| 56 | 0 | 0 | return; | ||||
| 57 | } | ||||||
| 58 | |||||||
| 59 - 65 | =head2 save $users->save($user, create_only => 1); Writes a L<Yukki::User> object to the users database. If the C<create_only> flag is set, the method will fail with an exception when the user already exists. =cut | ||||||
| 66 | |||||||
| 67 | sub save { | ||||||
| 68 | 0 | 1 | 0 | my ($self, $user, %opt) = @_; | |||
| 69 | |||||||
| 70 | 0 | 0 | my $user_file = $self->locate('user_path', $user->login_name); | ||||
| 71 | |||||||
| 72 | 0 | 0 | if ($opt{create_only} && $user_file->exists) { | ||||
| 73 | 0 | 0 | die "User ", $user->login_name, " already exists."; | ||||
| 74 | } | ||||||
| 75 | |||||||
| 76 | 0 | 0 | $user_file->parent->mkpath; | ||||
| 77 | 0 | 0 | $user_file->chmod(0600) if $user_file->exists; | ||||
| 78 | 0 | 0 | $user_file->spew_utf8($user->dump_yaml); | ||||
| 79 | 0 | 0 | $user_file->chmod(0400); | ||||
| 80 | |||||||
| 81 | 0 | 0 | return; | ||||
| 82 | } | ||||||
| 83 | |||||||
| 84 - 90 | =head2 delete $users->delete($user); Given a L<Yukki::User>, this method deletes the user file for that object. =cut | ||||||
| 91 | |||||||
| 92 | sub delete { | ||||||
| 93 | 0 | 1 | 0 | my ($self, $user) = @_; | |||
| 94 | |||||||
| 95 | 0 | 0 | my $user_file = $self->locate('user_path', $user->login_name); | ||||
| 96 | 0 | 0 | $user_file->remove if $user_file->is_file; | ||||
| 97 | |||||||
| 98 | 0 | 0 | return; | ||||
| 99 | } | ||||||
| 100 | |||||||
| 101 - 107 | =head2 find my $user = $users->find(login_name => $login_name); Returns a hash containing the information related to a specific user named by login name. =cut | ||||||
| 108 | |||||||
| 109 | sub find { | ||||||
| 110 | 1 | 1 | 2219 | my ($self, $opt) | |||
| 111 | = validate(\@_, class_type(__PACKAGE__), | ||||||
| 112 | slurpy Dict[ | ||||||
| 113 | login_name => LoginName | ||||||
| 114 | ], | ||||||
| 115 | ); | ||||||
| 116 | 1 | 13 | my $login_name = $opt->{login_name}; | ||||
| 117 | |||||||
| 118 | 1 | 68 | my $user_file = $self->locate('user_path', $login_name); | ||||
| 119 | 1 | 4 | if ($user_file->exists) { | ||||
| 120 | 1 | 28 | return Yukki::User->load_yaml($user_file->slurp_utf8); | ||||
| 121 | } | ||||||
| 122 | |||||||
| 123 | 0 | return; | |||||
| 124 | } | ||||||
| 125 | |||||||
| 126 - 132 | =head2 list my @names = $users->list; Returns a list of login names for all users configured. =cut | ||||||
| 133 | |||||||
| 134 | sub list { | ||||||
| 135 | 0 | 1 | my $self = shift; | ||||
| 136 | |||||||
| 137 | 0 | my $user_dir = $self->locate('user_path'); | |||||
| 138 | 0 0 | return map { $_->basename } $user_dir->children; | |||||
| 139 | } | ||||||
| 140 | |||||||
| 141 | 1; | ||||||