root/trunk/lib/MT/Permission.pm @ 3082

Revision 3082, 27.5 kB (checked in by bchoate, 14 months ago)

Merging fireball branch changes to-date to trunk: svn merge -r2974:3081 http://code.sixapart.com/svn/movabletype/branches/fireball .

  • Property svn:keywords set to Author Date Id Revision
Line 
1# Movable Type (r) Open Source (C) 2001-2008 Six Apart, Ltd.
2# This program is distributed under the terms of the
3# GNU General Public License, version 2.
4#
5# $Id$
6
7package MT::Permission;
8
9use strict;
10
11use MT::Blog;
12use MT::Object;
13@MT::Permission::ISA = qw(MT::Object);
14
15__PACKAGE__->install_properties(
16    {
17        column_defs => {
18            'id'        => 'integer not null auto_increment',
19            'author_id' => 'integer not null',
20            'blog_id'   => 'integer not null',
21            'role_mask' => 'integer',
22
23            # These were only declared for MTE 1.5x; dropping them
24            # has no ill effect since they were never actually used.
25            # 'role_mask2'      => 'integer',  # for upgrades...
26            # 'role_mask3'      => 'integer',
27            # 'role_mask4'      => 'integer',
28            'permissions'    => 'text',
29            'entry_prefs'    => 'text',
30            'blog_prefs'     => 'string(255)',
31            'template_prefs' => 'string(255)',
32            'restrictions'   => 'text',
33        },
34        child_of => 'MT::Blog',
35        indexes  => {
36            blog_id   => 1,
37            author_id => 1,
38            role_mask => 1,
39        },
40        defaults => {
41            author_id => 0,
42            blog_id   => 0,
43            role_mask => 0,
44        },
45        audit       => 1,
46        datasource  => 'permission',
47        primary_key => 'id',
48    }
49);
50
51sub class_label {
52    MT->translate("Permission");
53}
54
55sub class_label_plural {
56    MT->translate("Permissions");
57}
58
59
60sub user {
61    my $perm = shift;
62
63    #xxx Beware of circular references
64    return undef unless $perm->author_id;
65    $perm->cache_property(
66        'user',
67        sub {
68            require MT::Author;
69            MT::Author->load( $perm->author_id );
70        }
71    );
72}
73*author = *user;
74
75sub blog {
76    my $perm = shift;
77    return undef unless $perm->blog_id;
78    $perm->cache_property(
79        'blog',
80        sub {
81            require MT::Blog;
82            MT::Blog->load( $perm->blog_id );
83        }
84    );
85}
86
87sub global_perms {
88    my $perm = shift;
89
90    return undef unless $perm->author_id;
91    return $perm unless $perm->blog_id;
92
93    $perm->cache_property(
94        'global_perms',
95        sub {
96            __PACKAGE__->load( { author_id => $perm->author_id, blog_id => 0 });
97        }
98    );
99}
100
101# Legend:
102# author_id || blog_id || permissions
103#    N      ||    0    || System level privilege
104#    N      ||    N    || Author's Weblog level permissions
105#    0      ||    N    || Weblog default preferences of Entry Display (TBRemoved)
106#    0      ||    0    || !!BUG!!
107# Permissions are stored in database like 'Perm1','Perm_2','Pe_rm_3'.
108{
109    my @Perms;
110
111    sub init_permissions {
112        my $pkg = shift;
113        $pkg->perms() unless @Perms;
114    }
115
116    sub _all_perms {
117        my ($scope) = @_;
118        my @perms;
119        if ( my $perms = MT->registry("permissions") ) {
120            foreach my $p (%$perms) {
121                my ( $s, $name ) = split /\./, $p;
122                next unless $s && $name;
123                next unless $s eq $scope;
124                push @perms, "'$name'";
125            }
126        }
127        return join ',', @perms;
128    }
129
130    sub add_permissions {
131        my $perms = shift;
132
133        # This parameter can be any MT::Object that provides the
134        # permission field. So it works with MT::Permission and MT::Role.
135        my ($more_perm) = @_;
136        if ( my $more = $more_perm->permissions ) {
137            if ( $more =~ /'administer_blog'/ ) {
138                $more = _all_perms('blog');
139            }
140            my $cur_perm = $perms->permissions;
141            my @newperms;
142            for my $p ( split ',', $more ) {
143                $p =~ s/'(.+)'/$1/;
144                next if $perms->has($p);
145                push @newperms, $p;
146            }
147            return unless @newperms;
148            my $newperm = "'" . join( "','", @newperms ) . "'";
149            $newperm = "$cur_perm,$newperm" if $cur_perm;
150            $perms->permissions($newperm);
151        }
152    }
153
154    sub add_restrictions {
155        my $perms = shift;
156        my ($more_perm) = @_;
157        if ( my $more = $more_perm->restrictions ) {
158            if ( $more =~ /'administer_blog'/ ) {
159                $more = _all_perms('blog');
160            }
161            my $cur_perm = $perms->restrictions;
162            my @newperms;
163            for my $p ( split ',', $more ) {
164                $p =~ s/'(.+)'/$1/;
165                next if $perms->has($p);
166                push @newperms, $p;
167            }
168            return unless @newperms;
169            my $newperm = "'" . join( "','", @newperms ) . "'";
170            $newperm = "$cur_perm,$newperm" if $cur_perm;
171            $perms->restrictions($newperm);
172        }
173    }
174
175    # Sets permissions of those in a particular set
176    sub set_full_permissions {
177        my $perms = shift;
178        $perms->set_permissions('blog');
179    }
180
181    sub set_permissions {
182        my $perms = shift;
183        __PACKAGE__->_set_these( $perms, 'permissions', @_ );
184    }
185
186    sub set_restrictions {
187        my $perms = shift;
188        __PACKAGE__->_set_these( $perms, 'restrictions', @_ );
189    }
190
191    sub _set_these {
192        my $pkg   = shift;
193        my $perms = shift;
194        my ( $column, $set ) = @_;
195        my @permissions;
196        for my $ref ( @{ perms() } ) {
197            next if $set && ( $set ne '*' ) && ( $ref->[2] ne $set );
198            push @permissions, $ref->[0];
199        }
200        $perms->$column( "'" . join( "','", @permissions ) . "'" );
201    }
202
203    sub remove_restrictions {
204        my $perms    = shift;
205        my (@perms)  = @_;
206        my $cur_rest = $perms->restrictions;
207        return unless $cur_rest;
208        for my $perm_name (@perms) {
209            $cur_rest =~ s/'$perm_name',?//i;
210        }
211        $perms->restrictions($cur_rest);
212    }
213
214    # Clears all permissions or those in a particular set
215    sub clear_full_permissions {
216        my $perms = shift;
217        $perms->clear_permissions('blog');
218    }
219
220    sub clear_permissions {
221        my $perms = shift;
222        __PACKAGE__->_clear_these( $perms, 'permissions', @_ );
223    }
224
225    sub clear_restrictions {
226        my $perms = shift;
227        __PACKAGE__->_clear_these( $perms, 'restrictions', @_ );
228    }
229
230    sub _clear_these {
231        my $pkg   = shift;
232        my $perms = shift;
233        my ( $column, $set ) = @_;
234        my $cur_perm = $perms->$column;
235        return unless $cur_perm;
236        for my $ref ( @{ perms() } ) {
237            next if $set && ( $set ne '*' ) && ( $ref->[2] ne $set );
238            my $perm_name = $ref->[0];
239            $cur_perm =~ s/'$perm_name',?//i;
240        }
241        $perms->$column($cur_perm);
242    }
243
244    sub perms {
245        my $pkg = shift;
246        unless (@Perms) {
247            if ( my $perms = MT->registry("permissions") ) {
248                foreach my $pk (%$perms) {
249                    my ( $scope, $name ) = split /\./, $pk;
250                    next unless $scope && $name;
251                    my $label =
252                      'CODE' eq ref( $perms->{$pk}{label} )
253                      ? $perms->{$pk}{label}->()
254                      : $perms->{$pk}{label};
255                    push @Perms, [ $name, $label || '', $scope ];
256                }
257                __mk_perm($_) foreach @Perms;
258            }
259        }
260        if (@_) {
261            my $set = shift;
262            my @perms = grep { $_->[2] eq $set } @Perms;
263            \@perms;
264        }
265        else {
266            \@Perms;
267        }
268    }
269
270    my %Perms;
271
272    sub __mk_perm {
273        no strict 'refs';
274        my $ref  = shift;
275        my $meth = 'can_' . $ref->[0];
276
277        $Perms{ $ref->[0] } = $ref;
278        my $set = $ref->[2];
279
280        return if defined *$meth;
281
282        *$meth = sub {
283            my $cur_perm = $_[0]->permissions;
284            return undef if !$cur_perm && ( @_ < 2 );
285            my $perm = substr $meth, 4;    #remove 'can_'
286            if ( @_ == 2 ) {
287                if ( $_[1] ) {
288                    return 1 if $_[0]->has($perm);
289                    $cur_perm .= ',' if $cur_perm;
290                    $cur_perm .= "'$perm'";
291                }
292                else {
293
294                    # arg == 0 - remove it
295                    $cur_perm =~ s/'$perm',?// if defined $cur_perm;
296                }
297                $_[0]->permissions($cur_perm);
298            }
299            else {
300                if ( my $author = $_[0]->author ) {
301                    return 1
302                      if ( ( $meth ne 'can_administer' )
303                        && $author->is_superuser );
304                    return 1
305                      if ( ( $_[0]->blog_id )
306                        && $_[0]->has('administer_blog') );
307                }
308            }
309            # return negative if a restriction is present
310            return undef
311              if $_[0]->restrictions && $_[0]->restrictions =~ /'$perm'/i;
312            # return positive if permission is set in this permission set
313            return 1 if defined($cur_perm) && $cur_perm =~ /'$perm'/i;
314            # test for global-level permission
315            return 1
316              if $_[0]->author_id
317              && $_[0]->blog_id
318              && $_[0]->global_perms
319              && $_[0]->global_perms->has($perm);
320            return undef;
321        };
322    }
323
324    sub set_these_permissions {
325        my $perms = shift;
326        __PACKAGE__->_set_these_list( $perms, 'permissions', @_ );
327    }
328
329    sub set_these_restrictions {
330        my $perms = shift;
331        __PACKAGE__->_set_these_list( $perms, 'restrictions', @_ );
332    }
333
334    sub _set_these_list {
335        my $pkg   = shift;
336        my $perms = shift;
337        my ( $column, @list ) = @_;
338        if ( ( ref $list[0] ) eq 'ARRAY' ) {
339            @list = @{ $list[0] };
340        }
341        foreach (@list) {
342            my $ref = $Perms{$_};
343            die "invalid permission" unless $ref;
344            next if $pkg->_check_if($perms, $column, $_);
345            my $val = $perms->$column || '';
346            $val .= ',' if $val ne '';
347            $val .= "'" . $ref->[0] . "'";
348            $perms->$column($val);
349        }
350    }
351
352    sub add_permission {
353        my $pkg = shift;
354        my ($perm) = @_;
355        if ( ref $perm eq 'HASH' ) {
356            return unless $perm->{key} && $perm->{set};
357            my $ref = [ $perm->{key}, $perm->{label} || '', $perm->{set} ];
358            push @Perms, $ref;
359            __mk_perm($ref);
360        }
361        elsif ( ref $perm eq 'ARRAY' ) {
362            push @Perms, $perm;
363            __mk_perm($perm);
364        }
365    }
366
367    # $perm->has() and $perm->is_restricted skips any fancy logic,
368    # returning true or false depending only on whether the bit is
369    # set in this record.
370    sub has {
371        my $this = shift;
372        __PACKAGE__->_check_if( $this, 'permissions', @_ );
373    }
374
375    sub is_restricted {
376        my $this = shift;
377        __PACKAGE__->_check_if( $this, 'restrictions', @_ );
378    }
379
380    sub _check_if {
381        my $pkg  = shift;
382        my $this = shift;
383        my ( $column, $perm_name ) = @_;
384        my $cur_perm = $this->$column;
385        return 0 unless $cur_perm;
386        my $r = ( $cur_perm =~ /'$perm_name'/i ) ? 1 : 0;
387        return $r;
388    }
389}
390
391sub can_post {
392    my $perms = shift;
393    if ( my ($val) = @_ ) {
394        $perms->can_create_post($val);
395        $perms->can_publish_post($val);
396        return $val;
397    }
398    $perms->can_create_post && $perms->can_publish_post;
399}
400
401sub can_edit_authors {
402    my $perms  = shift;
403    my $author = $perms->user;
404    $perms->can_administer_blog || ( $author && $author->is_superuser() );
405}
406
407sub can_edit_entry {
408    my $perms = shift;
409    my ( $entry, $author, $status ) = @_;
410    die unless $author->isa('MT::Author');
411    return 1 if $author->is_superuser();
412    unless ( ref $entry ) {
413        require MT::Entry;
414        $entry = MT::Entry->load($entry)
415            or die;
416    }
417    die unless $entry->isa('MT::Entry');
418    if ( 'page' eq $entry->class ) {
419        return $perms->can_manage_pages;
420    }
421    return $perms->can_edit_all_posts
422      || (
423        defined $status
424        ? ( $perms->can_publish_post && $entry->author_id == $author->id )
425        : ( $perms->can_create_post && $entry->author_id == $author->id )
426      );
427}
428
429sub can_upload {
430    my $perms = shift;
431    if (@_) {
432        if (my $can = shift) {
433            $perms->set_these_permissions('upload');
434        } else {
435            $perms->clear_permissions('upload');
436        }
437    }
438    return $perms->can_edit_assets || $perms->has('upload');
439}
440
441sub can_view_feedback {
442    my $perms = shift;
443         $perms->can_edit_all_posts
444      || $perms->can_create_post
445      || $perms->can_publish_post
446      || $perms->can_manage_feedback;
447}
448
449sub is_empty {
450    my $perms = shift;
451    !( defined( $perms->permissions ) && $perms->permissions );
452}
453
454sub _static_rebuild {
455    my $pkg = shift;
456    my ($obj) = @_;
457
458    if ( $obj->isa('MT::Association') ) {
459        my $assoc = $obj;
460        if ( $assoc->role_id && $assoc->blog_id ) {
461            if ( $assoc->group_id ) {
462                my $grp = $assoc->group or return;
463                my $iter = $grp->user_iter;
464                while ( my $user = $iter->() ) {
465                    my $perm = MT::Permission->get_by_key(
466                        {
467                            author_id => $user->id,
468                            blog_id   => $assoc->blog_id
469                        }
470                    );
471                    $perm->rebuild;
472                }
473            }
474            elsif ( $assoc->author_id ) {
475                my $user = $assoc->user or return;
476                my $perm = MT::Permission->get_by_key(
477                    {
478                        author_id => $user->id,
479                        blog_id   => $assoc->blog_id
480                    }
481                );
482                $perm->rebuild;
483            }
484        }
485        elsif ( $assoc->author_id && $assoc->group_id ) {
486
487            # rebuild permissions for author
488            my $grp = $assoc->group or return;
489            my $blog_iter = $grp->blog_iter;
490            my @blogs;
491            if ($blog_iter) {
492                while ( my $blog = $blog_iter->() ) {
493                    push @blogs, $blog->id;
494                }
495            }
496            if (@blogs) {
497                foreach my $blog_id (@blogs) {
498                    my $perm = MT::Permission->get_by_key(
499                        {
500                            author_id => $assoc->author_id,
501                            blog_id   => $blog_id,
502                        }
503                    );
504                    $perm->rebuild;
505                }
506            }
507        }
508    }
509    1;
510}
511
512sub rebuild {
513    my $perm = shift;
514    if ( !ref $perm ) {
515        return $perm->_static_rebuild(@_);
516    }
517
518    # rebuild permissions for this user / blog
519    my $user_id = $perm->author_id;
520    my $blog_id = $perm->blog_id;
521
522    return unless $user_id && $blog_id;
523
524    # clean slate
525    $perm->clear_full_permissions;
526    my $has_permissions = 0;
527
528    # find all blogs for this user
529    my $user = MT::Author->load($user_id) or return;
530
531    my $role_iter = $user->role_iter( { blog_id => $blog_id } );
532    if ($role_iter) {
533        while ( my $role = $role_iter->() ) {
534            $perm->add_permissions($role);
535            $has_permissions = 1;
536        }
537    }
538
539    # find all blogs for this user through groups
540    $role_iter = $user->group_role_iter( { blog_id => $blog_id } );
541    if ($role_iter) {
542        while ( my $role = $role_iter->() ) {
543            $perm->add_permissions($role);
544            $has_permissions = 1;
545        }
546    }
547
548    if ($has_permissions) {
549        $perm->save;
550    }
551    else {
552        $perm->remove if $perm->id;
553    }
554}
555
556sub load_same {
557    my $pkg = shift;
558    my ( $terms, $args, $exact, @list ) = @_;
559    if ( ( ref $list[0] ) eq 'ARRAY' ) {
560        @list = @{ $list[0] };
561    }
562    foreach (@list) {
563        $_ =~ s/^([^'].+[^'])$/'$1'/;
564    }
565
566    my %terms = map { $_ => $terms->{$_} } keys %$terms;
567    my %args  = map { $_ => $args->{$_} } keys %$args;
568    $args{like} = { 'permissions' => 1 };
569    my @ids;
570    my @roles = ();
571    for my $key (@list) {
572        $terms{permissions} = "%" . $key . "%";
573        $terms{id} = \@ids if scalar(@ids);
574
575        my @tmp_roles = $pkg->load( \%terms, \%args );
576        unless ( scalar @tmp_roles ) {
577            @roles = ();
578            last;
579        }
580        delete $args{not};    # not is used only the first time
581        @ids = map { $_->id } @tmp_roles;
582        @roles = @tmp_roles;
583    }
584    return ( wantarray ? () : undef ) unless scalar(@roles);
585    if ($exact) {
586        my $base_len = length( join( ',', @list ) );
587        @roles = grep { length( $_->permissions ) == $base_len } @roles;
588    }
589    return wantarray ? @roles : ( ( scalar @roles ) ? $roles[0] : undef );
590}
591
592sub to_hash {
593    my $perms     = shift;
594    my $hash      = {};                        # $perms->SUPER::to_hash(@_);
595    my $all_perms = MT::Permission->perms();
596    foreach (@$all_perms) {
597        my $perm = $_->[0];
598        $perm = 'can_' . $perm;
599        $hash->{"permission.$perm"} = $perms->$perm();
600    }
601    $hash;
602}
603
6041;
605__END__
606
607=head1 NAME
608
609MT::Permission - Movable Type permissions record
610
611=head1 SYNOPSIS
612
613    use MT::Permission;
614    my $perms = MT::Permission->load({ blog_id => $blog->id,
615                                       author_id => $author->id })
616        or die "User has no permissions for blog";
617    $perms->can_create_post
618        or die "User cannot publish to blog";
619
620    $perms->can_edit_config(0);
621    $perms->save
622        or die $perms->errstr;
623
624=head1 DESCRIPTION
625
626An I<MT::Permission> object represents the permissions settings for a user
627in a particular blog. Permissions are set on a role basis, and each permission
628is either on or off for an user-blog combination; permissions are stored as
629a bitmask.
630
631Note: The I<MT::Permission> object is not meant to be modified or created
632directly. Permissions should be assigned to users through role associations,
633or through MT::Author's can_xxx methods for system level privileges.
634The I<MT::Permission> object is actually managed by Movable Type purely, and
635is a flattened view of all the permissions a particular user has for a single
636blog.  Users' system level privileges are also stored in MT::Permission record
637with blog_id = 0.
638
639=head1 USAGE
640
641As a subclass of I<MT::Object>, I<MT::Permission> inherits all of the
642data-management and -storage methods from that class; thus you should look
643at the I<MT::Object> documentation for details about creating a new object,
644loading an existing object, saving an object, etc.
645
646The following methods are unique to the I<MT::Permission> interface. Each of
647these methods, B<except> for I<set_full_permissions>, can be called with an
648optional argument to turn the permission on or off. If the argument is some
649true value, the permission is enabled; otherwise, the permission is disabled.
650If no argument is provided at all, the existing permission setting is
651returned.
652
653=head2 MT::Permission->perms( [ $set ] )
654
655Returns an array reference containing the list of available permissions. The
656array is a list of permissions, each of which is an array reference with
657the following items:
658
659    [ key, label, set ]
660
661The 'key' element is the value of that permission and is also a unique
662identifier that is used to identify the permission. Declared permissions
663may be tested through a 'can' method that is added to the MT::Permission
664namespace when registering them. So if you register with a 'key' value
665of 'foo', this creates a method 'can_foo', which may be tested for like this:
666
667    my $perm = $app->permissions;
668    if ($perm->can_foo) {
669        $app->foo;
670    }
671
672The 'label' element is a phrase that identifies the permission.
673
674The 'set' element identifies which group or category of permissions the
675permission is associated with. Currently, there are two sets of
676permissions: 'blog' and 'system'.
677
678If you call the perms method with the $set parameter, it will only return
679permissions declared with that 'set' identifier.
680
681=head2 MT::Permission->add_permission( \%perm )
682
683=head2 MT::Permission->add_permission( \@perm )
684
685Both of these methods can be used to register a new permission with
686Movable Type.
687
688Note: It is not advisable to call these method to register custom permissions
689without having preregistered for one from Six Apart, Ltd. This will
690reserve your permission and allow it to coexist with other plugins and
691future permissions defined by Movable Type itself.
692
693When calling add_permission with a hashref, you should specify these
694elements in the hash:
695
696=over 4
697
698=item * key
699
700=item * label
701
702=item * set
703
704=back
705
706See the 'perms' method documentation for more information on these
707elements.
708
709If calling the add_permission method with an arrayref, you should
710specify the elements of the array in the same order as given by
711the 'perms' method. You may only register one permission per call
712to the add_permission method.
713
714=head2 $perms->set_full_permissions()
715
716Turns on all blog-level permissions.
717
718=head2 $perms->clear_full_permissions()
719
720Turns off all permissions.
721
722=head2 $perms->set_permissions($set)
723
724Sets all permissions identified by the group C<$set> (use '*' to include
725all permissions regardless of grouping).
726
727=head2 $perms->clear_permissions($set)
728
729Clears all permissions identified by the group C<$set> (use '*' to include
730all permissions regardless of grouping).
731
732=head2 $perms->add_permissions($more_perms)
733
734Adds C<$more_perms> to C<$perms>.
735
736=head2 $perms->set_these_permissions(@permission_names)
737
738Adds permissions (enabling them) to the existing permission object.
739
740    $perms->set_these_permissions('view_blog_log', 'create_post');
741
742=head2 MT::Permission->rebuild($assoc)
743
744Rebuilds permission objects affected by the given L<MT::Association> object.
745
746=head2 $perms->rebuild()
747
748Rebuilds the single permission object based on the user/group/role/blog
749relationships that can be found for the author and blog tied to the
750permission.
751
752=head2 $perms->has($permission_name)
753
754Returns true or false depending only on whether the bit identified by
755C<$permission_name> is set in this permission object.
756
757=head2 $perms->can_administer_blog
758
759Returns true if the user can administer the blog. This is a blog-level
760"superuser" capability.
761
762=head2 $perms->can_create_post
763
764Returns true if the user can post to the blog , and edit the entries that
765he/she has posted; false otherwise.
766
767=head2 $perms->can_publish_post
768
769Returns true if the user can publish his/her post; false otherwise.
770
771=head2 $perms->can_post
772
773(Backward compatibility API) Returns true if the user can post to the blog,
774and edit the entries that he/she has posted and publish the post; false otherwise.
775
776=head2 $perms->can_upload
777
778Returns true if the user can upload files to the blog directories specified
779for this blog, false otherwise.
780
781=head2 $perms->can_edit_all_posts
782
783Returns true if the user can edit B<all> entries posted to this blog (even
784entries that he/she did not write), false otherwise.
785
786=head2 $perms->can_edit_templates
787
788Returns true if the user can edit the blog's templates, false otherwise.
789
790=head2 $perms->can_send_notifications
791
792Returns true if the user can send messages to the notification list, false
793otherwise.
794
795=head2 $perms->can_edit_categories
796
797Returns true if the user can edit the categories defined for the blog, false
798otherwise.
799
800=head2 $perms->can_edit_tags
801
802Returns true if the user can edit the tags defined for the blog, false
803otherwise.
804
805=head2 $perms->can_edit_notifications
806
807Returns true if the user can edit the notification list for the blog, false
808otherwise.
809
810=head2 $perms->can_view_blog_log
811
812Returns true if the user can view the activity log for the blog, false
813otherwise.
814
815=head2 $perms->can_rebuild
816
817Returns true if the user can edit the rebuild the blog, false otherwise.
818
819=head2 $perms->can_edit_config
820
821Returns true if the user can edit the blog configuration, false otherwise.
822
823(Backward compatibility warning) can_edit_config no longer means the user
824can set and modify publishing paths (site_path, site_url, archive_path and
825archive_url) for the weblog.  Use can_set_publish_paths.
826
827=head2 $perms->can_set_publish_paths
828
829Returns true if the user can set publishing paths, false otherwise.
830
831=head2 $perms->can_edit_authors()
832
833Returns true if the 'administer_blog' permission is set or the associated
834author has superuser rights.
835
836=head2 $perms->can_edit_entry($entry, $author)
837
838Returns true if the C<$author> has rights to edit entry C<$entry>. This
839is always true if C<$author> is a superuser or can edit all posts or
840is a blog administrator for the blog that contains the entry. Otherwise,
841it returns true if the author has permission to post and the entry was
842authored by that author, false otherwise.
843
844The C<$entry> parameter can either be a I<MT::Entry> object or an entry id.
845
846=head2 $perms->can_manage_feedback
847
848Returns true if the C<$author> has rights to manage feedbacks (comments
849and trackbacks) as well as IP ban list.
850
851=head2 $perms->can_view_feedback
852
853TODO Returns true if permission indicates the user can list comments and trackbacks.
854
855=head2 $perms->can_administer
856
857Returns true if the user in question is a system administrator, false otherwise.
858
859=head2 $perms->can_view_log
860
861Returns true if the user can view system level activity log, false otherwise.
862
863=head2 $perms->can_create_blog
864
865Returns true if the user can create a new weblog, false otherwise.
866
867=head2 $perms->can_manage_plugins
868
869Returns true if the user can enable/disable, and configure plugins in system level,
870false otherwise.
871
872=head2 $perms->can_not_comment
873
874Returns true if the user has been banned from commenting on the blog.
875This permission is used for authenticated commenters.
876
877=head2 $perms->can_comment
878
879Returns true if the user has been approved for commenting on the blog.
880This permission is used for authenticated commenters.
881
882=head2 $perms->blog
883
884Returns the I<MT::Blog> object for this permission object.
885
886=head2 $perms->user
887
888=head2 $perms->author
889
890Returns the I<MT::Author> object for this permission object. The C<author>
891method is deprecated in favor of C<user>.
892
893=head2 $perms->to_hash
894
895Returns a hashref that represents the contents of the permission object.
896Elements are in the form of (enabled permissions are set, disabled
897permissions are set to 0):
898
899    { 'permission.can_edit_templates' => 16,
900      'permission.can_rebuild' => 0,
901      # ....
902      'permission.can_create_post' => 2 }
903
904=head2 $class->load_same($terms, $args, $exact, @list)
905
906Returns an array or an object depending on context, of permission records
907which have specified list of permissions.  If $exact is set to True, permission
908records which have exact match to the list are returned.  $terms and $args
909can be used to further narrow down results.
910
911=head1 DATA ACCESS METHODS
912
913The I<MT::Comment> object holds the following pieces of data. These fields can
914be accessed and set using the standard data access methods described in the
915I<MT::Object> documentation.
916
917=over 4
918
919=item * id
920
921The numeric ID of this permissions record.
922
923=item * author_id
924
925The numeric ID of the user associated with this permissions record.
926
927=item * blog_id
928
929The numeric ID of the blog associated with this permissions record.
930
931=item * role_mask
932
933=item * role_mask2
934
935=item * role_mask3
936
937=item * role_mask4
938
939These bitmask fields are deprecated in favor of text based permissions
940column.
941
942=item * permissions
943
944Permissions are stored in this column like 'Perm1','Perm_2','Pe_rm_3'.
945
946=item * entry_prefs
947
948The setting of display fields of "edit entry" page.  The value
949at author_id 0 means default setting of a blog.
950
951=item * template_prefs
952
953The setting of display  "edit template" page.  The value
954at author_id 0 means default setting of a blog.
955
956=back
957
958=head1 DATA LOOKUP
959
960In addition to numeric ID lookup, you can look up or sort records by any
961combination of the following fields. See the I<load> documentation in
962I<MT::Object> for more information.
963
964=over 4
965
966=item * blog_id
967
968=item * author_id
969
970=back
971
972=head1 AUTHOR & COPYRIGHTS
973
974Please see the I<MT> manpage for user, copyright, and license information.
975
976=cut
Note: See TracBrowser for help on using the browser.