[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
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
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 { --------------------------------------------------------------------------------