"Edit password" ACL, #21178, part 2
[freeside.git] / FS / FS / access_right.pm
1 package FS::access_right;
2
3 use strict;
4 use vars qw( @ISA );
5 use Tie::IxHash;
6 use FS::Record qw( qsearch qsearchs );
7 use FS::upgrade_journal;
8
9 @ISA = qw(FS::Record);
10
11 =head1 NAME
12
13 FS::access_right - Object methods for access_right records
14
15 =head1 SYNOPSIS
16
17   use FS::access_right;
18
19   $record = new FS::access_right \%hash;
20   $record = new FS::access_right { 'column' => 'value' };
21
22   $error = $record->insert;
23
24   $error = $new_record->replace($old_record);
25
26   $error = $record->delete;
27
28   $error = $record->check;
29
30 =head1 DESCRIPTION
31
32 An FS::access_right object represents a granted access right.  FS::access_right
33 inherits from FS::Record.  The following fields are currently supported:
34
35 =over 4
36
37 =item rightnum - primary key
38
39 =item righttype - 
40
41 =item rightobjnum - 
42
43 =item rightname - 
44
45
46 =back
47
48 =head1 METHODS
49
50 =over 4
51
52 =item new HASHREF
53
54 Creates a new right.  To add the right to the database, see L<"insert">.
55
56 Note that this stores the hash reference, not a distinct copy of the hash it
57 points to.  You can ask the object for a copy with the I<hash> method.
58
59 =cut
60
61 # the new method can be inherited from FS::Record, if a table method is defined
62
63 sub table { 'access_right'; }
64
65 =item insert
66
67 Adds this record to the database.  If there is an error, returns the error,
68 otherwise returns false.
69
70 =cut
71
72 # the insert method can be inherited from FS::Record
73
74 =item delete
75
76 Delete this record from the database.
77
78 =cut
79
80 # the delete method can be inherited from FS::Record
81
82 =item replace OLD_RECORD
83
84 Replaces the OLD_RECORD with this one in the database.  If there is an error,
85 returns the error, otherwise returns false.
86
87 =cut
88
89 # the replace method can be inherited from FS::Record
90
91 =item check
92
93 Checks all fields to make sure this is a valid right.  If there is
94 an error, returns the error, otherwise returns false.  Called by the insert
95 and replace methods.
96
97 =cut
98
99 # the check method should currently be supplied - FS::Record contains some
100 # data checking routines
101
102 sub check {
103   my $self = shift;
104
105   my $error = 
106     $self->ut_numbern('rightnum')
107     || $self->ut_text('righttype')
108     || $self->ut_text('rightobjnum')
109     || $self->ut_text('rightname')
110   ;
111   return $error if $error;
112
113   $self->SUPER::check;
114 }
115
116 # _upgrade_data
117 #
118 # Used by FS::Upgrade to migrate to a new database.
119
120 sub _upgrade_data { # class method
121   my ($class, %opts) = @_;
122
123   my @unmigrated = ( qsearch( 'access_right',
124                               { 'righttype'=>'FS::access_group',
125                                 'rightname'=>'Engineering configuration',
126                               }
127                             ), 
128                      qsearch( 'access_right',
129                               { 'righttype'=>'FS::access_group',
130                                 'rightname'=>'Engineering global configuration',
131                               }
132                             )
133                    ); 
134   foreach ( @unmigrated ) {
135     my $rightname = $_->rightname;
136     $rightname =~ s/Engineering/Dialup/;
137     $_->rightname($rightname);
138     my $error = $_->replace;
139     die "Failed to update access right: $error"
140       if $error;
141     my $broadband = new FS::access_right { $_->hash };
142     $rightname =~ s/Dialup/Broadband/;
143     $broadband->rightnum('');
144     $broadband->rightname($rightname);
145     $error = $broadband->insert;
146     die "Failed to insert access right: $error"
147       if $error;
148   }
149
150   my %migrate = (
151     'Post payment'    => [ 'Post check payment', 'Post cash payment' ],
152     'Process payment' => [ 'Process credit card payment', 'Process Echeck payment' ],
153     'Post refund'     => [ 'Post check refund', 'Post cash refund' ],
154     'Refund payment'  => [ 'Refund credit card payment', 'Refund Echeck payment' ],
155     'Regular void'    => [ 'Void payments' ],
156     'Unvoid'          => [ 'Unvoid payments', 'Unvoid invoices' ],
157   );
158
159   foreach my $oldright (keys %migrate) {
160     my @old = qsearch('access_right', { 'righttype'=>'FS::access_group',
161                                         'rightname'=>$oldright,
162                                       }
163                      );
164
165     foreach my $old ( @old ) {
166
167       foreach my $newright ( @{ $migrate{$oldright} } ) {
168         my %hash = (
169           'righttype'   => 'FS::access_group',
170           'rightobjnum' => $old->rightobjnum,
171           'rightname'   => $newright,
172         );
173         next if qsearchs('access_right', \%hash);
174         my $access_right = new FS::access_right \%hash;
175         my $error = $access_right->insert;
176         die $error if $error;
177       }
178
179       unless ( $oldright =~ / (payment|refund)$/ ) { #after the WEST stuff is sorted
180         my $error = $old->delete;
181         die $error if $error;
182       }
183
184     }
185
186   }
187
188   my @all_groups = qsearch('access_group', {});
189
190   tie my %onetime, 'Tie::IxHash',
191     'List customers'                      => 'List all customers',
192     'List all customers'                  => 'Advanced customer search',
193     'List packages'                       => 'Summarize packages',
194     'Post payment'                        => 'Backdate payment',
195     'Cancel customer package immediately' => 'Un-cancel customer package',
196     'Suspend customer package'            => 'Suspend customer',
197     'Unsuspend customer package'          => 'Unsuspend customer',
198     'New prospect'                        => 'Generate quotation',
199     'Delete invoices'                     => 'Void invoices',
200     'List invoices'                       => 'List quotations',
201     'Post credit'                         => 'Credit line items',
202     #'View customer tax exemptions'        => 'Edit customer tax exemptions',
203     'Edit customer'                       => 'Edit customer tax exemptions',
204     'Edit package definitions'            => 'Bulk edit package definitions',
205
206     'List services'    => [ 'Services: Accounts',
207                             'Services: Domains',
208                             'Services: Certificates',
209                             'Services: Mail forwards',
210                             'Services: Virtual hosting services',
211                             'Services: Wireless broadband services',
212                             'Services: DSLs',
213                             'Services: Dish services',
214                             'Services: Hardware',
215                             'Services: Phone numbers',
216                             'Services: PBXs',
217                             'Services: Ports',
218                             'Services: Mailing lists',
219                             'Services: External services',
220                           ],
221
222     'Services: Accounts' => 'Services: Accounts: Advanced search',
223     'Services: Wireless broadband services' => 'Services: Wireless broadband services: Advanced search',
224     'Services: Hardware' => 'Services: Hardware: Advanced search',
225     'Services: Phone numbers' => 'Services: Phone numbers: Advanced search',
226
227     'List rating data' => [ 'Usage: RADIUS sessions',
228                             'Usage: Call Detail Records (CDRs)',
229                             'Usage: Unrateable CDRs',
230                           ],
231     'Provision customer service' => [ 'Edit password' ],
232
233 ;
234
235   foreach my $old_acl ( keys %onetime ) {
236
237     my @new_acl = ref($onetime{$old_acl})
238                     ? @{ $onetime{$old_acl} }
239                     :  ( $onetime{$old_acl} );
240
241     foreach my $new_acl ( @new_acl ) {
242
243       ( my $journal = 'ACL_'.lc($new_acl) ) =~ s/\W/_/g;
244       next if FS::upgrade_journal->is_done($journal);
245
246       # grant $new_acl to all groups who have $old_acl
247       for my $group (@all_groups) {
248         next unless $group->access_right($old_acl);
249         next if     $group->access_right($new_acl);
250         my $access_right = FS::access_right->new( {
251             'righttype'   => 'FS::access_group',
252             'rightobjnum' => $group->groupnum,
253             'rightname'   => $new_acl,
254         } );
255         my $error = $access_right->insert;
256         die $error if $error;
257       }
258     
259       FS::upgrade_journal->set_done($journal);
260
261     }
262
263   }
264
265   ### ACL_download_report_data
266   if ( !FS::upgrade_journal->is_done('ACL_download_report_data') ) {
267
268     # grant to everyone
269     for my $group (@all_groups) {
270       my $access_right = FS::access_right->new( {
271           'righttype'   => 'FS::access_group',
272           'rightobjnum' => $group->groupnum,
273           'rightname'   => 'Download report data',
274       } );
275       my $error = $access_right->insert;
276       warn $error if $error;
277     }
278
279     FS::upgrade_journal->set_done('ACL_download_report_data');
280   }
281
282   '';
283
284 }
285
286 =back
287
288 =head1 BUGS
289
290 =head1 SEE ALSO
291
292 L<FS::Record>, schema.html from the base documentation.
293
294 =cut
295
296 1;
297