[dw-free] implement admin/impersonate.bml as dw-free
[commit: http://hg.dwscoalition.org/dw-free/rev/a81a6da8ecc1]
http://bugs.dwscoalition.org/show_bug.cgi?id=178
Add /admin/impersonate tool.
Patch by
afuna.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=178
Add /admin/impersonate tool.
Patch by
Files modified:
- cgi-bin/LJ/User.pm
- htdocs/admin/impersonate.bml
- htdocs/admin/impersonate.bml.text
- htdocs/admin/userlog.bml
--------------------------------------------------------------------------------
diff -r 4388e4653fad -r a81a6da8ecc1 cgi-bin/LJ/User.pm
--- a/cgi-bin/LJ/User.pm Sun Sep 06 18:04:56 2009 +0000
+++ b/cgi-bin/LJ/User.pm Sun Sep 06 18:21:55 2009 +0000
@@ -927,9 +927,12 @@ sub logout_all {
$u->_logout_common;
}
+sub make_fake_login_session {
+ return $_[0]->make_login_session( 'once', undef, 1 );
+}
sub make_login_session {
- my ($u, $exptype, $ipfixed) = @_;
+ my ( $u, $exptype, $ipfixed, $fake_login ) = @_;
$exptype ||= 'short';
return 0 unless $u;
@@ -940,15 +943,18 @@ sub make_login_session {
'exptype' => $exptype,
'ipfixed' => $ipfixed,
};
+ $sess_opts->{nolog} = 1 if $fake_login;
my $sess = LJ::Session->create($u, %$sess_opts);
$sess->update_master_cookie;
LJ::User->set_remote($u);
- # add a uniqmap row if we don't have one already
- my $uniq = LJ::UniqCookie->current_uniq;
- LJ::UniqCookie->save_mapping($uniq => $u);
+ unless ( $fake_login ) {
+ # add a uniqmap row if we don't have one already
+ my $uniq = LJ::UniqCookie->current_uniq;
+ LJ::UniqCookie->save_mapping($uniq => $u);
+ }
# restore scheme and language
my $bl = LJ::Lang::get_lang($u->prop('browselang'));
@@ -978,11 +984,13 @@ sub make_login_session {
"expiretime" => $etime,
});
- # activity for cluster usage tracking
- LJ::mark_user_active($u, 'login');
-
- # activity for global account number tracking
- $u->note_activity('A');
+ unless ( $fake_login ) {
+ # activity for cluster usage tracking
+ LJ::mark_user_active($u, 'login');
+
+ # activity for global account number tracking
+ $u->note_activity('A');
+ }
return 1;
}
diff -r 4388e4653fad -r a81a6da8ecc1 htdocs/admin/impersonate.bml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/admin/impersonate.bml Sun Sep 06 18:21:55 2009 +0000
@@ -0,0 +1,90 @@
+<?_c
+#
+# admin/impersonate.bml
+#
+# Allow someone trusted to log in as another user for a limited
+# amount of time.
+#
+# Authors:
+# Afuna <coder.dw@afunamatata.com>
+#
+# Copyright (c) 2009 by Dreamwidth Studios, LLC.
+#
+# This program is free software; you may redistribute it and/or modify it under
+# the same terms as Perl itself. For a copy of the license, please reference
+# 'perldoc perlartistic' or 'perldoc perlgpl'.
+#
+_c?><?page
+body<=
+<?_code
+{
+ use strict;
+ use vars qw/ %POST @errors /;
+
+ if ( $LJ::USE_SSL && !$LJ::IS_SSL ) {
+ return BML::redirect( "$LJ::SSLROOT/admin/impersonate" );
+ }
+
+ my $remote = LJ::get_remote();
+ return "<?needlogin?>" unless $remote;
+
+ my @displayprivs = ( "canview:*" );
+ my $numprivs = @displayprivs;
+
+ return BML::ml( "admin.noprivserror", { numprivs => $numprivs, needprivs => "<b>" . join( ", ", @displayprivs ) . "</b>" } )
+ unless $remote->has_priv( canview => '*' );
+
+ my $ret;
+
+ if ( LJ::did_post() && LJ::check_referer( '/admin/impersonate.bml' ) ) {
+ return LJ::error_list( $ML{'error.invalidform'} ) unless LJ::check_form_auth();
+
+ my $u = LJ::load_user( $POST{username} );
+ push @errors, BML::ml( '.error.invaliduser', { user => LJ::ehtml( $POST{username} ) } ) unless $u;
+
+ my $password = $POST{password};
+ push @errors, $ML{'.error.invalidpassword'} unless $password && $password eq $remote->password;
+
+ my $reason = LJ::ehtml( LJ::trim( $POST{reason} ) );
+ push @errors, $ML{'.error.emptyreason'} unless $reason;
+
+ $remote->logout;
+
+ if ( $u->make_fake_login_session ) {
+ # log for auditing
+ $remote->log_event( 'impersonator', { actiontarget => $u->id, remote => $remote, reason => $reason } );
+ $u->log_event( 'impersonated', { actiontarget => $u->id, remote => $remote, reason => $reason } );
+ LJ::statushistory_add( $u->id, $remote->id, 'impersonate', $reason );
+
+ return BML::redirect( $LJ::SITEROOT );
+
+ } else {
+ push @errors, $ML{'.error.failedlogin'};
+ }
+ }
+
+ $ret .= LJ::error_list( @errors ) if @errors;
+
+ $ret .= "<form method='POST'>";
+ $ret .= LJ::form_auth();
+
+ $ret .= LJ::labelfy( 'impersonate_username', $ML{'.form.username' } );
+ $ret .= LJ::html_text( { id => 'impersonate_username', name => 'username', maxlength => '25', size => '25', value => $POST{username} } ) . "<br />";
+
+ $ret .= LJ::labelfy( 'impersonate_password', $ML{'.form.password'} );
+ $ret .= LJ::html_text( { id => 'impersonate_password', name => 'password', type => 'password', size => '25' } ) . "<br />";
+
+ $ret .= LJ::labelfy( 'impersonate_reason', $ML{'.form.reason'} );
+ $ret .= LJ::html_text( { id => 'impersonate_reason', name => 'reason', maxlength => '255', size => '50', value => $POST{reason} } ) . "<br />";
+ $ret .= "<input type='submit' value='Submit' />";
+ $ret .= "</form>";
+
+ return $ret;
+}
+_code?>
+<=body
+title=><?_ml .title _ml?>
+head<=
+<?_code return $headextra; _code?>
+<=head
+page?>
diff -r 4388e4653fad -r a81a6da8ecc1 htdocs/admin/impersonate.bml.text
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/htdocs/admin/impersonate.bml.text Sun Sep 06 18:21:55 2009 +0000
@@ -0,0 +1,15 @@
+.error.emptyreason=A reason is required.
+
+.error.failedlogin=Attempt to impersonate failed.
+
+.error.invalidpassword=Password is incorrect.
+
+.error.invaliduser=Could not load user '[[user]]'.
+
+.form.password=Password:
+
+.form.reason=Reason:
+
+.form.username=Usename:
+
+.title=Impersonate
diff -r 4388e4653fad -r a81a6da8ecc1 htdocs/admin/userlog.bml
--- a/htdocs/admin/userlog.bml Sun Sep 06 18:04:56 2009 +0000
+++ b/htdocs/admin/userlog.bml Sun Sep 06 18:21:55 2009 +0000
@@ -109,6 +109,11 @@ FORM
# TODO: parse out e_unixtime and s_unixtime and display?
} elsif ($row->{action} eq 'delete_userpic') {
$action = "Deleted userpic #$extra->{picid}";
+ } elsif ( $row->{action} eq 'impersonated' ) {
+ $action = "Was impersonated: " . LJ::ehtml( $extra->{reason} );
+ } elsif ( $row->{action} eq 'impersonator' ) {
+ my $u = LJ::load_userid( $row->{actiontarget} );
+ $action = "Did impersonate on " . ( $u ? $u->ljuser_display : "(no target)" ) . ": " . LJ::ehtml( $extra->{reason} );
} elsif (my $info = LJ::run_hook('userlog_rows', $row)) {
$action = $info;
} else {
--------------------------------------------------------------------------------
