line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#!perl |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
package Schema::RDBMS::AUS::User; |
4
|
|
|
|
|
|
|
|
5
|
3
|
|
|
3
|
|
1998
|
use strict; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
100
|
|
6
|
3
|
|
|
3
|
|
15
|
use warnings; |
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
104
|
|
7
|
3
|
|
|
3
|
|
17
|
use Carp qw(croak); |
|
3
|
|
|
|
|
7
|
|
|
3
|
|
|
|
|
174
|
|
8
|
3
|
|
|
3
|
|
15
|
use DBIx::Transaction; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
107
|
|
9
|
3
|
|
|
3
|
|
506101
|
use URI; |
|
3
|
|
|
|
|
26182
|
|
|
3
|
|
|
|
|
127
|
|
10
|
3
|
|
|
3
|
|
2621
|
use URI::QueryParam; |
|
3
|
|
|
|
|
2555
|
|
|
3
|
|
|
|
|
89
|
|
11
|
3
|
|
|
3
|
|
18
|
use Schema::RDBMS::AUS; |
|
3
|
|
|
|
|
7
|
|
|
3
|
|
|
|
|
83
|
|
12
|
|
|
|
|
|
|
|
13
|
3
|
|
|
3
|
|
18
|
use vars qw(%ENV); |
|
3
|
|
|
|
|
7
|
|
|
3
|
|
|
|
|
15044
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
return 1; |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
# constructors |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
sub login { |
20
|
0
|
|
|
0
|
1
|
|
my($class, $user, $password, %login_info) = @_; |
21
|
0
|
|
|
|
|
|
%login_info = (%login_info, name => $user, password => $password); |
22
|
0
|
|
|
|
|
|
my $self; |
23
|
0
|
0
|
|
|
|
|
if($self = eval { $class->_login(%login_info) }) { |
|
0
|
|
|
|
|
|
|
24
|
0
|
|
0
|
0
|
|
|
my $txn = delete($login_info{_post_login}) || sub { return shift }; |
|
0
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
return $self->dbh->transaction(sub { |
26
|
0
|
|
|
0
|
|
|
$self->used; |
27
|
0
|
0
|
|
|
|
|
$self->log('login', %login_info) or return; |
28
|
0
|
|
|
|
|
|
$txn->($self); |
29
|
0
|
|
|
|
|
|
}); |
30
|
|
|
|
|
|
|
} else { |
31
|
0
|
|
|
|
|
|
my $err = $@; |
32
|
0
|
|
|
|
|
|
$self = $class->load(%login_info); # will die if user doesnt exist |
33
|
0
|
|
|
|
|
|
$login_info{error} = $err; |
34
|
0
|
|
|
|
|
|
$self->log('login_failure', %login_info); |
35
|
0
|
|
|
|
|
|
die $err; |
36
|
|
|
|
|
|
|
} |
37
|
|
|
|
|
|
|
} |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
sub _login { |
40
|
0
|
|
|
0
|
|
|
my($class, %login_info) = @_; |
41
|
|
|
|
|
|
|
|
42
|
0
|
0
|
|
|
|
|
if(my $self = $class->load(%login_info)) { |
43
|
0
|
0
|
|
|
|
|
die qq{Can not log in as group #$self->{id} "$login_info{name}"\n} |
44
|
|
|
|
|
|
|
if($self->{is_group}); |
45
|
|
|
|
|
|
|
|
46
|
0
|
0
|
|
|
|
|
die qq{Account #$self->{id} "$login_info{name}" is disabled.\n} |
47
|
|
|
|
|
|
|
if($self->flag('Disabled')); |
48
|
|
|
|
|
|
|
|
49
|
0
|
0
|
|
|
|
|
if($self->check_password($login_info{password})) { |
50
|
0
|
|
|
|
|
|
return $self; |
51
|
|
|
|
|
|
|
} else { |
52
|
0
|
|
|
|
|
|
die qq{Bad password for user #$self->{id} "$login_info{name}"\n}; |
53
|
|
|
|
|
|
|
} |
54
|
|
|
|
|
|
|
} else { |
55
|
0
|
|
|
|
|
|
die qq{No such user "$login_info{name}"\n}; |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
} |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
sub load { |
60
|
0
|
|
|
0
|
1
|
|
my $class = shift; |
61
|
0
|
|
|
|
|
|
return $class->_new(@_)->_LOAD_user; |
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
sub create { |
65
|
0
|
|
|
0
|
1
|
|
my($class, %args) = @_; |
66
|
0
|
|
|
|
|
|
my $self = $class->_new(%args); |
67
|
|
|
|
|
|
|
|
68
|
0
|
0
|
|
|
|
|
$self->{password_crypt} = $self->default_password_crypt |
69
|
|
|
|
|
|
|
unless $self->{password_crypt}; |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
return $self->dbh->transaction(sub { |
72
|
0
|
0
|
|
0
|
|
|
$self->_CREATE_user or die "Failed to create user.\n"; |
73
|
0
|
0
|
|
|
|
|
$self->log('create', %args) or die "Failed to log user creation.\n"; |
74
|
0
|
0
|
|
|
|
|
return $self unless defined $self->{_password}; |
75
|
|
|
|
|
|
|
|
76
|
0
|
|
|
|
|
|
$self->{password} = |
77
|
|
|
|
|
|
|
$self->crypt($self->password(delete $self->{_password})); |
78
|
|
|
|
|
|
|
|
79
|
0
|
|
|
|
|
|
$self->save; |
80
|
0
|
|
|
|
|
|
}); |
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
# methods |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
sub password { |
86
|
0
|
|
|
0
|
1
|
|
my($self, $password) = @_; |
87
|
0
|
0
|
|
|
|
|
if($self->{_validate_password}->($password)) { |
88
|
0
|
|
|
|
|
|
return $password; |
89
|
|
|
|
|
|
|
} else { |
90
|
0
|
|
|
|
|
|
die "Invalid password.\n"; |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
sub reset_password { |
95
|
0
|
|
|
0
|
1
|
|
my($self, $password) = splice(@_, 0, 2); |
96
|
0
|
0
|
|
|
|
|
if($self->password($password)) { |
97
|
0
|
|
|
|
|
|
return $self->_reset_password($password, @_); |
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
sub _reset_password { |
102
|
0
|
|
|
0
|
|
|
my($self, $password, $reason, %log_params) = @_; |
103
|
0
|
|
0
|
|
|
|
$reason ||= 'reset_password'; |
104
|
0
|
|
|
|
|
|
$self->{password} = $self->crypt($password); |
105
|
|
|
|
|
|
|
return $self->dbh->transaction(sub { |
106
|
0
|
0
|
|
0
|
|
|
$self->save && |
107
|
|
|
|
|
|
|
$self->log($reason, %log_params); |
108
|
0
|
|
|
|
|
|
}); |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
sub change_password { |
112
|
0
|
|
|
0
|
1
|
|
my($self, $old, $new, %log_params) = @_; |
113
|
0
|
0
|
|
|
|
|
if($self->_check_password($old)) { |
114
|
0
|
|
|
|
|
|
return $self->reset_password($new, 'change_password', %log_params); |
115
|
|
|
|
|
|
|
} else { |
116
|
0
|
|
|
|
|
|
die "Old password does not match.\n"; |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
sub save { |
121
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
122
|
|
|
|
|
|
|
return $self->dbh->transaction(sub { |
123
|
0
|
0
|
0
|
0
|
|
|
if($self->_UPDATE_user && $self->_save_flags) { |
124
|
0
|
|
|
|
|
|
return $self; |
125
|
|
|
|
|
|
|
} else { |
126
|
0
|
|
|
|
|
|
die "Failed to save user.\n"; |
127
|
|
|
|
|
|
|
} |
128
|
0
|
|
|
|
|
|
}); |
129
|
|
|
|
|
|
|
} |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
sub used { |
132
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
133
|
0
|
|
|
|
|
|
return $self->{time_used} = $self->_UPDATE_used; |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
sub log { |
137
|
0
|
|
|
0
|
1
|
|
my($self, $event, %args) = @_; |
138
|
0
|
|
|
|
|
|
delete @args{qw(password id _dbh)}; |
139
|
0
|
|
|
|
|
|
my $uri = URI->new; |
140
|
0
|
|
|
|
|
|
$uri->query_form_hash(\%args); |
141
|
0
|
|
|
|
|
|
my $data = $uri->query; |
142
|
0
|
|
|
|
|
|
return $self->_INSERT_user_log($event, $data); |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
sub crypt { |
146
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
147
|
0
|
|
|
|
|
|
return $self->{_crypt_class}->crypt(@_); |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
sub check_password { |
151
|
0
|
|
|
0
|
0
|
|
my($self, $password) = @_; |
152
|
0
|
0
|
0
|
|
|
|
return unless defined $self->{password} && length $self->{password} && |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
153
|
|
|
|
|
|
|
defined $password && length $password; |
154
|
0
|
|
|
|
|
|
return $self->_check_password($password); |
155
|
|
|
|
|
|
|
} |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
sub flag { |
158
|
0
|
|
|
0
|
1
|
|
my($self, $flag) = @_; |
159
|
0
|
|
|
|
|
|
return $self->{_flags}->{lc $flag}; |
160
|
|
|
|
|
|
|
} |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
sub permission { |
163
|
0
|
|
|
0
|
1
|
|
my($self, $perm) = @_; |
164
|
0
|
|
|
|
|
|
return $self->{_permissions}->{lc $perm}; |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
sub set_flag { |
168
|
0
|
|
|
0
|
1
|
|
my($self, $flag, $value, $create) = @_; |
169
|
0
|
0
|
|
|
|
|
if(!defined $value) { |
170
|
0
|
|
|
|
|
|
$value = 1; |
171
|
|
|
|
|
|
|
} else { |
172
|
0
|
|
0
|
|
|
|
$value = (!!$value) || 0; |
173
|
|
|
|
|
|
|
} |
174
|
0
|
0
|
|
|
|
|
$self->_SELECT_or_INSERT_flag($flag) if $create; |
175
|
0
|
|
|
|
|
|
return $self->{_flags}->{lc $flag} = $value; |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
sub clear_flag { |
179
|
0
|
|
|
0
|
1
|
|
my($self, $flag) = @_; |
180
|
0
|
|
|
|
|
|
delete $self->{_flags}->{lc $flag}; |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
sub add_to_group { |
184
|
0
|
|
|
0
|
1
|
|
my($self, $group) = @_; |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
return $self->dbh->transaction(sub { |
187
|
0
|
0
|
|
0
|
|
|
$group = ref($self)->load(name => $group, _dbh => $self->{_dbh}) |
188
|
|
|
|
|
|
|
unless ref $group; |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
return |
191
|
0
|
|
0
|
|
|
|
$self->_INSERT_membership($group->{id}) && |
192
|
|
|
|
|
|
|
$self->_refresh_permissions && |
193
|
|
|
|
|
|
|
$self->_refresh_membership; |
194
|
0
|
|
|
|
|
|
}); |
195
|
|
|
|
|
|
|
} |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
sub remove_from_group { |
198
|
0
|
|
|
0
|
1
|
|
my($self, $group) = @_; |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
return $self->dbh->transaction(sub { |
201
|
0
|
0
|
|
0
|
|
|
$group = ref($self)->load(name => $group, _dbh => $self->{_dbh}) |
202
|
|
|
|
|
|
|
unless ref $group; |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
return |
205
|
0
|
|
0
|
|
|
|
$self->_DELETE_membership($group->{id}) && |
206
|
|
|
|
|
|
|
$self->_refresh_permissions && |
207
|
|
|
|
|
|
|
$self->_refresh_membership; |
208
|
0
|
|
|
|
|
|
}); |
209
|
|
|
|
|
|
|
} |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
sub refresh { |
212
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
213
|
0
|
|
0
|
|
|
|
return $self->_refresh_meta && $self->_refresh_user; |
214
|
|
|
|
|
|
|
} |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
# accessors |
217
|
|
|
|
|
|
|
|
218
|
0
|
|
|
0
|
1
|
|
sub dbh { return $_[0]->{_dbh}; } |
219
|
|
|
|
|
|
|
|
220
|
0
|
|
|
0
|
0
|
|
sub default_password_crypt { return "SHA1"; } |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
# driver constructor |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
sub driver_new { |
225
|
0
|
|
|
0
|
0
|
|
my($class, $driver, %args) = @_; |
226
|
|
|
|
|
|
|
|
227
|
0
|
|
0
|
|
|
|
$args{_flags} ||= {}; |
228
|
0
|
|
0
|
|
|
|
$args{_permissions} ||= {}; |
229
|
0
|
|
0
|
|
|
|
$args{_membership} ||= {}; |
230
|
|
|
|
|
|
|
|
231
|
0
|
|
|
|
|
|
return bless \%args, $class; |
232
|
|
|
|
|
|
|
} |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
# private class methods |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
sub _connect_cached { |
237
|
0
|
|
|
0
|
|
|
my($class, %args) = @_; |
238
|
|
|
|
|
|
|
|
239
|
0
|
0
|
|
|
|
|
if(my $dbh = Schema::RDBMS::AUS->dbh( |
240
|
|
|
|
|
|
|
@args{qw(_db_dsn _db_user _db_pass _db_opts)} |
241
|
|
|
|
|
|
|
)) { |
242
|
0
|
|
|
|
|
|
return $dbh; |
243
|
|
|
|
|
|
|
} else { |
244
|
0
|
|
|
|
|
|
croak(qq{_connect_cached() failed: }, DBI->errstr); |
245
|
|
|
|
|
|
|
} |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
# private class/object methods |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
sub _new { |
251
|
0
|
|
|
0
|
|
|
my($self, %args) = @_; |
252
|
|
|
|
|
|
|
|
253
|
0
|
|
|
|
|
|
my $class; |
254
|
0
|
0
|
|
|
|
|
if($class = ref($self)) { |
255
|
0
|
|
|
|
|
|
%args = (%$self, %args); |
256
|
|
|
|
|
|
|
} else { |
257
|
0
|
|
|
|
|
|
$class = $self; |
258
|
|
|
|
|
|
|
} |
259
|
|
|
|
|
|
|
|
260
|
0
|
0
|
|
|
|
|
$args{_dbh} = $self->_connect_cached(%args) |
261
|
|
|
|
|
|
|
unless $args{_dbh}; |
262
|
|
|
|
|
|
|
|
263
|
0
|
0
|
|
|
|
|
croak "a database handle (_dbh) is required for $class" |
264
|
|
|
|
|
|
|
unless($args{_dbh}); |
265
|
|
|
|
|
|
|
|
266
|
0
|
0
|
|
|
|
|
croak "_dbh does not seem to be a DBIx::Transaction object" |
267
|
|
|
|
|
|
|
unless($args{_dbh}->isa('DBIx::Transaction::db')); |
268
|
|
|
|
|
|
|
|
269
|
0
|
0
|
|
|
|
|
$args{_dbh_driver} = $args{_dbh}->{Driver}->{Name} |
270
|
|
|
|
|
|
|
unless $args{_dbh_driver}; |
271
|
|
|
|
|
|
|
|
272
|
0
|
|
|
0
|
|
|
$args{_validate_password} = sub { return length $_[0]; } |
273
|
0
|
0
|
|
|
|
|
unless $args{_validate_password}; |
274
|
|
|
|
|
|
|
|
275
|
0
|
|
|
|
|
|
return $class->driver_new($args{_dbh_driver}, %args); |
276
|
|
|
|
|
|
|
} |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
sub _use_crypt_class { |
279
|
0
|
|
|
0
|
|
|
my $self = shift; |
280
|
|
|
|
|
|
|
|
281
|
0
|
0
|
|
|
|
|
eval "use $self->{_crypt_class}; 1" |
282
|
|
|
|
|
|
|
or croak "Failed to load $self->{_crypt_class}: $@"; |
283
|
|
|
|
|
|
|
|
284
|
0
|
|
|
|
|
|
return $self; |
285
|
|
|
|
|
|
|
} |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
sub _refresh_user { |
288
|
0
|
|
|
0
|
|
|
my $self = shift; |
289
|
0
|
0
|
|
|
|
|
if(my $row = $self->_SELECT_user) { |
290
|
0
|
|
|
|
|
|
%$self = (%$self, %$row); |
291
|
0
|
|
|
|
|
|
return $self; |
292
|
|
|
|
|
|
|
} else { |
293
|
0
|
|
|
|
|
|
die "Refreshing user failed!"; |
294
|
|
|
|
|
|
|
} |
295
|
|
|
|
|
|
|
} |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
sub _refresh_meta { |
298
|
0
|
|
|
0
|
|
|
my $self = shift; |
299
|
|
|
|
|
|
|
return |
300
|
0
|
0
|
0
|
|
|
|
$self->_refresh_flags && |
301
|
|
|
|
|
|
|
$self->_refresh_permissions && |
302
|
|
|
|
|
|
|
$self->_refresh_membership |
303
|
|
|
|
|
|
|
or die "Refreshing metadata failed!"; |
304
|
|
|
|
|
|
|
} |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
# low-level queries |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
sub _LOAD_user { |
309
|
0
|
|
|
0
|
|
|
my($self, %args) = @_; |
310
|
|
|
|
|
|
|
return $self->dbh->transaction(sub { |
311
|
0
|
0
|
|
0
|
|
|
if(my $row = $self->_SELECT_user(%args)) { |
312
|
0
|
|
|
|
|
|
%$self = (%$self, %$row); |
313
|
0
|
|
|
|
|
|
$self->_refresh_flags; |
314
|
0
|
|
|
|
|
|
$self->_refresh_permissions; |
315
|
0
|
|
|
|
|
|
$self->_refresh_membership; |
316
|
0
|
|
|
|
|
|
return $self->_use_crypt_class; |
317
|
|
|
|
|
|
|
} else { |
318
|
0
|
|
|
|
|
|
die "User not found.\n"; |
319
|
|
|
|
|
|
|
} |
320
|
0
|
|
|
|
|
|
}); |
321
|
|
|
|
|
|
|
} |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
sub _check_password { |
324
|
0
|
|
|
0
|
|
|
my($self, $password) = @_; |
325
|
0
|
|
|
|
|
|
return $self->crypt($password) eq $self->{password}; |
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
sub _CREATE_user { |
329
|
0
|
|
|
0
|
|
|
my($self, %args) = @_; |
330
|
|
|
|
|
|
|
return $self->dbh->transaction(sub { |
331
|
0
|
0
|
|
0
|
|
|
if($self->_INSERT_user(%args)) { |
332
|
0
|
|
|
|
|
|
my $id = $self->dbh->last_insert_id(undef, undef, 'aus_user', undef); |
333
|
0
|
|
|
|
|
|
$self->{id} = $id; |
334
|
0
|
|
|
|
|
|
return $self->_LOAD_user; |
335
|
|
|
|
|
|
|
} else { |
336
|
0
|
|
|
|
|
|
return; |
337
|
|
|
|
|
|
|
} |
338
|
0
|
|
|
|
|
|
}); |
339
|
|
|
|
|
|
|
} |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
sub _sql_UPDATE_used { |
342
|
0
|
|
|
0
|
|
|
my $self = shift; |
343
|
0
|
|
|
|
|
|
return('UPDATE aus_user SET time_used = now() WHERE id = ?', $self->{id}); |
344
|
|
|
|
|
|
|
} |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
sub _sql_SELECT_used { |
347
|
0
|
|
|
0
|
|
|
my $self = shift; |
348
|
0
|
|
|
|
|
|
return('SELECT time_used FROM aus_user WHERE id = ?', $self->{id}); |
349
|
|
|
|
|
|
|
} |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
sub _UPDATE_used { |
352
|
0
|
|
|
0
|
|
|
my $self = shift; |
353
|
0
|
|
|
|
|
|
my $dbh = $self->dbh; |
354
|
|
|
|
|
|
|
return $dbh->transaction(sub { |
355
|
0
|
|
|
0
|
|
|
my($query, $id) = $self->_sql_UPDATE_used; |
356
|
0
|
0
|
|
|
|
|
$dbh->do($query, {}, $id) |
357
|
|
|
|
|
|
|
or die "Failed to update last used time: ", $dbh->errstr; |
358
|
|
|
|
|
|
|
|
359
|
0
|
|
|
|
|
|
($query, $id) = $self->_sql_SELECT_used; |
360
|
0
|
0
|
|
|
|
|
return $dbh->selectrow_array($query, {}, $id) |
361
|
|
|
|
|
|
|
or die "Failed to fetch last used time: ", $dbh->errstr; |
362
|
0
|
|
|
|
|
|
}); |
363
|
|
|
|
|
|
|
} |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
sub _FIELDS_user { |
366
|
0
|
|
|
0
|
|
|
return qw(id name password password_crypt is_group time_used); |
367
|
|
|
|
|
|
|
} |
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
sub _sql_SELECT_user { |
370
|
0
|
|
|
0
|
|
|
my($self, %args) = @_; |
371
|
|
|
|
|
|
|
|
372
|
0
|
|
|
|
|
|
my($k, $v); |
373
|
0
|
|
|
|
|
|
my @fields = ( |
374
|
0
|
|
|
|
|
|
(map { "aus_user.$_ AS $_" } $self->_FIELDS_user), |
375
|
|
|
|
|
|
|
"aus_password_crypt.class AS _crypt_class" |
376
|
|
|
|
|
|
|
); |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
{ |
379
|
0
|
|
|
|
|
|
local $" = ", "; |
|
0
|
|
|
|
|
|
|
380
|
0
|
|
|
|
|
|
$k = qq{ |
381
|
|
|
|
|
|
|
SELECT @fields FROM aus_user |
382
|
|
|
|
|
|
|
LEFT OUTER JOIN |
383
|
|
|
|
|
|
|
aus_password_crypt |
384
|
|
|
|
|
|
|
ON |
385
|
|
|
|
|
|
|
aus_user.password_crypt = aus_password_crypt.id |
386
|
|
|
|
|
|
|
}; |
387
|
|
|
|
|
|
|
} |
388
|
|
|
|
|
|
|
|
389
|
0
|
0
|
|
|
|
|
if($args{id}) { |
|
|
0
|
|
|
|
|
|
390
|
0
|
|
|
|
|
|
$k .= "WHERE aus_user.id = ?"; |
391
|
0
|
|
|
|
|
|
$v = $args{id}; |
392
|
|
|
|
|
|
|
} elsif($args{name}) { |
393
|
0
|
|
|
|
|
|
$k .= "WHERE aus_user.name = ?"; |
394
|
0
|
|
|
|
|
|
$v = $args{name}; |
395
|
|
|
|
|
|
|
} else { |
396
|
0
|
|
|
|
|
|
croak q{Neither "name" or "id" were specified to _SELECT_user!}; |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
|
399
|
0
|
|
|
|
|
|
return($k, $v); |
400
|
|
|
|
|
|
|
} |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
sub _SELECT_user { |
403
|
0
|
|
|
0
|
|
|
my($self, %args) = @_; |
404
|
0
|
|
|
|
|
|
%args = (%$self, %args); |
405
|
|
|
|
|
|
|
|
406
|
0
|
|
|
|
|
|
my($query, $id) = $self->_sql_SELECT_user(%args); |
407
|
0
|
0
|
|
|
|
|
if(my $sth = $self->dbh->prepare($query)) { |
408
|
0
|
0
|
|
|
|
|
if($sth->execute($id)) { |
409
|
0
|
|
|
|
|
|
my $rv = $sth->fetchrow_hashref; |
410
|
0
|
|
|
|
|
|
$sth->finish; |
411
|
0
|
|
|
|
|
|
return $rv; |
412
|
|
|
|
|
|
|
} |
413
|
|
|
|
|
|
|
} |
414
|
|
|
|
|
|
|
|
415
|
0
|
|
|
|
|
|
die "Query $query failed: ", $self->dbh->errstr; |
416
|
|
|
|
|
|
|
} |
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
sub _SELECT_or_INSERT_flag { |
419
|
0
|
|
|
0
|
|
|
my($self, $flag) = @_; |
420
|
0
|
|
|
|
|
|
$flag = lc $flag; |
421
|
|
|
|
|
|
|
return $self->dbh->transaction(sub { |
422
|
0
|
|
|
0
|
|
|
my $sth = $self->dbh->prepare_cached( |
423
|
|
|
|
|
|
|
"SELECT name FROM aus_flag WHERE name = ?" |
424
|
|
|
|
|
|
|
); |
425
|
|
|
|
|
|
|
|
426
|
0
|
0
|
|
|
|
|
$sth->execute($flag) or die $sth->errstr; |
427
|
0
|
0
|
|
|
|
|
if($sth->fetchrow_array) { |
428
|
0
|
|
|
|
|
|
$sth->finish; |
429
|
0
|
|
|
|
|
|
return $flag; |
430
|
|
|
|
|
|
|
} else { |
431
|
0
|
|
|
|
|
|
$sth->finish; |
432
|
0
|
0
|
|
|
|
|
$self->dbh->do("INSERT INTO aus_flag (name) VALUES (?)", {}, $flag) |
433
|
|
|
|
|
|
|
or die $self->dbh->errstr; |
434
|
0
|
|
|
|
|
|
return $flag; |
435
|
|
|
|
|
|
|
} |
436
|
0
|
|
|
|
|
|
}); |
437
|
|
|
|
|
|
|
} |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
sub _sql_INSERT_user { |
440
|
0
|
|
|
0
|
|
|
my($self, %args) = @_; |
441
|
|
|
|
|
|
|
|
442
|
0
|
|
|
|
|
|
my @keys = sort grep($args{$_}, $self->_FIELDS_user); |
443
|
0
|
|
|
|
|
|
my @qs = (("?") x scalar @keys); |
444
|
|
|
|
|
|
|
|
445
|
0
|
|
|
|
|
|
local $" = ", "; |
446
|
0
|
|
|
|
|
|
return(qq{INSERT INTO aus_user (@keys) VALUES (@qs)}, @keys); |
447
|
|
|
|
|
|
|
} |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
sub _INSERT_user { |
450
|
0
|
|
|
0
|
|
|
my($self, %args) = @_; |
451
|
|
|
|
|
|
|
|
452
|
0
|
|
|
|
|
|
%args = (%$self, %args); |
453
|
0
|
0
|
|
|
|
|
croak "Can't INSERT a user that already has an id" if($args{id}); |
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
return $self if($self->dbh->transaction(sub { |
456
|
0
|
|
|
0
|
|
|
my($query, @keys) = $self->_sql_INSERT_user(%args); |
457
|
0
|
|
|
|
|
|
$self->dbh->do($query, {}, @args{@keys}); |
458
|
0
|
0
|
|
|
|
|
})); |
459
|
|
|
|
|
|
|
|
460
|
0
|
|
|
|
|
|
return; |
461
|
|
|
|
|
|
|
} |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
sub _INSERT_user_log { |
464
|
0
|
|
|
0
|
|
|
my($self, $event, $data) = @_; |
465
|
|
|
|
|
|
|
return $self->dbh->transaction(sub { |
466
|
0
|
|
|
0
|
|
|
$self->dbh->do( |
467
|
|
|
|
|
|
|
"INSERT INTO aus_user_log (user_id, event, data) VALUES (?, ?, ?)", |
468
|
|
|
|
|
|
|
{}, |
469
|
|
|
|
|
|
|
$self->{id}, $event, $data |
470
|
|
|
|
|
|
|
); |
471
|
0
|
|
|
|
|
|
}); |
472
|
|
|
|
|
|
|
} |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
sub _sql_UPDATE_user { |
475
|
0
|
|
|
0
|
|
|
my $self = shift; |
476
|
0
|
|
0
|
|
|
|
my @fields = grep($_ ne 'id' && $_ ne 'time_used', $self->_FIELDS_user); |
477
|
0
|
|
|
|
|
|
my @updates = map { "$_ = ?" } @fields; |
|
0
|
|
|
|
|
|
|
478
|
0
|
|
|
|
|
|
local $" = ", "; |
479
|
0
|
|
|
|
|
|
my $sql = "UPDATE aus_user SET @updates WHERE id = ?"; |
480
|
0
|
|
|
|
|
|
return($sql, @fields, 'id'); |
481
|
|
|
|
|
|
|
} |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
sub _UPDATE_user { |
484
|
0
|
|
|
0
|
|
|
my $self = shift; |
485
|
0
|
|
|
|
|
|
my($query, @params) = $self->_sql_UPDATE_user; |
486
|
|
|
|
|
|
|
|
487
|
|
|
|
|
|
|
return $self->dbh->transaction( |
488
|
0
|
|
|
0
|
|
|
sub { $self->dbh->do($query, {}, @{$self}{@params}); } |
|
0
|
|
|
|
|
|
|
489
|
0
|
|
|
|
|
|
); |
490
|
|
|
|
|
|
|
} |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
sub _sql_DELETE_flags { |
493
|
0
|
|
|
0
|
|
|
my $self = shift; |
494
|
|
|
|
|
|
|
return( |
495
|
0
|
|
|
|
|
|
q{DELETE FROM aus_user_flags WHERE user_id = ?}, |
496
|
|
|
|
|
|
|
'id' |
497
|
|
|
|
|
|
|
); |
498
|
|
|
|
|
|
|
} |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
sub _sql_INSERT_flag { |
501
|
0
|
|
|
0
|
|
|
my $self = shift; |
502
|
|
|
|
|
|
|
return( |
503
|
0
|
|
|
|
|
|
q{INSERT INTO aus_user_flags (user_id, flag_name, enabled) VALUES (?, ?, ?)}, |
504
|
|
|
|
|
|
|
'id' |
505
|
|
|
|
|
|
|
); |
506
|
|
|
|
|
|
|
} |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
sub _sql_SELECT_flags { |
509
|
0
|
|
|
0
|
|
|
my $self = shift; |
510
|
|
|
|
|
|
|
return( |
511
|
0
|
|
|
|
|
|
q{SELECT flag_name, enabled FROM aus_user_flags WHERE user_id = ?}, |
512
|
|
|
|
|
|
|
'id' |
513
|
|
|
|
|
|
|
); |
514
|
|
|
|
|
|
|
} |
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
sub _sql_SELECT_permissions { |
517
|
0
|
|
|
0
|
|
|
my $self = shift; |
518
|
|
|
|
|
|
|
return( |
519
|
0
|
|
|
|
|
|
q{SELECT flag_name, enabled FROM aus_all_user_flags WHERE user_id = ?}, |
520
|
|
|
|
|
|
|
'id' |
521
|
|
|
|
|
|
|
); |
522
|
|
|
|
|
|
|
} |
523
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
sub _sql_SELECT_membership { |
525
|
0
|
|
|
0
|
|
|
my $self = shift; |
526
|
|
|
|
|
|
|
return( |
527
|
0
|
|
|
|
|
|
q{ |
528
|
|
|
|
|
|
|
SELECT |
529
|
|
|
|
|
|
|
ancestor, min(degree) AS degree |
530
|
|
|
|
|
|
|
FROM aus_user_ancestors |
531
|
|
|
|
|
|
|
WHERE user_id = ? |
532
|
|
|
|
|
|
|
GROUP BY user_id, ancestor |
533
|
|
|
|
|
|
|
}, |
534
|
|
|
|
|
|
|
'id' |
535
|
|
|
|
|
|
|
); |
536
|
|
|
|
|
|
|
} |
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
sub _fetch_flags { |
539
|
0
|
|
|
0
|
|
|
my($self, $sth) = @_; |
540
|
0
|
|
|
|
|
|
my %rv; |
541
|
0
|
|
|
|
|
|
while(my @row = $sth->fetchrow_array) { |
542
|
0
|
|
|
|
|
|
$rv{lc $row[0]} = $row[1]; |
543
|
|
|
|
|
|
|
} |
544
|
0
|
|
|
|
|
|
return %rv; |
545
|
|
|
|
|
|
|
} |
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
sub _SELECT_flags { |
548
|
0
|
|
|
0
|
|
|
my($self, $query, @params) = @_; |
549
|
0
|
|
|
|
|
|
my %rv; |
550
|
|
|
|
|
|
|
$self->dbh->transaction(sub { |
551
|
0
|
|
|
0
|
|
|
my $sth = $self->dbh->prepare_cached($query); |
552
|
0
|
0
|
|
|
|
|
if($sth->execute(@{$self}{@params})) { |
|
0
|
|
|
|
|
|
|
553
|
0
|
|
|
|
|
|
%rv = $self->_fetch_flags($sth); |
554
|
0
|
|
|
|
|
|
$sth->finish; |
555
|
|
|
|
|
|
|
} else { |
556
|
0
|
|
|
|
|
|
die "fetching flags failed: ", $sth->errstr; |
557
|
|
|
|
|
|
|
} |
558
|
0
|
|
|
|
|
|
}); |
559
|
0
|
|
|
|
|
|
return %rv; |
560
|
|
|
|
|
|
|
} |
561
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
sub _INSERT_membership { |
563
|
0
|
|
|
0
|
|
|
my($self, $gid) = @_; |
564
|
|
|
|
|
|
|
return $self->dbh->transaction(sub { |
565
|
0
|
|
|
0
|
|
|
my $sth = $self->dbh->prepare_cached( |
566
|
|
|
|
|
|
|
q{INSERT INTO aus_user_membership (user_id, member_of) VALUES (?, ?)} |
567
|
|
|
|
|
|
|
); |
568
|
|
|
|
|
|
|
|
569
|
0
|
0
|
|
|
|
|
$sth->execute($self->{id}, $gid) |
570
|
|
|
|
|
|
|
or die $sth->errstr; |
571
|
|
|
|
|
|
|
|
572
|
0
|
|
|
|
|
|
return 1; |
573
|
0
|
|
|
|
|
|
}); |
574
|
|
|
|
|
|
|
} |
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
sub _DELETE_membership { |
577
|
0
|
|
|
0
|
|
|
my($self, $gid) = @_; |
578
|
|
|
|
|
|
|
return $self->dbh->transaction(sub { |
579
|
0
|
|
|
0
|
|
|
my $sth = $self->dbh->prepare_cached( |
580
|
|
|
|
|
|
|
q{DELETE FROM aus_user_membership WHERE user_id = ? AND member_of = ?} |
581
|
|
|
|
|
|
|
); |
582
|
|
|
|
|
|
|
|
583
|
0
|
0
|
|
|
|
|
$sth->execute($self->{id}, $gid) |
584
|
|
|
|
|
|
|
or die $sth->errstr; |
585
|
|
|
|
|
|
|
|
586
|
0
|
|
|
|
|
|
return 1; |
587
|
0
|
|
|
|
|
|
}); |
588
|
|
|
|
|
|
|
} |
589
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
sub _refresh_flags { |
591
|
0
|
|
|
0
|
|
|
my $self = shift; |
592
|
0
|
|
|
|
|
|
my %rv = $self->_SELECT_flags($self->_sql_SELECT_flags); |
593
|
0
|
|
|
|
|
|
$self->{_flags} = \%rv; |
594
|
0
|
|
|
|
|
|
return $self->{_flags}; |
595
|
|
|
|
|
|
|
} |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
sub _refresh_permissions { |
598
|
0
|
|
|
0
|
|
|
my $self = shift; |
599
|
0
|
|
|
|
|
|
my %rv = $self->_SELECT_flags($self->_sql_SELECT_permissions); |
600
|
0
|
|
|
|
|
|
$self->{_permissions} = \%rv; |
601
|
0
|
|
|
|
|
|
return $self->{_permissions}; |
602
|
|
|
|
|
|
|
} |
603
|
|
|
|
|
|
|
|
604
|
|
|
|
|
|
|
sub _refresh_membership { |
605
|
0
|
|
|
0
|
|
|
my $self = shift; |
606
|
0
|
|
|
|
|
|
my %rv = $self->_SELECT_flags($self->_sql_SELECT_membership); |
607
|
0
|
|
|
|
|
|
$self->{_membership} = \%rv; |
608
|
0
|
|
|
|
|
|
return $self->{_membership}; |
609
|
|
|
|
|
|
|
} |
610
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
sub _save_flags { |
612
|
0
|
|
|
0
|
|
|
my $self = shift; |
613
|
|
|
|
|
|
|
return $self->dbh->transaction(sub { |
614
|
0
|
|
|
0
|
|
|
my($q, @p) = $self->_sql_DELETE_flags; |
615
|
|
|
|
|
|
|
|
616
|
0
|
0
|
|
|
|
|
$self->dbh->do($q, {}, @{$self}{@p}) or die |
|
0
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
"do($q): ", $self->dbh->errstr; |
618
|
|
|
|
|
|
|
|
619
|
0
|
|
|
|
|
|
($q, @p) = $self->_sql_INSERT_flag; |
620
|
|
|
|
|
|
|
|
621
|
0
|
|
|
|
|
|
while(my($k, $v) = each(%{$self->{_flags}})) { |
|
0
|
|
|
|
|
|
|
622
|
0
|
0
|
|
|
|
|
$self->dbh->do($q, {}, @{$self}{@p}, $k, $v) or |
|
0
|
|
|
|
|
|
|
623
|
|
|
|
|
|
|
die "do($q, $k, $v): ", $self->dbh->errstr; |
624
|
|
|
|
|
|
|
} |
625
|
|
|
|
|
|
|
|
626
|
0
|
|
|
|
|
|
$self->_refresh_permissions; |
627
|
0
|
|
|
|
|
|
return 1; |
628
|
0
|
|
|
|
|
|
}); |
629
|
|
|
|
|
|
|
} |