LJSUP-17669: Login.bml form refactoring
[livejournal.git] / cgi-bin / LJ / Event / SecurityAttributeChanged.pm
blob0af3842a7f1569469330eb91a31f2f0f7bace57b
1 package LJ::Event::SecurityAttributeChanged;
3 use strict;
5 use Carp qw(croak);
6 use LJ::TimeUtil;
8 use base 'LJ::Event';
10 sub new {
11 my ($class, $u, $opts) = @_;
12 croak 'Not an LJ::User' unless LJ::isu($u);
14 my $_get_logtime = sub {
15 my $u = shift;
16 my $action = shift;
17 my $opts = shift;
19 my $ip = $opts->{ip};
21 die "Missing credentials" unless $ip && $action;
23 # $action == 1 -- deleted
24 my $extra = (1 == $action) ? 'new=D&old=V' : 'new=V&old=D';
26 # TODO: change this to use LJ::User::Userlog
27 my $dbr = LJ::get_cluster_reader($u);
28 my $sth = $dbr->prepare(
29 "SELECT logtime, ip".
30 " FROM userlog".
31 " WHERE userid=? AND extra=?".
32 " ORDER BY logtime DESC LIMIT 2");
33 $sth->execute($u->{userid},$extra);
34 my ($logtime, $logip) = $sth->fetchrow_array;
36 # Check for errors
37 die "This event (uid=$u->{userid}, extra=$extra) was not found in logs" unless $logtime;
39 my ($logtime2, $logip2) = $sth->fetchrow_array;
40 die "Second record about this event was found in log"
41 if $logtime2 && $logtime2 == $logtime && ($logip2 ne $logip);
43 die "The event (uid=$u->{userid}, extra=$extra, logtime=$logtime) was found in log,".
44 " but with wrong ip address ($logip, but not $ip)"
45 if $ip ne $logip;
47 return $logtime;
50 my $_get_rename_id = sub {
51 my $u = shift;
52 my $action = shift;
53 my $opts = shift;
55 my $ip = $opts->{ip};
56 my $old_username = $opts->{old_username};
57 my $userid = $u->{userid};
59 # TODO: check is $u a user object?
60 die "Missing credentials" unless $ip && $action && $old_username;
62 my $infohistory = LJ::User::InfoHistory->get( $u, 'username' );
63 my ($latest_record) =
64 reverse
65 sort { $a->timechange_unix <=> $b->timechange_unix }
66 @$infohistory;
68 die "This event (uid=$userid, what=username) was not found in logs"
69 unless $latest_record;
71 my $timechange = $latest_record->timechange_unix;
72 my $oldvalue = $latest_record->oldvalue;
74 die "Event (uid=$userid, what=username) was not found in logs".
75 " has wrong old username: $oldvalue instead of $old_username"
76 if $oldvalue ne $old_username;
78 return $timechange;
81 my %actions = (
82 'account_deleted' => [ 1, $_get_logtime ],
83 'account_activated' => [ 2, $_get_logtime ],
84 'account_renamed' => [ 3, $_get_rename_id ],
87 die 'Wrong action parameter' unless exists($actions{$opts->{action}});
89 my $action = $actions{$opts->{action}}[0];
90 return
91 $class->SUPER::new($u,$action,$actions{$opts->{action}}[1]->($u,$action,$opts));
94 sub is_common { 1 } # As seen in LJ/Event.pm, event fired without subscription
96 # Override this with a false value make subscriptions to this event not show up in normal UI
97 sub is_visible { 0 }
99 # Whether Inbox is always subscribed to
100 sub always_checked { 0 }
102 sub is_significant { 1 }
104 # override parent class subscriptions method to always return
105 # a subscription object for the user
106 sub subscriptions {
107 my ($self, %args) = @_;
108 my $cid = delete $args{'cluster'}; # optional
109 my $limit = delete $args{'limit'}; # optional
110 croak("Unknown options: " . join(', ', keys %args)) if %args;
111 croak("Can't call in web context") if LJ::is_web_context();
113 my @subs;
114 my $u = $self->u;
116 if ($cid == $u->clusterid) {
117 my $row = { userid => $self->u->{userid},
118 ntypeid => LJ::NotificationMethod::Email->ntypeid, # Email
121 push @subs, LJ::Subscription->new_from_row($row);
122 $limit--;
125 push @subs, eval { $self->SUPER::subscriptions(cluster => $cid,
126 limit => $limit) };
128 return @subs;
131 sub _arg1_to_mlkey {
132 my $action = shift;
133 my @ml_actions = (
134 'account_deleted',
135 'account_activated',
136 'account_renamed',
139 return 'esn.security_attribute_changed.' . $ml_actions[$action-1] . '.';
142 sub as_alert {
143 my ($self, $u) = @_;
144 my $lang = $u->prop('browselang');
145 return LJ::Lang::get_text($lang, _arg1_to_mlkey($self->arg1) . 'alert',
146 undef,
148 'user' => $u->ljuser_display()
152 sub as_email_subject {
153 my ($self, $u) = @_;
154 my $lang = $u->prop('browselang');
155 return LJ::Lang::get_text($lang, _arg1_to_mlkey($self->arg1) . 'email_subject',
156 undef,
158 'user' => $u->{user}
162 sub _as_email {
163 my ($self, $u, $is_html) = @_;
165 my $lang = $u->prop('browselang');
166 my $action = $self->arg1;
167 my $logtime = $self->arg2;
169 my $_get_params_from_logtime = sub {
170 my ($u, $logtime) = @_;
172 # TODO: change this to use LJ::User::Userlog
173 my $userid = $u->{userid};
174 my $dbr = LJ::get_cluster_reader($u);
175 my ($datetime, $remoteid, $ip, $uniq) = $dbr->selectrow_array(
176 "SELECT FROM_UNIXTIME(logtime), remoteid, ip, uniq".
177 " FROM userlog".
178 " WHERE userid=$userid AND logtime=$logtime LIMIT 1");
179 return undef unless $remoteid;
180 return (
181 datetime => $datetime,
182 remoteid => $remoteid,
183 ip => $ip,
184 uniq => $uniq,
185 userid => $userid,
189 my $_get_params_from_rename_id = sub {
190 my ($u, $timechange_stamp) = @_;
191 my $userid = $u->{userid};
193 my $infohistory = LJ::User::InfoHistory->get( $u, 'username' );
194 my ($infohistory_record) =
195 grep { $_->timechange_unix == $timechange_stamp }
196 @$infohistory;
198 unless ($infohistory_record) {
199 croak "This event (uid=$userid, what=username) was not found in logs";
200 return undef;
203 my $old_name = $infohistory_record->oldvalue;
204 my $other = $infohistory_record->other;
206 # Convert $timechange from GMT to local for user
207 my $offset = 0;
208 LJ::get_timezone($u, \$offset);
209 my $timechange = LJ::TimeUtil->mysql_time($timechange_stamp + 60*60*$offset, 0);
211 $other =~ /ip=(.+)/;
212 my ($ip) = ($1);
214 return (
215 oldname => $old_name,
216 ip => $ip,
217 datetime => $timechange,
221 my @actions = (
222 $_get_params_from_logtime,
223 $_get_params_from_logtime,
224 $_get_params_from_rename_id,
227 my %logparams = $actions[$action-1]($u, $logtime);
229 if (%logparams && $logparams{datetime}) {
230 ($logparams{date}, $logparams{time}) = split(/ /, $logparams{datetime});
233 my $vars = {
234 'user' => $u->{user},
235 'username' => $u->{name},
236 'sitename' => $LJ::SITENAME,
237 'siteroot' => $LJ::SITEROOT,
238 %logparams,
241 return LJ::Lang::get_text($lang, _arg1_to_mlkey($action) . 'email_text', undef, $vars);
244 sub as_email_string {
245 my ($self, $u) = @_;
246 return '' unless $u;
247 return _as_email($self, $u, 0);
250 sub as_email_html {
251 my ($self, $u) = @_;
252 return '' unless $u;
253 return _as_email($self, $u, 1);