Introduced IP based access control for groups.
authorNik Okuntseff <support@anuko.com>
Fri, 30 Mar 2018 20:07:13 +0000 (20:07 +0000)
committerNik Okuntseff <support@anuko.com>
Fri, 30 Mar 2018 20:07:13 +0000 (20:07 +0000)
WEB-INF/lib/common.lib.php
WEB-INF/lib/ttRoleHelper.class.php
WEB-INF/lib/ttTeamHelper.class.php
WEB-INF/lib/ttUser.class.php
WEB-INF/resources/en.lang.php
WEB-INF/templates/footer.tpl
WEB-INF/templates/group_edit.tpl
dbinstall.php
group_edit.php
mysql.sql

index 7086fe2..210ec41 100644 (file)
@@ -339,6 +339,21 @@ function ttAccessAllowed($required_right)
     exit();
   }
 
+  // Check IP restriction, if set.
+  if ($user->allow_ip && !$user->can('override_allow_ip')) {
+    $access_allowed = false;
+    $user_ip = $_SERVER['REMOTE_ADDR'];
+    $allowed_ip_array = explode(',', $user->allow_ip);
+    foreach ($allowed_ip_array as $allowed_ip) {
+      $len = strlen($allowed_ip);
+      if (substr($user_ip, 0, $len) === $allowed_ip) {
+         $access_allowed = true;
+         break;
+      }
+    }
+    if (!$access_allowed) return false;
+  }
+
   // Check if user has the right.
   if (in_array($required_right, $user->rights)) {
     import('ttUserHelper');
index f416809..a5f16f9 100644 (file)
@@ -186,7 +186,7 @@ class ttRoleHelper {
     $rights_client = 'view_own_reports,view_own_charts,view_own_invoices,manage_own_settings';
     $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,manage_own_settings,view_users';
     $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets';
-    $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,view_all_reports';
+    $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,view_all_reports';
     $rights_manager = $rights_comanager.',manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups';
 
     // Active roles.
@@ -244,7 +244,7 @@ class ttRoleHelper {
     $rights_client = 'view_own_reports,view_own_charts,view_own_invoices,manage_own_settings';
     $rights_user = 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_projects,manage_own_settings,view_users';
     $rights_supervisor = $rights_user.',track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets';
-    $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,view_all_reports';
+    $rights_comanager = $rights_supervisor.',manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,view_all_reports';
     $rights_manager = $rights_comanager.',manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups';
 
     // Active roles.
index 01b0db3..0093e92 100644 (file)
@@ -869,6 +869,7 @@ class ttTeamHelper {
     $task_required_part = ' , task_required = '.(int) $fields['task_required'];
     $record_type_part = '';
     $bcc_email_part = '';
+    $allow_ip = '';
     $plugins_part = '';
     $config_part = '';
     $lock_spec_part = '';
@@ -883,6 +884,7 @@ class ttTeamHelper {
     if (isset($fields['tracking_mode'])) $tracking_mode_part = ', tracking_mode = '.(int) $fields['tracking_mode'];
     if (isset($fields['record_type'])) $record_type_part = ', record_type = '.(int) $fields['record_type'];
     if (isset($fields['bcc_email'])) $bcc_email_part = ', bcc_email = '.$mdb2->quote($fields['bcc_email']);
+    if (isset($fields['allow_ip'])) $allow_ip_part = ', allow_ip = '.$mdb2->quote($fields['allow_ip']);
     if (isset($fields['plugins'])) $plugins_part = ', plugins = '.$mdb2->quote($fields['plugins']);
     if (isset($fields['config'])) $config_part = ', config = '.$mdb2->quote($fields['config']);
     if (isset($fields['lock_spec'])) $lock_spec_part = ', lock_spec = '.$mdb2->quote($fields['lock_spec']);
@@ -891,7 +893,7 @@ class ttTeamHelper {
 
     $sql = "update tt_groups set $name_part $currency_part $lang_part $decimal_mark_part
       $date_format_part $time_format_part $week_start_part $tracking_mode_part $task_required_part $record_type_part
-      $bcc_email_part $plugins_part $config_part $lock_spec_part $workday_minutes_part $modified_part where id = $group_id";
+      $bcc_email_part $allow_ip_part $plugins_part $config_part $lock_spec_part $workday_minutes_part $modified_part where id = $group_id";
     $affected = $mdb2->exec($sql);
     if (is_a($affected, 'PEAR_Error')) return false;
 
index 70e5504..2781ea6 100644 (file)
@@ -53,6 +53,7 @@ class ttUser {
   var $future_entries = 0;      // Whether to allow creating future entries.
   var $uncompleted_indicators = 0; // Uncompleted time entry indicators (show nowhere or on users page).
   var $bcc_email = null;        // Bcc email.
+  var $allow_ip = null;         // Specification from where user is allowed access.
   var $currency = null;         // Currency.
   var $plugins = null;          // Comma-separated list of enabled plugins.
   var $config = null;           // Comma-separated list of miscellaneous config options.
@@ -72,11 +73,11 @@ class ttUser {
 
     $mdb2 = getConnection();
 
-    $sql = "SELECT u.id, u.login, u.name, u.group_id, u.role_id, r.rank, r.name as role_name, r.rights, u.client_id, u.email, t.name as team_name,
-      t.currency, t.lang, t.decimal_mark, t.date_format, t.time_format, t.week_start,
-      t.tracking_mode, t.project_required, t.task_required, t.record_type,
-      t.bcc_email, t.plugins, t.config, t.lock_spec, t.workday_minutes, t.custom_logo
-      FROM tt_users u LEFT JOIN tt_groups t ON (u.group_id = t.id) LEFT JOIN tt_roles r on (r.id = u.role_id) WHERE ";
+    $sql = "SELECT u.id, u.login, u.name, u.group_id, u.role_id, r.rank, r.name as role_name, r.rights, u.client_id, u.email, g.name as group_name,
+      g.currency, g.lang, g.decimal_mark, g.date_format, g.time_format, g.week_start,
+      g.tracking_mode, g.project_required, g.task_required, g.record_type,
+      g.bcc_email, g.allow_ip, g.plugins, g.config, g.lock_spec, g.workday_minutes, g.custom_logo
+      FROM tt_users u LEFT JOIN tt_groups g ON (u.group_id = g.id) LEFT JOIN tt_roles r on (r.id = u.role_id) WHERE ";
     if ($id)
       $sql .= "u.id = $id";
     else
@@ -111,7 +112,8 @@ class ttUser {
       $this->task_required = $val['task_required'];
       $this->record_type = $val['record_type'];
       $this->bcc_email = $val['bcc_email'];
-      $this->team = $val['team_name'];
+      $this->allow_ip = $val['allow_ip'];
+      $this->team = $val['group_name'];
       $this->currency = $val['currency'];
       $this->plugins = $val['plugins'];
       $this->lock_spec = $val['lock_spec'];
index 2063f4e..7e930e4 100644 (file)
@@ -446,6 +446,7 @@ $i18n_key_words = array(
 'form.profile.allow_overlap' => 'Allow overlap',
 'form.profile.future_entries' => 'Future entries',
 'form.profile.uncompleted_indicators' => 'Uncompleted indicators',
+'form.profile.allow_ip' => 'Allow IP',
 'form.profile.plugins' => 'Plugins',
 
 // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report.
index fb117e2..873d5ec 100644 (file)
@@ -12,7 +12,7 @@
       <br>
       <table cellspacing="0" cellpadding="4" width="100%" border="0">
         <tr>
-          <td align="center">&nbsp;Anuko Time Tracker 1.17.82.4202 | Copyright &copy; <a href="https://www.anuko.com/lp/tt_3.htm" target="_blank">Anuko</a> |
+          <td align="center">&nbsp;Anuko Time Tracker 1.17.83.4203 | Copyright &copy; <a href="https://www.anuko.com/lp/tt_3.htm" target="_blank">Anuko</a> |
             <a href="https://www.anuko.com/lp/tt_4.htm" target="_blank">{$i18n.footer.credits}</a> |
             <a href="https://www.anuko.com/lp/tt_5.htm" target="_blank">{$i18n.footer.license}</a> |
             <a href="https://www.anuko.com/lp/tt_7.htm" target="_blank">{$i18n.footer.improve}</a>
index 9b341b6..4dedafd 100644 (file)
@@ -164,11 +164,15 @@ function handlePluginCheckboxes() {
             <td align="right" nowrap>{$i18n.form.profile.uncompleted_indicators}:</td>
             <td>{$forms.groupForm.uncompleted_indicators.control} <a href="https://www.anuko.com/lp/tt_15.htm" target="_blank">{$i18n.label.what_is_it}</a></td>
           </tr>
-{if $user->isManager()}
+{if $user->can('manage_advanced_settings')}
           <tr>
             <td align="right" nowrap>{$i18n.label.bcc}:</td>
             <td>{$forms.groupForm.bcc_email.control} <a href="https://www.anuko.com/lp/tt_10.htm" target="_blank">{$i18n.label.what_is_it}</a></td>
           </tr>
+          <tr>
+            <td align="right" nowrap>{$i18n.form.profile.allow_ip}:</td>
+            <td>{$forms.groupForm.allow_ip.control} <a href="https://www.anuko.com/lp/tt_21.htm" target="_blank">{$i18n.label.what_is_it}</a></td>
+          </tr>
 {/if}
           {* initialize preview text *}
           <script>
index e8f282f..f801926 100644 (file)
@@ -805,7 +805,7 @@ if ($_POST) {
     print "Updated $users_updated users...<br>\n";
   }
 
-  if ($_POST["convert11744to11782"]) {
+  if ($_POST["convert11744to11783"]) {
     setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.44') set rights = replace(rights, 'override_punch_mode,override_date_lock', 'override_punch_mode,override_own_punch_mode,override_date_lock')");
     setChange("UPDATE `tt_site_config` SET param_value = '1.17.48' where param_name = 'version_db' and param_value = '1.17.44'");
     setChange("update `tt_users` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.48') set role_id = (select id from tt_roles where team_id = 0 and rank = 512) where role = 324");
@@ -885,6 +885,9 @@ if ($_POST) {
     setChange("UPDATE `tt_site_config` SET param_value = '1.17.81', modified = now() where param_name = 'version_db' and param_value = '1.17.80'");
     setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.81') set rights = replace(rights, ',manage_invoices', ',manage_invoices,view_all_reports')");
     setChange("UPDATE `tt_site_config` SET param_value = '1.17.82', modified = now() where param_name = 'version_db' and param_value = '1.17.81'");
+    setChange("ALTER TABLE `tt_groups` ADD `allow_ip` varchar(255) default NULL AFTER `bcc_email`");
+    setChange("update `tt_roles` inner join `tt_site_config` sc on (sc.param_name = 'version_db' and sc.param_value = '1.17.82') set rights = replace(rights, 'manage_invoices,view_all_reports', 'manage_invoices,override_allow_ip,view_all_reports')");
+    setChange("UPDATE `tt_site_config` SET param_value = '1.17.83', modified = now() where param_name = 'version_db' and param_value = '1.17.82'");
   }
 
   if ($_POST["cleanup"]) {
@@ -930,7 +933,7 @@ if ($_POST) {
 <h2>DB Install</h2>
 <table width="80%" border="1" cellpadding="10" cellspacing="0">
   <tr>
-    <td width="80%"><b>Create database structure (v1.17.82)</b>
+    <td width="80%"><b>Create database structure (v1.17.83)</b>
     <br>(applies only to new installations, do not execute when updating)</br></td><td><input type="submit" name="crstructure" value="Create"></td>
   </tr>
 </table>
@@ -970,8 +973,8 @@ if ($_POST) {
     <td><input type="submit" name="convert11400to11744" value="Update"><br><input type="submit" name="update_role_id" value="Update role_id"></td>
   </tr>
     <tr valign="top">
-    <td>Update database structure (v1.17.44 to v1.17.82)</td>
-    <td><input type="submit" name="convert11744to11782" value="Update"></td>
+    <td>Update database structure (v1.17.44 to v1.17.83)</td>
+    <td><input type="submit" name="convert11744to11783" value="Update"></td>
   </tr>
 </table>
 
index 1d71cc1..1d42ed6 100644 (file)
@@ -59,6 +59,7 @@ if ($request->isPost()) {
   $cl_future_entries = $request->getParameter('future_entries');
   $cl_uncompleted_indicators = $request->getParameter('uncompleted_indicators');
   $cl_bcc_email = trim($request->getParameter('bcc_email'));
+  $cl_allow_ip = trim($request->getParameter('allow_ip'));
 
   // Plugin checkboxes.
   $cl_charts = $request->getParameter('charts');
@@ -91,6 +92,7 @@ if ($request->isPost()) {
   $cl_future_entries = $user->future_entries;
   $cl_uncompleted_indicators = $user->uncompleted_indicators;
   $cl_bcc_email = $user->bcc_email;
+  $cl_allow_ip = $user->allow_ip;
 
   // Which plugins do we have enabled?
   $plugins = explode(',', $user->plugins);
@@ -188,6 +190,7 @@ $form->addInput(array('type'=>'checkbox','name'=>'uncompleted_indicators','value
 // Add bcc email control, for manager only.
 if ($user->can('manage_advanced_settings')) {
   $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'bcc_email','value'=>$cl_bcc_email));
+  $form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'allow_ip','value'=>$cl_allow_ip));
 }
 
 // Plugin checkboxes.
@@ -211,6 +214,8 @@ if ($request->isPost()) {
   if (!ttValidString($cl_currency, true)) $err->add($i18n->get('error.field'), $i18n->get('label.currency'));
   if ($user->can('manage_advanced_settings')) {
     if (!ttValidEmail($cl_bcc_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.bcc'));
+    // TODO: how about writing ttValidIP?
+    if (!ttValidString($cl_allow_ip, true)) $err->add($i18n->get('error.field'), $i18n->get('form.profile.allow_ip'));
   }
   // Finished validating user input.
 
@@ -282,6 +287,7 @@ if ($request->isPost()) {
         'record_type' => $cl_record_type,
         'uncompleted_indicators' => $cl_uncompleted_indicators,
         'bcc_email' => $cl_bcc_email,
+        'allow_ip' => $cl_allow_ip,
         'plugins' => $plugins,
         'config' => $config));
     }
index 6d6ce5f..995b032 100644 (file)
--- a/mysql.sql
+++ b/mysql.sql
@@ -28,6 +28,7 @@ CREATE TABLE `tt_groups` (
   `task_required` smallint(2) NOT NULL default 0,        # whether a task selection is required or optional
   `record_type` smallint(2) NOT NULL default 0,          # time record type ("start and finish", "duration", or both)
   `bcc_email` varchar(100) default NULL,                 # bcc email to copy all reports to
+  `allow_ip` varchar(255) default NULL,                  # specification from where users are allowed access
   `plugins` varchar(255) default NULL,                   # a list of enabled plugins for team
   `lock_spec` varchar(255) default NULL,                 # Cron specification for record locking,
                                                          # for example: "0 10 * * 1" for "weekly on Mon at 10:00".
@@ -73,7 +74,7 @@ create unique index role_idx on tt_roles(group_id, rank, status);
 
 # Insert site-wide roles - site administrator and top manager.
 INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Site administrator', 1024, 'administer_site');
-INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_invoices,view_own_projects,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,view_all_reports,manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups');
+INSERT INTO `tt_roles` (`group_id`, `name`, `rank`, `rights`) VALUES (0, 'Top manager', 512, 'track_own_time,track_own_expenses,view_own_reports,view_own_charts,view_own_invoices,view_own_projects,manage_own_settings,view_users,track_time,track_expenses,view_reports,view_charts,override_punch_mode,override_own_punch_mode,override_date_lock,override_own_date_lock,swap_roles,approve_timesheets,manage_own_account,manage_users,manage_projects,manage_tasks,manage_custom_fields,manage_clients,manage_invoices,override_allow_ip,view_all_reports,manage_features,manage_basic_settings,manage_advanced_settings,manage_roles,export_data,manage_subgroups');
 
 
 #
@@ -449,4 +450,4 @@ CREATE TABLE `tt_site_config` (
   PRIMARY KEY  (`param_name`)
 );
 
-INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.82', now()); # TODO: change when structure changes.
+INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.17.83', now()); # TODO: change when structure changes.