| 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__ |