root/branches/release-36/lib/MT/Permission.pm @ 2099

Revision 2099, 26.8 kB (checked in by bchoate, 19 months ago)

Handle special case where user has excessive permission records. BugId:79501

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