diff --git a/lib/NGCP/Panel/Controller/Administrator.pm b/lib/NGCP/Panel/Controller/Administrator.pm index 2c9c31eaae..846aabccff 100644 --- a/lib/NGCP/Panel/Controller/Administrator.pm +++ b/lib/NGCP/Panel/Controller/Administrator.pm @@ -2,10 +2,11 @@ package NGCP::Panel::Controller::Administrator; use Sipwise::Base; use namespace::sweep; BEGIN { extends 'Catalyst::Controller'; } -use NGCP::Panel::Form::Administrator qw(); +use NGCP::Panel::Form::Administrator::Reseller; +use NGCP::Panel::Form::Administrator::Admin; use NGCP::Panel::Utils::Navigation; -sub auto :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) { +sub auto :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) :AllowedRole(reseller) { my ($self, $c) = @_; $c->log->debug(__PACKAGE__ . '::auto'); return 1; @@ -13,13 +14,45 @@ sub auto :Does(ACL) :ACLDetachTo('/denied_page') :AllowedRole(admin) { sub list_admin :PathPart('administrator') :Chained('/') :CaptureArgs(0) { my ($self, $c) = @_; + + my $dispatch_to = '_admin_resultset_' . $c->user->auth_realm; $c->stash( - admins => $c->model('DB')->resultset('admins'), + admins => $self->$dispatch_to($c), template => 'administrator/list.tt', ); + my $cols = [ + { name => "id", search => 1, title => "#" }, + ]; + if($c->user->is_superuser) { + @{ $cols } = (@{ $cols }, { name => "reseller.name", search => 1, title => "Reseller" }); + } + @{ $cols } = (@{ $cols }, + { name => "login", search => 1, title => "Login" }, + { name => "is_master", title => "Master" }, + { name => "is_active", title => "Active" }, + { name => "read_only", title => "Read Only" }, + { name => "show_passwords", title => "Show Passwords" }, + { name => "call_data", title => "Show CDRs" }, + ); + if($c->user->is_superuser) { + @{ $cols } = (@{ $cols }, { name => "lawful_intercept", title => "Lawful Intercept" }); + } + $c->stash->{admin_dt_columns} = NGCP::Panel::Utils::Datatables::set_columns($c, $cols); return; } +sub _admin_resultset_admin { + my ($self, $c) = @_; + return $c->model('DB')->resultset('admins'); +} + +sub _admin_resultset_reseller { + my ($self, $c) = @_; + return $c->model('DB')->resultset('admins')->search({ + reseller_id => $c->user->reseller_id, + }); +} + sub root :Chained('list_admin') :PathPart('') :Args(0) { my ($self, $c) = @_; return; @@ -28,13 +61,7 @@ sub root :Chained('list_admin') :PathPart('') :Args(0) { sub ajax :Chained('list_admin') :PathPart('ajax') :Args(0) { my ($self, $c) = @_; my $admins = $c->stash->{admins}; - $c->forward( - '/ajax_process_resultset', [ - $admins, - [qw(id login is_master is_active read_only show_passwords call_data lawful_intercept)], - [ qw(login) ] - ] - ); + NGCP::Panel::Utils::Datatables::process($c, $admins, $c->stash->{admin_dt_columns}); $c->detach($c->view('JSON')); return; } @@ -42,11 +69,16 @@ sub ajax :Chained('list_admin') :PathPart('ajax') :Args(0) { sub create :Chained('list_admin') :PathPart('create') :Args(0) { my ($self, $c) = @_; -# use Data::Printer; p $c->user; -# $c->detach('/denied_page') -# unless($c->user->{is_master}); + $c->detach('/denied_page') + unless($c->user->is_master); - my $form = NGCP::Panel::Form::Administrator->new; + my $form; + if($c->user->auth_realm eq "admin") { + $form = NGCP::Panel::Form::Administrator::Admin->new; + } else { + $form = NGCP::Panel::Form::Administrator::Reseller->new; + $c->request->params->{reseller}{id} = $c->user->reseller_id, + } $form->process( posted => $c->request->method eq 'POST', params => $c->request->params, @@ -59,12 +91,11 @@ sub create :Chained('list_admin') :PathPart('create') :Args(0) { back_uri => $c->uri_for('create') ); if ($form->validated) { - # TODO: check if reseller, and if so, auto-set contract; - # also, only show admins within reseller_id if reseller try { + $form->params->{reseller_id} = delete $form->params->{reseller}{id}; + delete $form->params->{reseller}; delete $form->params->{save}; - $form->params->{is_superuser} = 1; - $form->params->{reseller_id} = 1; + delete $form->params->{id}; $c->model('DB')->resultset('admins')->create($form->params); $c->flash(messages => [{type => 'success', text => 'Administrator created.'}]); } catch($e) { @@ -83,6 +114,10 @@ sub create :Chained('list_admin') :PathPart('create') :Args(0) { sub base :Chained('list_admin') :PathPart('') :CaptureArgs(1) { my ($self, $c, $administrator_id) = @_; + + $c->detach('/denied_page') + unless($c->user->is_master); + unless ($administrator_id && $administrator_id->is_integer) { $c->flash(messages => [{type => 'error', text => 'invalid administrator id'}]); $c->response->redirect($c->uri_for); @@ -94,9 +129,16 @@ sub base :Chained('list_admin') :PathPart('') :CaptureArgs(1) { sub edit :Chained('base') :PathPart('edit') :Args(0) { my ($self, $c) = @_; my $posted = $c->request->method eq 'POST'; - my $form = NGCP::Panel::Form::Administrator->new; - $c->stash->{administrator}->{'reseller.id'} = delete $c->stash->{administrator}->{reseller_id}; + my $form; + if($c->user->auth_realm eq "admin") { + $form = NGCP::Panel::Form::Administrator::Admin->new; + $c->stash->{administrator}->{reseller}{id} = + delete $c->stash->{administrator}->{reseller_id}; + } else { + $form = NGCP::Panel::Form::Administrator::Reseller->new; + } $form->field('md5pass')->{required} = 0; + $form->process( posted => 1, params => $posted ? $c->request->params : $c->stash->{administrator}, @@ -106,8 +148,17 @@ sub edit :Chained('base') :PathPart('edit') :Args(0) { if ($posted && $form->validated) { try { my $form_values = $form->value; + + # don't allow to take away own master rights, otherwise he'll not be + # able to manage any more admins + if($form_values->{id} == $c->user->id) { + delete $form_values->{is_master}; + delete $form_values->{is_active}; + } + # flatten nested hashref instead of recursive update - $form_values->{reseller_id} = delete $form_values->{reseller}{id}; + $form_values->{reseller_id} = delete $form_values->{reseller}{id} + if($form_values->{reseller}{id}); delete $form_values->{reseller}; delete $form_values->{md5pass} unless length $form_values->{md5pass}; $c->stash->{admins}->search_rs({ id => $form_values->{id} })->update_all($form_values); diff --git a/lib/NGCP/Panel/Form/Administrator/Admin.pm b/lib/NGCP/Panel/Form/Administrator/Admin.pm new file mode 100644 index 0000000000..280ef829aa --- /dev/null +++ b/lib/NGCP/Panel/Form/Administrator/Admin.pm @@ -0,0 +1,23 @@ +package NGCP::Panel::Form::Administrator::Admin; +use HTML::FormHandler::Moose; +use HTML::FormHandler::Widget::Block::Bootstrap; +use Moose::Util::TypeConstraints; +extends 'NGCP::Panel::Form::Administrator::Reseller'; + +for (qw(is_superuser lawful_intercept)) { + has_field $_ => (type => 'Boolean',); +} +has_field 'reseller' => ( + type => '+NGCP::Panel::Field::Reseller', + label => 'Reseller', + not_nullable => 1, +); +has_block 'fields' => ( + tag => 'div', + class => [qw(modal-body)], + render_list => [qw( + reseller login md5pass is_superuser is_master is_active read_only show_passwords call_data lawful_intercept + )], +); + +1; diff --git a/lib/NGCP/Panel/Form/Administrator.pm b/lib/NGCP/Panel/Form/Administrator/Reseller.pm similarity index 76% rename from lib/NGCP/Panel/Form/Administrator.pm rename to lib/NGCP/Panel/Form/Administrator/Reseller.pm index cf0096dd29..b455b35361 100644 --- a/lib/NGCP/Panel/Form/Administrator.pm +++ b/lib/NGCP/Panel/Form/Administrator/Reseller.pm @@ -1,4 +1,4 @@ -package NGCP::Panel::Form::Administrator; +package NGCP::Panel::Form::Administrator::Reseller; use HTML::FormHandler::Moose; use HTML::FormHandler::Widget::Block::Bootstrap; use Moose::Util::TypeConstraints; @@ -6,18 +6,12 @@ extends 'HTML::FormHandler'; has '+widget_wrapper' => (default => 'Bootstrap'); has_field 'id' => (type => 'Hidden'); -# has_field 'reseller_id' => (type => 'PosInteger', required => 1,); -has_field 'reseller' => ( - type => '+NGCP::Panel::Field::Reseller', - label => 'Reseller', - not_nullable => 1, -); has_field 'login' => (type => 'Text', required => 1,); has_field 'md5pass' => (type => 'Password', required => 1, label => 'Password'); for (qw(is_active show_passwords call_data)) { has_field $_ => (type => 'Boolean', default => 1); } -for (qw(is_master read_only lawful_intercept)) { +for (qw(is_master read_only)) { has_field $_ => (type => 'Boolean',); } has_field 'save' => (type => 'Submit', element_class => [qw(btn btn-primary)],); @@ -25,7 +19,7 @@ has_block 'fields' => ( tag => 'div', class => [qw(modal-body)], render_list => [qw( - login md5pass is_master is_active read_only show_passwords call_data lawful_intercept + login md5pass is_master is_active read_only show_passwords call_data )], ); has_block 'actions' => (tag => 'div', class => [qw(modal-footer)], render_list => [qw(save)],); diff --git a/share/templates/administrator/list.tt b/share/templates/administrator/list.tt index 09aaca76f3..4fe917a793 100644 --- a/share/templates/administrator/list.tt +++ b/share/templates/administrator/list.tt @@ -4,8 +4,7 @@ helper.show_create_button = 1; helper.data = admins; helper.messages = messages; - helper.column_titles = [ '#', 'Login', 'Master', 'Active', 'Read only', 'Show passwords', 'Call data', 'Lawful intercept' ]; - helper.column_fields = [ 'id', 'login', 'is_master', 'is_active', 'read_only', 'show_passwords', 'call_data', 'lawful_intercept' ]; + helper.dt_columns = admin_dt_columns; helper.close_target = close_target; helper.create_flag = create_flag; @@ -13,14 +12,17 @@ helper.form_object = form; helper.ajax_uri = c.uri_for( c.controller.action_for('ajax') ); - helper.dt_buttons = [ - { name = 'Edit', uri = "/administrator/'+full[\"id\"]+'/edit", class = 'btn-small btn-primary', icon = 'icon-edit' }, - { name = 'Delete', uri = "/administrator/'+full[\"id\"]+'/delete", class = 'btn-small btn-secondary', icon = 'icon-trash' }, - ]; - helper.top_buttons = [ - { name = 'Create Administrator', uri = c.uri_for('/administrator/create'), icon = 'icon-star' }, - ]; + IF c.user.is_master; + helper.dt_buttons = [ + { name = 'Edit', uri = "/administrator/'+full[\"id\"]+'/edit", class = 'btn-small btn-primary', icon = 'icon-edit' }, + { name = 'Delete', uri = "/administrator/'+full[\"id\"]+'/delete", class = 'btn-small btn-secondary', icon = 'icon-trash' }, + ]; + + helper.top_buttons = [ + { name = 'Create Administrator', uri = c.uri_for('/administrator/create'), icon = 'icon-star' }, + ]; + END; PROCESS 'helpers/datatables.tt'; -%] - +[% # vim: set tabstop=4 syntax=html expandtab: -%]