Add a method that generates a reset HMAC to User.pm
[gruntmaster-data.git] / lib / Gruntmaster / Data / Result / User.pm
1 use utf8;
2 package Gruntmaster::Data::Result::User;
3
4 # Created by DBIx::Class::Schema::Loader
5 # DO NOT MODIFY THE FIRST PART OF THIS FILE
6
7 =head1 NAME
8
9 Gruntmaster::Data::Result::User - List of users
10
11 =cut
12
13 use strict;
14 use warnings;
15
16 use base 'DBIx::Class::Core';
17
18 =head1 TABLE: C<users>
19
20 =cut
21
22 __PACKAGE__->table("users");
23
24 =head1 ACCESSORS
25
26 =head2 id
27
28 data_type: 'text'
29 is_nullable: 0
30
31 =head2 passphrase
32
33 data_type: 'text'
34 is_nullable: 1
35
36 RFC2307-encoded passphrase
37
38 =head2 admin
39
40 data_type: 'boolean'
41 default_value: false
42 is_nullable: 0
43
44 =head2 name
45
46 data_type: 'text'
47 is_nullable: 1
48
49 Full name of user
50
51 =head2 email
52
53 data_type: 'text'
54 is_nullable: 1
55
56 =head2 phone
57
58 data_type: 'text'
59 is_nullable: 1
60
61 =head2 town
62
63 data_type: 'text'
64 is_nullable: 1
65
66 =head2 university
67
68 data_type: 'text'
69 is_nullable: 1
70
71 =head2 level
72
73 data_type: 'text'
74 is_nullable: 1
75
76 Highschool, Undergraduate, Master, Doctorate or Other
77
78 =head2 country
79
80 data_type: 'text'
81 is_nullable: 1
82
83 =head2 lastjob
84
85 data_type: 'bigint'
86 is_nullable: 1
87
88 Unix time when this user last submitted a job
89
90 =head2 since
91
92 data_type: 'bigint'
93 default_value: (date_part('epoch'::text, now()))::bigint
94 is_nullable: 1
95
96 Unix time when this user was created
97
98 =cut
99
100 __PACKAGE__->add_columns(
101 "id",
102 { data_type => "text", is_nullable => 0 },
103 "passphrase",
104 { data_type => "text", is_nullable => 1 },
105 "admin",
106 { data_type => "boolean", default_value => \"false", is_nullable => 0 },
107 "name",
108 { data_type => "text", is_nullable => 1 },
109 "email",
110 { data_type => "text", is_nullable => 1 },
111 "phone",
112 { data_type => "text", is_nullable => 1 },
113 "town",
114 { data_type => "text", is_nullable => 1 },
115 "university",
116 { data_type => "text", is_nullable => 1 },
117 "level",
118 { data_type => "text", is_nullable => 1 },
119 "country",
120 { data_type => "text", is_nullable => 1 },
121 "lastjob",
122 { data_type => "bigint", is_nullable => 1 },
123 "since",
124 {
125 data_type => "bigint",
126 default_value => \"(date_part('epoch'::text, now()))::bigint",
127 is_nullable => 1,
128 },
129 );
130
131 =head1 PRIMARY KEY
132
133 =over 4
134
135 =item * L</id>
136
137 =back
138
139 =cut
140
141 __PACKAGE__->set_primary_key("id");
142
143 =head1 RELATIONS
144
145 =head2 contest_statuses
146
147 Type: has_many
148
149 Related object: L<Gruntmaster::Data::Result::ContestStatus>
150
151 =cut
152
153 __PACKAGE__->has_many(
154 "contest_statuses",
155 "Gruntmaster::Data::Result::ContestStatus",
156 { "foreign.owner" => "self.id" },
157 { cascade_copy => 0, cascade_delete => 0 },
158 );
159
160 =head2 contests
161
162 Type: has_many
163
164 Related object: L<Gruntmaster::Data::Result::Contest>
165
166 =cut
167
168 __PACKAGE__->has_many(
169 "contests",
170 "Gruntmaster::Data::Result::Contest",
171 { "foreign.owner" => "self.id" },
172 { cascade_copy => 0, cascade_delete => 0 },
173 );
174
175 =head2 jobs
176
177 Type: has_many
178
179 Related object: L<Gruntmaster::Data::Result::Job>
180
181 =cut
182
183 __PACKAGE__->has_many(
184 "jobs",
185 "Gruntmaster::Data::Result::Job",
186 { "foreign.owner" => "self.id" },
187 { cascade_copy => 0, cascade_delete => 0 },
188 );
189
190 =head2 opens
191
192 Type: has_many
193
194 Related object: L<Gruntmaster::Data::Result::Open>
195
196 =cut
197
198 __PACKAGE__->has_many(
199 "opens",
200 "Gruntmaster::Data::Result::Open",
201 { "foreign.owner" => "self.id" },
202 { cascade_copy => 0, cascade_delete => 0 },
203 );
204
205 =head2 problem_statuses
206
207 Type: has_many
208
209 Related object: L<Gruntmaster::Data::Result::ProblemStatus>
210
211 =cut
212
213 __PACKAGE__->has_many(
214 "problem_statuses",
215 "Gruntmaster::Data::Result::ProblemStatus",
216 { "foreign.owner" => "self.id" },
217 { cascade_copy => 0, cascade_delete => 0 },
218 );
219
220 =head2 problems
221
222 Type: has_many
223
224 Related object: L<Gruntmaster::Data::Result::Problem>
225
226 =cut
227
228 __PACKAGE__->has_many(
229 "problems",
230 "Gruntmaster::Data::Result::Problem",
231 { "foreign.owner" => "self.id" },
232 { cascade_copy => 0, cascade_delete => 0 },
233 );
234
235
236 # Created by DBIx::Class::Schema::Loader v0.07042 @ 2015-02-10 18:42:04
237 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:L/ExLdA0pkJ1DeM+RzlDjw
238
239 use Bytes::Random::Secure qw/random_bytes/;
240 use Class::Method::Modifiers qw/after/;
241 use Digest::SHA qw/hmac_sha1_base64/;
242
243 after qw/insert update delete/ => sub {
244 my ($self) = @_;
245 Gruntmaster::Data::purge '/us/';
246 Gruntmaster::Data::purge '/us/' . $self->id;
247 };
248
249 use Authen::Passphrase;
250 use Authen::Passphrase::BlowfishCrypt;
251
252 sub check_passphrase {
253 my ($self, $pw) = @_;
254 Authen::Passphrase->from_rfc2307($self->passphrase)->match($pw)
255 }
256
257 sub set_passphrase {
258 my ($self, $pw) = @_;
259 $self->update({passphrase => Authen::Passphrase::BlowfishCrypt->new(
260 cost => 10,
261 passphrase => $pw,
262 salt_random => 1,
263 )->as_rfc2307});
264 }
265
266 my $hmackey = $ENV{GRUNTMASTER_HMAC_KEY};
267
268 sub make_reset_hmac {
269 my ($self, $expire) = @_;
270 $expire //= time + 60 * 60;
271 $hmackey //= random_bytes 512;
272 hmac_sha1_base64 $self->id . " $expire " . $self->passphrase, $hmackey;
273 }
274
275 1;
276
277 __END__
278
279 =head1 METHODS
280
281 =head2 check_passphrase(I<$passphrase>)
282
283 Returns true if I<$passphrase> is the correct passphrase, false otherwise.
284
285 =head2 set_passphrase(I<$passphrase>)
286
287 Changes the passphrase to I<$passphrase>.
288
289 =head1 AUTHOR
290
291 Marius Gavrilescu E<lt>marius@ieval.roE<gt>
292
293 =head1 COPYRIGHT AND LICENSE
294
295 Copyright (C) 2014 by Marius Gavrilescu
296
297 This library is free software; you can redistribute it and/or modify
298 it under the same terms as Perl itself, either Perl version 5.18.1 or,
299 at your option, any later version of Perl 5 you may have available.
300
301
302 =cut
This page took 0.031857 seconds and 4 git commands to generate.