Add a method that generates a reset HMAC to User.pm
[gruntmaster-data.git] / lib / Gruntmaster / Data / Result / User.pm
CommitLineData
4ed3f8e7
MG
1use utf8;
2package 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
be2f7678 9Gruntmaster::Data::Result::User - List of users
4ed3f8e7
MG
10
11=cut
12
13use strict;
14use warnings;
15
16use 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
2fec2d56
MG
31=head2 passphrase
32
33 data_type: 'text'
9bb39921 34 is_nullable: 1
2fec2d56 35
be2f7678
MG
36RFC2307-encoded passphrase
37
2fec2d56
MG
38=head2 admin
39
40 data_type: 'boolean'
41 default_value: false
42 is_nullable: 0
43
4ed3f8e7
MG
44=head2 name
45
46 data_type: 'text'
47 is_nullable: 1
48
be2f7678
MG
49Full name of user
50
4ed3f8e7
MG
51=head2 email
52
53 data_type: 'text'
54 is_nullable: 1
55
85d3f015
MG
56=head2 phone
57
58 data_type: 'text'
59 is_nullable: 1
60
4ed3f8e7
MG
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
be2f7678
MG
76Highschool, Undergraduate, Master, Doctorate or Other
77
73243865
MG
78=head2 country
79
80 data_type: 'text'
81 is_nullable: 1
82
4ed3f8e7
MG
83=head2 lastjob
84
85 data_type: 'bigint'
86 is_nullable: 1
87
be2f7678
MG
88Unix time when this user last submitted a job
89
8c7ef664
MG
90=head2 since
91
92 data_type: 'bigint'
93 default_value: (date_part('epoch'::text, now()))::bigint
94 is_nullable: 1
95
96Unix time when this user was created
97
4ed3f8e7
MG
98=cut
99
100__PACKAGE__->add_columns(
101 "id",
102 { data_type => "text", is_nullable => 0 },
2fec2d56 103 "passphrase",
9bb39921 104 { data_type => "text", is_nullable => 1 },
2fec2d56
MG
105 "admin",
106 { data_type => "boolean", default_value => \"false", is_nullable => 0 },
4ed3f8e7
MG
107 "name",
108 { data_type => "text", is_nullable => 1 },
109 "email",
110 { data_type => "text", is_nullable => 1 },
85d3f015
MG
111 "phone",
112 { data_type => "text", is_nullable => 1 },
4ed3f8e7
MG
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 },
73243865
MG
119 "country",
120 { data_type => "text", is_nullable => 1 },
4ed3f8e7
MG
121 "lastjob",
122 { data_type => "bigint", is_nullable => 1 },
8c7ef664
MG
123 "since",
124 {
125 data_type => "bigint",
126 default_value => \"(date_part('epoch'::text, now()))::bigint",
127 is_nullable => 1,
128 },
4ed3f8e7
MG
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
adb42d4d
MG
145=head2 contest_statuses
146
147Type: has_many
148
149Related 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
4ed3f8e7
MG
160=head2 contests
161
162Type: has_many
163
164Related 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
177Type: has_many
178
179Related 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
192Type: has_many
193
194Related 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
adb42d4d
MG
205=head2 problem_statuses
206
207Type: has_many
208
209Related 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
4ed3f8e7
MG
220=head2 problems
221
222Type: has_many
223
224Related 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
8c7ef664
MG
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
4ed3f8e7 238
54bc1dff 239use Bytes::Random::Secure qw/random_bytes/;
de7226ca 240use Class::Method::Modifiers qw/after/;
54bc1dff 241use Digest::SHA qw/hmac_sha1_base64/;
de7226ca
MG
242
243after qw/insert update delete/ => sub {
244 my ($self) = @_;
245 Gruntmaster::Data::purge '/us/';
246 Gruntmaster::Data::purge '/us/' . $self->id;
247};
248
de625c9b
MG
249use Authen::Passphrase;
250use Authen::Passphrase::BlowfishCrypt;
251
252sub check_passphrase {
253 my ($self, $pw) = @_;
254 Authen::Passphrase->from_rfc2307($self->passphrase)->match($pw)
255}
256
257sub set_passphrase {
258 my ($self, $pw) = @_;
259 $self->update({passphrase => Authen::Passphrase::BlowfishCrypt->new(
260 cost => 10,
261 passphrase => $pw,
262 salt_random => 1,
526b9e80 263 )->as_rfc2307});
de625c9b 264}
4ed3f8e7 265
54bc1dff
MG
266my $hmackey = $ENV{GRUNTMASTER_HMAC_KEY};
267
268sub 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
4ed3f8e7 2751;
4a8747ef
MG
276
277__END__
278
de625c9b
MG
279=head1 METHODS
280
281=head2 check_passphrase(I<$passphrase>)
282
283Returns true if I<$passphrase> is the correct passphrase, false otherwise.
284
285=head2 set_passphrase(I<$passphrase>)
286
287Changes the passphrase to I<$passphrase>.
288
4a8747ef
MG
289=head1 AUTHOR
290
291Marius Gavrilescu E<lt>marius@ieval.roE<gt>
292
293=head1 COPYRIGHT AND LICENSE
294
295Copyright (C) 2014 by Marius Gavrilescu
296
297This library is free software; you can redistribute it and/or modify
298it under the same terms as Perl itself, either Perl version 5.18.1 or,
299at your option, any later version of Perl 5 you may have available.
300
301
302=cut
This page took 0.032759 seconds and 4 git commands to generate.