[dw-free] Add priv-checking option to DW::Controller::controller()
[commit: http://hg.dwscoalition.org/dw-free/rev/0d9755820438]
http://bugs.dwscoalition.org/show_bug.cgi?id=2407
Add privcheck mode to controller base, so TT pages can easily check for
privileges.
Patch by
pauamma.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=2407
Add privcheck mode to controller base, so TT pages can easily check for
privileges.
Patch by
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Files modified:
- cgi-bin/DW/Controller.pm
- cgi-bin/LJ/User.pm
-------------------------------------------------------------------------------- diff -r eec75d6d72ef -r 0d9755820438 cgi-bin/DW/Controller.pm --- a/cgi-bin/DW/Controller.pm Fri Apr 23 01:29:23 2010 +0000 +++ b/cgi-bin/DW/Controller.pm Fri Apr 23 01:34:39 2010 +0000 @@ -7,7 +7,7 @@ # Authors: # Mark Smith <mark@dreamwidth.org> # -# Copyright (c) 2009 by Dreamwidth Studios, LLC. +# Copyright (c) 2009-2010 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 @@ -55,6 +55,30 @@ sub success_ml { } # helper controller. give it a few arguments and it does nice things for you. +# +# Supported arguments: (1 stands for any true value, 0 for any false value) +# - anonymous => 1 -- lets anonymous (not logged in) visitors view the page +# - anonymous => 0 -- doesn't (default) +# - authas => 1 -- allows ?authas= in URL, generates authas form (not permitted +# if anonymous => 1 specified) +# - authas => 0 -- doesn't (default) +# - specify_user => 1 -- allows ?user= in URL (Note: requesting both authas and +# specify_user is allowed, but probably not a good idea) +# - specify_user => 0 -- doesn't (default) +# - privcheck => $privs -- user must be logged in and have at least one priv of +# the ones in this arrayref. +# Example: [ "faqedit:guides", "faqcat", "admin:*" ] +# +# Returns one of: +# - 0, $error_text (if there's an error) +# - 1, $hashref (if everything looks good) +# +# Returned hashref can be passed to DW::Template->render_template as the 2nd +# argument, and has the following keys: +# - remote -- the remote user object or undef (LJ::get_remote()) +# - u -- user object for username in ?user= or ?authas= if present and valid, +# otherwise same as remote +# - authas_html -- HTML for the "switch user" form sub controller { my ( %args ) = @_; @@ -62,8 +86,12 @@ sub controller { my $fail = sub { return ( 0, $_[0] ); }; my $ok = sub { return ( 1, $vars ); }; - # ensure the arguments make sense... anonymous means we cannot authas - delete $args{authas} if $args{anonymous}; + # some argument combinations are invalid, so just die. this is something that should + # be caught in development... + die "Invalid usage of controller, check your calling arguments.\n" + if ( $args{authas} && $args{specify_user} ) || + ( $args{authas} && $args{anonymous} ) || + ( $args{privcheck} && $args{anonymous} ); # 'anonymous' pages must declare themselves, else we assume that a remote is # necessary as most pages require a user @@ -89,6 +117,25 @@ sub controller { $vars->{authas_html} = LJ::make_authas_select( $vars->{remote}, { authas => $vars->{u}->user } ); } + # check user is suitably privved + if ( my $privs = $args{privcheck} ) { + # if they just gave us a string, throw it in an array + $privs = [ $privs ] unless ref $privs eq 'ARRAY'; + + # now iterate over the array and check. the user must have ANY + # of the privs to pass the test. + my $has_one = 0; + foreach my $priv ( @$privs ) { + last if $has_one = $vars->{remote}->has_priv( $priv ); + } + + # now if they have none, throw an error message + return $fail->( error_ml( 'admin.noprivserror', + { numprivs => scalar @$privs, + needprivs => join( ', ', sort @$privs ) } ) ) + unless $has_one; + } + # everything good... let the caller know they can continue return $ok->(); } diff -r eec75d6d72ef -r 0d9755820438 cgi-bin/LJ/User.pm --- a/cgi-bin/LJ/User.pm Fri Apr 23 01:29:23 2010 +0000 +++ b/cgi-bin/LJ/User.pm Fri Apr 23 01:34:39 2010 +0000 @@ -4974,6 +4974,16 @@ sub has_priv { sub has_priv { my ( $u, $priv, $arg ) = @_; + # check to see if the priv is packed, and unpack it if so, this allows + # someone to call $u->has_priv( "foo:*" ) instead of $u->has_priv( foo => '*' ) + # which is helpful for some callers. + ( $priv, $arg ) = ( $1, $2 ) + if $priv =~ /^(.+?):(.+)$/; + + # at this point, if they didn't provide us with a priv, bail out + return 0 unless $priv; + + # load what privileges the user has, if we haven't LJ::load_user_privs($u, $priv) unless $u->{'_privloaded'}->{$priv}; --------------------------------------------------------------------------------