0.14_25 commit
[bse.git] / site / cgi-bin / modules / SiteUser.pm
CommitLineData
589b789c
TC
1package SiteUser;
2use strict;
3# represents a registered user
4use Squirrel::Row;
5use vars qw/@ISA/;
6@ISA = qw/Squirrel::Row/;
9063386f
TC
7use Constants qw($SHOP_FROM);
8use BSE::Util::SQL qw/now_datetime/;
9
10use constant MAX_UNACKED_CONF_MSGS => 3;
11use constant MIN_UNACKED_CONF_GAP => 2 * 24 * 60 * 60;
589b789c
TC
12
13sub columns {
14 return qw/id userId password email keepAddress whenRegistered lastLogon
15 name1 name2 address city state postcode telephone facsimile
b19047a6
TC
16 country wantLetter confirmed confirmSecret waitingForConfirmation
17 textOnlyMail title organization referral otherReferral
9063386f
TC
18 prompt otherPrompt profession otherProfession previousLogon
19 billFirstName billLastName billStreet billSuburb billState
20 billPostCode billCountry instructions billTelephone billFacsimile
4175638b
TC
21 billEmail adminNotes disabled flags
22 customText1 customText2 customText3
23 customStr1 customStr2 customStr3/;
b19047a6
TC
24}
25
26sub removeSubscriptions {
27 my ($self) = @_;
28
29 SiteUsers->doSpecial('removeSubscriptions', $self->{id});
589b789c
TC
30}
31
531fb3bc
TC
32sub removeSubscription {
33 my ($self, $subid) = @_;
34
35 SiteUsers->doSpecial('removeSub', $self->{id}, $subid);
36}
37
9063386f
TC
38sub generic_email {
39 my ($class, $checkemail) = @_;
40
41 # Build a generic form for the email - since an attacker could
42 # include comments or extra spaces or a bunch of other stuff.
43 # this isn't strictly correct, but it's good enough
44 1 while $checkemail =~ s/\([^)]\)//g;
45 if ($checkemail =~ /<([^>]+)>/) {
46 $checkemail = $1;
47 }
48 $checkemail = lc $checkemail;
49 $checkemail =~ s/\s+//g;
50
51 $checkemail;
52}
53
54sub subscriptions {
55 my ($self) = @_;
56
57 require BSE::SubscriptionTypes;
58 return BSE::SubscriptionTypes->getSpecial(userSubscribedTo => $self->{id});
59}
60
61sub send_conf_request {
62 my ($user, $cgi, $cfg, $rcode, $rmsg) = @_;
63
64 my $nopassword = $cfg->entryBool('site users', 'nopassword', 0);
65
66 # check for existing in-progress confirmations
67 my $checkemail = $user->generic_email($user->{email});
68
69 # check the blacklist
70 require BSE::EmailBlacklist;
71
72 # check that the from address has been configured
73 my $from = $cfg->entry('confirmations', 'from') ||
74 $cfg->entry('basic', 'emailfrom')|| $SHOP_FROM;
75 unless ($from) {
76 $$rcode = 'config';
77 $$rmsg = "Configuration Error: The confirmations from address has not been configured";
78 return;
79 }
80
81 my $blackentry = BSE::EmailBlacklist->getEntry($checkemail);
82
83 if ($blackentry) {
84 $$rcode = "blacklist";
85 $$rmsg = $blackentry->{why};
86 return;
87 }
88
89 unless ($user->{confirmSecret}) {
90 use BSE::Util::Secure qw/make_secret/;
91 # print STDERR "Generating secret\n";
92 $user->{confirmSecret} = make_secret($cfg);
93 $user->save;
94 }
95
96 # check for existing confirmations
220c179a 97 require BSE::EmailRequests;
9063386f
TC
98 my $confirm = BSE::EmailRequests->getBy(genEmail=>$checkemail);
99 if ($confirm) {
100 if ($confirm->{unackedConfMsgs} >= MAX_UNACKED_CONF_MSGS) {
101 $$rcode = 'toomany';
102 $$rmsg = "Too many confirmations have been sent to this email address";
103 return;
104 }
105 use BSE::Util::SQL qw/sql_datetime_to_epoch/;
106 my $lastSentEpoch = sql_datetime_to_epoch($confirm->{lastConfSent});
107 if ($lastSentEpoch + MIN_UNACKED_CONF_GAP > time) {
108 $$rcode = 'toosoon';
109 $$rmsg = "The last confirmation was sent too recently, please wait before trying again";
110 return;
111 }
112 }
113 else {
114 my %confirm;
115 my @cols = BSE::EmailRequest->columns;
116 shift @cols;
117 $confirm{email} = $user->{email};
118 $confirm{genEmail} = $checkemail;
119 # prevents silliness on error
120 use BSE::Util::SQL qw(sql_datetime);
121 $confirm{lastConfSent} = sql_datetime(time - MIN_UNACKED_CONF_GAP);
122 $confirm{unackedConfMsgs} = 0;
123 $confirm = BSE::EmailRequests->add(@confirm{@cols});
124 }
125
126 # ok, now we can send the confirmation request
127 my %confacts;
128 %confacts =
129 (
130 BSE::Util::Tags->basic(\%confacts, $cgi, $cfg),
131 user => sub { $user->{$_[0]} },
132 confirm => sub { $confirm->{$_[0]} },
133 remote_addr => sub { $ENV{REMOTE_ADDR} },
134 );
135 my $email_template =
136 $nopassword ? 'user/email_confirm_nop' : 'user/email_confirm';
137 my $body = BSE::Template->get_page($email_template, $cfg, \%confacts);
220c179a
TC
138
139 require BSE::Mail;
9063386f
TC
140 my $mail = BSE::Mail->new(cfg=>$cfg);
141 my $subject = $cfg->entry('confirmations', 'subject')
142 || 'Subscription Confirmation';
143 unless ($mail->send(from=>$from, to=>$user->{email}, subject=>$subject,
144 body=>$body)) {
145 # a problem sending the mail
146 $$rcode = "mail";
147 $$rmsg = $mail->errstr;
148 return;
149 }
150 ++$confirm->{unackedConfMsgs};
151 $confirm->{lastConfSent} = now_datetime;
152 $confirm->save;
153
154 return 1;
155}
156
6a8a205a
TC
157sub orders {
158 my ($self) = @_;
159
160 require Orders;
161
162 return Orders->getBy(userId => $self->{userId});
163}
164
0ec4ac8a
TC
165# check if the user is subscribed to the given subscription
166sub subscribed_to {
167 my ($self, $sub) = @_;
168
169 return; # PH for now, not subscribed
170}
171
172# check if the user is subscribed to the given subscription, and allow
173# for the max_lapsed grace period
174sub subscribed_to_grace {
175 my ($self, $sub) = @_;
176
177 return; # PH for now, not subscribed
178}
179
589b789c 1801;