line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Myco::Core::User; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
############################################################################## |
4
|
|
|
|
|
|
|
# $Id: User.pm,v 1.1.1.1 2006/03/01 21:00:55 sommerb Exp $ |
5
|
|
|
|
|
|
|
# |
6
|
|
|
|
|
|
|
# See license and copyright near the end of this file. |
7
|
|
|
|
|
|
|
############################################################################## |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
=pod |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=head1 NAME |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
Myco::Core::User - Interface to Myco User Objects |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=head1 VERSION |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
1.0 |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
=cut |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
our $VERSION = 1.0; |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=pod |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
=head1 SYNOPSIS |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
use Myco::Core::User; |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
# Constructors. |
30
|
|
|
|
|
|
|
my $user = Myco::Core::User->new; |
31
|
|
|
|
|
|
|
# See Myco::Entity for more. |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
# Class Methods. |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
# Instance Methods. |
36
|
|
|
|
|
|
|
my $person = $user->get_person; |
37
|
|
|
|
|
|
|
$user->set_person($person); |
38
|
|
|
|
|
|
|
my $login = $user->login; |
39
|
|
|
|
|
|
|
$login->set_login($login); |
40
|
|
|
|
|
|
|
$user->set_pass($pass); |
41
|
|
|
|
|
|
|
if ($user->chk_pass($pass)) { |
42
|
|
|
|
|
|
|
# Allow access. |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
$user->save; |
46
|
|
|
|
|
|
|
$user->destroy; |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
=head1 DESCRIPTION |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
This Class provides the basic interface to all Myco user objects. It offers |
51
|
|
|
|
|
|
|
the ability to set and get the login name, and to set and check the password. |
52
|
|
|
|
|
|
|
The password is double-MD5 hash encrypted for security. |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
=cut |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
############################################################################## |
57
|
|
|
|
|
|
|
# Dependencies |
58
|
|
|
|
|
|
|
############################################################################## |
59
|
|
|
|
|
|
|
# Module Dependencies and Compiler Pragma |
60
|
1
|
|
|
1
|
|
11896
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
47
|
|
61
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
34
|
|
62
|
1
|
|
|
1
|
|
2508
|
use Myco::Exceptions; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
############################################################################## |
65
|
|
|
|
|
|
|
# Programmatic Dependences |
66
|
|
|
|
|
|
|
use Myco; |
67
|
|
|
|
|
|
|
use Digest::MD5 (); |
68
|
|
|
|
|
|
|
use Myco::Core::Person; |
69
|
|
|
|
|
|
|
use Tangram::FlatHash; |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
############################################################################## |
72
|
|
|
|
|
|
|
# Constants |
73
|
|
|
|
|
|
|
############################################################################## |
74
|
|
|
|
|
|
|
use constant DEBUG => 0; |
75
|
|
|
|
|
|
|
use constant SECRET => 'YOUR SECRET HERE'; |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
############################################################################## |
78
|
|
|
|
|
|
|
# Class Variables |
79
|
|
|
|
|
|
|
############################################################################## |
80
|
|
|
|
|
|
|
my $_errors = {}; |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
############################################################################## |
83
|
|
|
|
|
|
|
# Inheritance & Introspection |
84
|
|
|
|
|
|
|
############################################################################## |
85
|
|
|
|
|
|
|
use base qw(Myco::Entity Myco::Association); |
86
|
|
|
|
|
|
|
my $md = Myco::Entity::Meta->new |
87
|
|
|
|
|
|
|
( name => __PACKAGE__, |
88
|
|
|
|
|
|
|
access_list => { rw => [qw(admin)] }, |
89
|
|
|
|
|
|
|
tangram => { table => 'myco_user', # watch those SQL reserved words! |
90
|
|
|
|
|
|
|
bases => [qw(Myco::Association)] }, |
91
|
|
|
|
|
|
|
ui => { displayname => sub { shift->get_displayname }, |
92
|
|
|
|
|
|
|
list => { layout => [qw(login)] }, |
93
|
|
|
|
|
|
|
view => { layout => [qw(login)] }, }, |
94
|
|
|
|
|
|
|
); |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
############################################################################## |
97
|
|
|
|
|
|
|
# Function and Closure Prototypes |
98
|
|
|
|
|
|
|
############################################################################# |
99
|
|
|
|
|
|
|
## Use this closure to check that a reference is to a Myco::Core::Person object. |
100
|
|
|
|
|
|
|
my $chk_person = sub { |
101
|
|
|
|
|
|
|
Myco::Exception::DataValidation->throw |
102
|
|
|
|
|
|
|
(error => "'${$_[0]}' is not a Myco::Core::Person object") |
103
|
|
|
|
|
|
|
unless UNIVERSAL::isa(${$_[0]}, 'Myco::Core::Person') |
104
|
|
|
|
|
|
|
}; |
105
|
|
|
|
|
|
|
# Use this closure to check that login is at least 4 letters or digits |
106
|
|
|
|
|
|
|
my $chk_login = sub { |
107
|
|
|
|
|
|
|
my $login = $ {$_[0]}; |
108
|
|
|
|
|
|
|
Myco::Exception::DataValidation->throw |
109
|
|
|
|
|
|
|
(error => 'Login must be 4 or more characters') |
110
|
|
|
|
|
|
|
if $login !~ /([A-Za-z]|\d){4,}/; |
111
|
|
|
|
|
|
|
}; |
112
|
|
|
|
|
|
|
# Use this closure to check that pass is at least 6 letters or digits |
113
|
|
|
|
|
|
|
my $chk_pass = sub { |
114
|
|
|
|
|
|
|
my $pass = $ {$_[0]}; |
115
|
|
|
|
|
|
|
Myco::Exception::DataValidation->throw |
116
|
|
|
|
|
|
|
(error => 'Login must be 6 or more characters') |
117
|
|
|
|
|
|
|
if $pass !~ /([A-Za-z]|\d){6,}/; |
118
|
|
|
|
|
|
|
}; |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
############################################################################## |
121
|
|
|
|
|
|
|
# Queries |
122
|
|
|
|
|
|
|
############################################################################## |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
=head1 QUERIES |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
Myco::Query::Meta::Query objects defining generic and reusable queries for |
127
|
|
|
|
|
|
|
finding Myco::Core::User objects. |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
=head2 default query |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
my $metadata = Myco::Core::User->introspect->get_queries; |
132
|
|
|
|
|
|
|
my $default_query = $metadata->{default}; |
133
|
|
|
|
|
|
|
my @results = $default_query->run_query(login => 'doej'); |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
Find a user object with a given unique login attribute. |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
=head2 by_person query |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
my $metadata = Myco::Core::User->introspect->get_queries; |
140
|
|
|
|
|
|
|
my $default_query = $metadata->{by_person}; |
141
|
|
|
|
|
|
|
my @results = $default_query->run_query(person => $p); |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
Find a user object with a person attribute set to a given Myco::Core::Person |
144
|
|
|
|
|
|
|
object, $p. |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
=cut |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
my $queries = sub { |
149
|
|
|
|
|
|
|
my $md = $_[0]; # Metadata object |
150
|
|
|
|
|
|
|
$md->add_query( name => 'default', |
151
|
|
|
|
|
|
|
remotes => { '$u_' => 'Myco::Core::User', }, |
152
|
|
|
|
|
|
|
result_remote => '$u_', |
153
|
|
|
|
|
|
|
params => { |
154
|
|
|
|
|
|
|
login => [ qw($u_ login) ], |
155
|
|
|
|
|
|
|
}, |
156
|
|
|
|
|
|
|
filter => { parts => [ { remote => '$u_', |
157
|
|
|
|
|
|
|
attr => 'login', |
158
|
|
|
|
|
|
|
oper => 'eq', |
159
|
|
|
|
|
|
|
param => 'login', }, |
160
|
|
|
|
|
|
|
] }, |
161
|
|
|
|
|
|
|
); |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
$md->add_query( name => 'by_person', |
164
|
|
|
|
|
|
|
remotes => { '$u_' => 'Myco::Core::User', }, |
165
|
|
|
|
|
|
|
result_remote => '$u_', |
166
|
|
|
|
|
|
|
params => { |
167
|
|
|
|
|
|
|
person => [ qw($u_ person) ], |
168
|
|
|
|
|
|
|
}, |
169
|
|
|
|
|
|
|
filter => { parts => [ |
170
|
|
|
|
|
|
|
{ remote => '$u_', |
171
|
|
|
|
|
|
|
attr => 'person', |
172
|
|
|
|
|
|
|
oper => '==', |
173
|
|
|
|
|
|
|
param => 'person' }, |
174
|
|
|
|
|
|
|
] }, |
175
|
|
|
|
|
|
|
); |
176
|
|
|
|
|
|
|
}; |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
############################################################################## |
179
|
|
|
|
|
|
|
# Constructor, etc. |
180
|
|
|
|
|
|
|
############################################################################## |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
=head1 COMMON ENTITY INTERFACE |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
Constructor, accessors, and other methods -- as inherited from Myco::Entity. |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
=cut |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
############################################################################## |
189
|
|
|
|
|
|
|
# Attributes & Attribute Accessors / Schema Definition |
190
|
|
|
|
|
|
|
############################################################################## |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
=head1 ATTRIBUTES |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
Attributes may be initially set during object construction (with C) but |
195
|
|
|
|
|
|
|
otherwise are accessed solely through accessor methods. Typical usage: |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
=over 2 |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
=item * Set attribute value |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
$user->set_attribute($value); |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
Check functions (see L) perform data |
204
|
|
|
|
|
|
|
validation. If there is any concern that the set method might be called with |
205
|
|
|
|
|
|
|
invalid data then the call should be wrapped in an C block to catch |
206
|
|
|
|
|
|
|
exceptions that would result. |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
=item * Get attribute value |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
$value = $user->get_attribute; |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
=back |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
Available attributes are listed below, using syntax borrowed from UML class |
215
|
|
|
|
|
|
|
diagrams; for each showing the name, type, default initial value (if any), |
216
|
|
|
|
|
|
|
and, following that, a description. |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
=over 4 |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
=cut |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
############################################################################## |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
=item -person: ref(Myco::Core::Person) = Myco::Core::Person |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
The person object to which this user belongs. Access this object to output |
227
|
|
|
|
|
|
|
name information about a user. |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
=cut |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
$md->add_attribute(name => 'person', |
232
|
|
|
|
|
|
|
type => 'ref', |
233
|
|
|
|
|
|
|
# access_list => { rw => [qw(admin)] }, |
234
|
|
|
|
|
|
|
synopsis => 'Person', |
235
|
|
|
|
|
|
|
tangram_options => { check_func => $chk_person, |
236
|
|
|
|
|
|
|
required => 1, |
237
|
|
|
|
|
|
|
class => 'Myco::Core::Person' }, |
238
|
|
|
|
|
|
|
); |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
############################################################################## |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
=item -login: string(128) = undef |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
The userE<39>s login name. |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
=cut |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
$md->add_attribute( name => 'login', |
250
|
|
|
|
|
|
|
type => 'string', |
251
|
|
|
|
|
|
|
# access_list => { rw => [qw(admin)] }, |
252
|
|
|
|
|
|
|
synopsis => 'Login Name', |
253
|
|
|
|
|
|
|
ui => { label => 'Login Name' }, |
254
|
|
|
|
|
|
|
); |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
############################################################################## |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
=item -pass: string(32) = undef |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
The userE<39>s login password. Internally, it will be encrypted in a double-MD5 |
261
|
|
|
|
|
|
|
hash before being stored in the system. |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
=cut |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
$md->add_attribute( name => 'pass', |
266
|
|
|
|
|
|
|
type => 'string', |
267
|
|
|
|
|
|
|
# access_list => { rw => [qw(admin)] }, |
268
|
|
|
|
|
|
|
synopsis => 'Password', |
269
|
|
|
|
|
|
|
ui => { label => 'Password', |
270
|
|
|
|
|
|
|
widget => [ 'password_field' ], }, |
271
|
|
|
|
|
|
|
); |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
# These are designed to prevent direct access to the password. |
274
|
|
|
|
|
|
|
|
275
|
|
|
|
|
|
|
sub get_pass { |
276
|
|
|
|
|
|
|
Myco::Exception::MNI->throw |
277
|
|
|
|
|
|
|
(error => 'unknown method/attribute '.__PACKAGE__.'->get_pass called'); |
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
sub pass { |
280
|
|
|
|
|
|
|
Myco::Exception::MNI->throw |
281
|
|
|
|
|
|
|
(error => 'unknown method/attribute '.__PACKAGE__.'->pass called'); |
282
|
|
|
|
|
|
|
} |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
sub set_pass { |
285
|
|
|
|
|
|
|
my ($self, $pass) = @_; |
286
|
|
|
|
|
|
|
$self->SUPER::set_pass( |
287
|
|
|
|
|
|
|
Digest::MD5::md5_hex(SECRET . Digest::MD5::md5_hex($pass))); |
288
|
|
|
|
|
|
|
Myco::Exception::DataValidation->throw |
289
|
|
|
|
|
|
|
(error => 'Password must be at least 6 characters') |
290
|
|
|
|
|
|
|
if ($pass && length $pass < 6); |
291
|
|
|
|
|
|
|
} |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
=item -roles: hash (string(64} => int) = {} |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
The userE<39>s roles. These are stored in a hash, where the keys are the role |
296
|
|
|
|
|
|
|
names and the values are an integer, usually "1". Mostly, you shouldnE<39>t |
297
|
|
|
|
|
|
|
use the hash to get at the roles, though. See below for the methods specific |
298
|
|
|
|
|
|
|
to Role access. |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
=cut |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
$md->add_attribute( name => 'roles', |
303
|
|
|
|
|
|
|
type => 'flat_hash', |
304
|
|
|
|
|
|
|
# access_list => { rw => [qw(admin)] }, |
305
|
|
|
|
|
|
|
synopsis => 'Roles', |
306
|
|
|
|
|
|
|
tangram_options => { table => 'user_roles', |
307
|
|
|
|
|
|
|
key_type => 'string', |
308
|
|
|
|
|
|
|
key_sql => 'VARCHAR(64) NOT NULL', |
309
|
|
|
|
|
|
|
type => 'int', |
310
|
|
|
|
|
|
|
sql => 'INT NOT NULL DEFAULT 1', }, |
311
|
|
|
|
|
|
|
); |
312
|
|
|
|
|
|
|
# This is designed to prevent direct access to roles |
313
|
|
|
|
|
|
|
sub roles { |
314
|
|
|
|
|
|
|
Myco::Exception::MNI->throw |
315
|
|
|
|
|
|
|
(error => 'unknown method/attribute '.__PACKAGE__.'->roles called'); |
316
|
|
|
|
|
|
|
} |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
=back |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
############################################################################## |
321
|
|
|
|
|
|
|
# Methods |
322
|
|
|
|
|
|
|
############################################################################## |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
=head1 ADDED CLASS / INSTANCE METHODS |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
=cut |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
=head2 chk_pass |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
if ($user->chk_pass($pass)) { |
331
|
|
|
|
|
|
|
# Allow access. |
332
|
|
|
|
|
|
|
} |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
Checks the userE<39>s pass word or phrase. Returns true if the pass word or |
335
|
|
|
|
|
|
|
phrase is correct, and false if it is not. |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
=cut |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
sub chk_pass { |
340
|
|
|
|
|
|
|
my ($self, $pass) = @_; |
341
|
|
|
|
|
|
|
# Use Class::Tangram::get() to get the password, because there won't yet |
342
|
|
|
|
|
|
|
# be a user when it's getting checked! |
343
|
|
|
|
|
|
|
my $oldpass = $self->SUPER::get_pass || return; |
344
|
|
|
|
|
|
|
return Digest::MD5::md5_hex(SECRET . Digest::MD5::md5_hex($pass)) eq |
345
|
|
|
|
|
|
|
$oldpass ? 1 : 0; |
346
|
|
|
|
|
|
|
} |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
############################################################################## |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
=head2 get_roles |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
my @roles = $user->get_roles; |
353
|
|
|
|
|
|
|
my $roles_aref = $user->get_roles; |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
Returns a list (in an array context) or an anonymous array (in a scalar |
356
|
|
|
|
|
|
|
context) of all the roles assigned to the user. |
357
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
=cut |
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
sub get_roles { |
361
|
|
|
|
|
|
|
if ($_[0]->SUPER::get_roles) { |
362
|
|
|
|
|
|
|
wantarray ? |
363
|
|
|
|
|
|
|
sort keys %{ $_[0]->SUPER::get_roles } : |
364
|
|
|
|
|
|
|
[ sort keys %{ $_[0]->SUPER::get_roles } ]; |
365
|
|
|
|
|
|
|
} |
366
|
|
|
|
|
|
|
} |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
############################################################################## |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
=head2 add_roles |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
$user->add_roles(@roles); |
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
Adds the listed roles to the user. If any role in @roles does not actually |
375
|
|
|
|
|
|
|
exist as a role, then C will throw an exception. |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
=cut |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
sub add_roles { |
380
|
|
|
|
|
|
|
my $self = shift; |
381
|
|
|
|
|
|
|
my $roles = $self->SUPER::get_roles; |
382
|
|
|
|
|
|
|
$self->SUPER::set_roles($roles = {}) unless $roles; |
383
|
|
|
|
|
|
|
} |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
############################################################################## |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
=head2 del_roles |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
$user->del_roles(@roles); |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
Deletes the listed roles from the user. |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
=cut |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
sub del_roles { |
396
|
|
|
|
|
|
|
my $self = shift; |
397
|
|
|
|
|
|
|
my $roles = $self->SUPER::get_roles; |
398
|
|
|
|
|
|
|
delete @{$roles}{@_}; |
399
|
|
|
|
|
|
|
} |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
############################################################################## |
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
=head2 get_roles_hash |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
$user->get_roles_hash; |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
Returns an anonymous hash of all of the roles assigned to the user. The hash |
408
|
|
|
|
|
|
|
keys are the role names, and the values are a simple integer (usually one). |
409
|
|
|
|
|
|
|
This is the internal representation of the roles in the User object, and |
410
|
|
|
|
|
|
|
normally this method will only be used internally. |
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
=cut |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
# This absolutely must use the Class::Tangram::get() method. To do otherwise |
415
|
|
|
|
|
|
|
# will likely cause a problem with deep recursion in Myco::Entity. |
416
|
|
|
|
|
|
|
# That's why it's best that this method only be used internally -- no one else |
417
|
|
|
|
|
|
|
# should have permission to use it, really, anyway (except in chk_pass(), |
418
|
|
|
|
|
|
|
# above). |
419
|
|
|
|
|
|
|
sub get_roles_hash { $_[0]->SUPER::get_roles } |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
############################################################################## |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
=head2 get_displayname |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
$user->get_displayname; |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
Returns the displayname of the person (first and last name) associated with a user. |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
=cut |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
sub get_displayname { |
433
|
|
|
|
|
|
|
my $self = shift; |
434
|
|
|
|
|
|
|
return $self->get_person->displayname; |
435
|
|
|
|
|
|
|
} |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
############################################################################## |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
=head2 find_user |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
my $u = Myco::Core::User->find_user($person); |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
Finds a user, given a Myco::Core::Person. This is a simple wrapper around the |
444
|
|
|
|
|
|
|
'by_person' query contained in the Myco::Core::User query. |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
=cut |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
sub find_user { |
449
|
|
|
|
|
|
|
my $self = shift; |
450
|
|
|
|
|
|
|
my $p = shift; |
451
|
|
|
|
|
|
|
my ($u) = __PACKAGE__->introspect->get_queries->{by_person}->run |
452
|
|
|
|
|
|
|
(person => $p); |
453
|
|
|
|
|
|
|
return $u; |
454
|
|
|
|
|
|
|
} |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
############################################################################## |
458
|
|
|
|
|
|
|
# Throw a fatal Exception if $_errors is not empty |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
############################################################################## |
462
|
|
|
|
|
|
|
# Object Schema Activation and Metadata Finalization |
463
|
|
|
|
|
|
|
############################################################################## |
464
|
|
|
|
|
|
|
$md->activate_class( queries => $queries ); |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
1; |
467
|
|
|
|
|
|
|
__END__ |