Odyssey
permissions.i
1 <?php
2 
3 /*
4  * File containing functions to help validate permissions. Permissions are both the ability to see/use
5  * a given feature, as well as if the user has reached a certain limit. Limits can be a total, monthly,
6  * daily amount or count.
7  *
8  *
9  *
10  * There are three entry points:
11  * 1. Get the access rights for the user - Perm_AccessRights,
12  * 2. Get the limit amounts (in case wanting Transaction limit on client) - Perm_GetValidationAmounts,
13  * 3. With the current operation will the user surpass the limit - Perm_CheckLimits.
14  *
15  * NOTE: $permInputs are included in all entry points to provide a variable list of
16  * function-dependant parameters.
17  * ["feature"] - (required) the feature permission being accessed
18  * ["amount"] - The amount for the current function being checked
19  * ["account"] - The account being used in the current function being checked
20  *
21  * NOTE: UserId is included in the environment
22  *
23  */
24 
25 // permission types (aka feature codes)
26 define( "FEATURE_ALERTS", "ALERT" );
27 define( "FEATURE_BASIC", "BASIC" );
28 define( "FEATURE_BILLPAY", "BILLPAY" );
29 define( "FEATURE_MOBILE_BILLPAY", "MBILLPAY" );
30 define( "FEATURE_MOBILE_RDC", "MRDC" );
31 define( "FEATURE_ONLINE_LOAN_APP", "ONLINEAPP" );
32 define( "FEATURE_PFM", "PFM" );
33 define( "FEATURE_RDC", "RDC" );
34 define( "FEATURE_SECURE_MSG", "SECUREMSG" );
35 define( "FEATURE_SMS", "SMS" );
36 define( "FEATURE_STOP", "STOP" );
37 define( "FEATURE_DOWNLOAD_HISTORY", "TRNDOWN" );
38 define( "FEATURE_EXTERNAL_TRANSFERS", "TRNEXT" );
39 define( "FEATURE_WIRE_TRANSFERS", "TRNWIRE" );
40 define( "FEATURE_M2M_TRANSFERS", "TRNM2M" );
41 
42 define( "FEATURE_TRANSFERS", "TRN" );
43 define( "FEATURE_SCHEDULED_TRANSFERS", "TRNSCHED" );
44 define( "FEATURE_ESTATEMENTS", "ESTMT" );
45 define( "FEATURE_ACH_PAYMENTS", "ACHPMT" );
46 define( "FEATURE_ACH_COLLECTIONS", "ACHCOL" );
47 define( "FEATURE_PAYROLL", "ACHPYRL" );
48 
49 // Error codes, for easier lookup
50 // ** USER ERRORS
51 define( "PERM_ERROR_AMOUNT_EXCEED_TRANSACTION", 1200 );
52 define( "PERM_ERROR_AMOUNT_EXCEED_DAILY", 1201 );
53 define( "PERM_ERROR_AMOUNT_EXCEED_ACCT_PER_DAY", 1202 );
54 define( "PERM_ERROR_AMOUNT_EXCEED_MONTHLY", 1203 );
55 define( "PERM_ERROR_COUNT_EXCEED_DAILY", 1204 );
56 define( "PERM_ERROR_COUNT_EXCEED_ACCT_PER_DAY", 1205 );
57 define( "PERM_ERROR_COUNT_EXCEED_MONTHLY", 1206 );
58 define( "PERM_ERROR_ALERT_EXCEED_LIMIT", 1207 );
59 
60 // ** GROUP PERM ERRORS
61 define( "PERM_ERROR_GROUP_AMOUNT_EXCEED_TRANSACTION", 1208 );
62 define( "PERM_ERROR_GROUP_AMOUNT_EXCEED_DAILY", 1209 );
63 define( "PERM_ERROR_GROUP_AMOUNT_EXCEED_ACCT_PER_DAY", 1210 );
64 define( "PERM_ERROR_GROUP_AMOUNT_EXCEED_MONTHLY", 1211 );
65 define( "PERM_ERROR_GROUP_COUNT_EXCEED_DAILY", 1212 );
66 define( "PERM_ERROR_GROUP_COUNT_EXCEED_ACCT_PER_DAY", 1213 );
67 define( "PERM_ERROR_GROUP_COUNT_EXCEED_MONTHLY", 1214 );
68 
69 define( "PERM_ERROR_GETTING_LIMITS", 1250 );
70 define( "PERM_ERROR_COUNTING_ALERTS", 1251 );
71 
72 
73 /**
74  * Get the access rights. Return all the rights in case the caller needs to use them in
75  * several places.
76  *
77  * @param integer $pDbh -- Current database handle
78  * @param array $pHBEnv -- Current HB_ENV values
79  * @param array $permInputs -- An array with information specific to the given perm
80  * -- feature
81  * @return The access rights for the user.
82  */
83 function Perm_AccessRights( $pDbh, $pHBEnv, $pPermInputs ) {
84  try {
85  $rights = privPermGetFeatureRights( $pDbh, $pHBEnv, $pPermInputs["feature"] );
86  } catch (Exception $ex) {
87  $logInfo = array( "message" => $ex->getMessage(), "code" => $ex->getCode() );
88 
89  $rights = false;
90  }
91 
92  return $rights;
93 } // end Perm_AccessAllowed
94 
95 
96 /**
97  * Does the user have ACCESS to the member account?
98  *
99  * This is identified by the looking in the <client>memberacctrights table for the user and member account
100  *
101  * @param integer $pDbh -- Current database handle
102  * @param array $pHBEnv -- Current Environment Array
103  * @param integer $pUserId -- User Id
104  * @param string $pMbrAcct -- Account number we are looking for
105  *
106  * @return boolean -- Does the user have ACCESS rights to the specified member account
107  */
108 function Perm_MemberAccess($pDbh, $pHBEnv, $pUserId, $pMbrAcct) {
109 
110  $retVal = false;
111 
112  try {
113 
114  // * Query the memberacctrights for the user's ACCESS ability
115  $SQL = "SELECT allowed
116  FROM " . prep_save($pHBEnv['Cu'], 10) . "memberacctrights as mar
117  WHERE user_id = " . intval($pUserId) . "
118  AND accountnumber = '" . prep_save($pMbrAcct, 12) . "'
119  AND whichright = 'ACCESS' ";
120 
121  $accessRS = db_query( $SQL, $pDbh );
122  $accessRow = db_fetch_assoc( $accessRS);
123 
124  if (HCU_array_key_exists('allowed', $accessRow)) {
125  $retVal = ($accessRow['allowed'] === 't');
126  }
127 
128  } catch (Exception $ex) {
129  $retVal = false;
130  }
131 
132 
133  return $retVal;
134 }
135 
136 
137 /**
138  * Check if confirmation is required for the given feature.
139  *
140  * @param integer $pDbh -- Current database handle
141  * @param array $pHBEnv -- Current HB_ENV values
142  * @param array $permInputs -- An array with information specific to the given perm
143  * feature
144  * @return The confirmation required limitation for the user.
145  */
146 function Perm_CheckConfirmReq( $pDbh, $pHBEnv, $pPermInputs ) {
147  try {
148  $required = privPermCheckConfirmReq( $pDbh, $pHBEnv, $pPermInputs["feature"] );
149  } catch (Exception $ex) {
150  $logInfo = array( "message" => $ex->getMessage(), "code" => $ex->getCode() );
151 
152  $required = false;
153  }
154 
155  return $required;
156 } // end Perm_AccessAllowed
157 
158 
159 /**
160  * Check if the user has reached the limit amount for the given feature.
161  *
162  * @param integer $pDbh -- Current database handle
163  * @param array $pHBEnv -- Current HB_ENV values
164  * @param array $permInputs -- An array with information specific to the given perm
165  * -- feature, amount, account, accounttype
166  * @return True if under the limit; structure with error information if error or over limit.
167  */
168 function Perm_CheckLimits( $pDbh, $pHBEnv, $pPermInputs ) {
169 
170  try {
171  $feature = $pPermInputs["feature"];
172 
173  $amounts = privPermGetAllowedLimits( $pDbh, $pHBEnv, $feature );
174  if ( $amounts === false ) {
175  // something failed
176  throw new exception("Error getting allowed limits", PERM_ERROR_GETTING_LIMITS);
177  }
178 
179  // these all use the transaction table
180  /** **************
181  * USER LIMITS
182  */
183 
184  // handle the transaction limit special
185  if ( $pPermInputs["amount"] > $amounts["amount_per_transaction"] ) {
186  throw new exception("Exceeds amount per transaction limit", PERM_ERROR_AMOUNT_EXCEED_TRANSACTION);
187  }
188 
189  // get the historical amounts for current user
190  $currentAmounts = privPermGetCurrentActivity( $pDbh, $pHBEnv, $feature );
191 
192  // need to test all limits
193  // amount_per_day
194  if ( ($currentAmounts["amount"]["day"] + $pPermInputs["amount"]) > $amounts["amount_per_day"] ) {
195  throw new exception("Exceeds daily amount", PERM_ERROR_AMOUNT_EXCEED_DAILY);
196  }
197 
198  // amount_per_account_per_day
199  $accountNumber = trim( $pPermInputs["account"] );
200  $accountType = trim( $pPermInputs["accounttype"] );
201 
202  $accountAmount = isset( $currentAmounts["amount"]["account"]["$accountNumber|$accountType"] ) ? $currentAmounts["amount"]["account"]["$accountNumber|$accountType"] : 0;
203  if ( ($accountAmount + $pPermInputs["amount"]) > $amounts["amount_per_account_per_day"] ) {
204  throw new exception("Exceeds daily amount for selected account", PERM_ERROR_AMOUNT_EXCEED_ACCT_PER_DAY);
205  }
206 
207  // amount_per_month
208  if ( ($currentAmounts["amount"]["month"] + $pPermInputs["amount"]) > $amounts["amount_per_month"] ) {
209  throw new exception("Exceeds monthly amount", PERM_ERROR_AMOUNT_EXCEED_MONTHLY);
210  }
211 
212  // count_per_day
213  if ( $currentAmounts["count"]["day"] >= $amounts["count_per_day"] ) {
214  throw new exception("Exceeds daily count", PERM_ERROR_COUNT_EXCEED_DAILY);
215  }
216 
217  // count_per_account_per_day
218  $countAmount = isset( $currentAmounts["count"]["account"]["$accountNumber|$accountType"] ) ? $currentAmounts["count"]["account"]["$accountNumber|$accountType"] : 0;
219  if ( $countAmount >= $amounts["count_per_account_per_day"] ) {
220  throw new exception("Exceeds daily count for selected account", PERM_ERROR_COUNT_EXCEED_ACCT_PER_DAY);
221  }
222 
223  // count_per_month
224  if ( $currentAmounts["count"]["month"] >= $amounts["count_per_month"] ) {
225  throw new exception("Exceeds monthly count", PERM_ERROR_COUNT_EXCEED_MONTHLY);
226  }
227 
228  /** **************
229  * EVALUATE GROUP LIMITS
230  * ************** */
231 
232  /**
233  * Rules:
234  *
235  * Only evaluate the group limits, if there is more than 1 user in group
236  * This is because the user limits will have already been the most stringent policies
237  *
238  * ONLY evaluatge an item if the allowed value is LESS than the DEFAULT MAX AMOUNT
239  *
240  *
241  */
242  $groupUserCount = privGetGroupUserCount($pDbh, $pHBEnv, array("Uid" => $pHBEnv['Uid']));
243  /* MORE THAN ONE USER IN GROUP ? */
244  if ($groupUserCount > 1) {
245  /** GET GROUP LIMITS */
246  $groupLimits = HCU_array_key_value("group", $amounts);
247 
248  /** GET GROUP ACTIVITY **/
249  $groupActivityAmounts = privPermGetCurrentActivity( $pDbh, $pHBEnv, $feature, "GROUP" );
250 
251 
252  /** EVALUATE GROUP AMOUNT / DAY **/
253  if ( ($groupActivityAmounts["amount"]["day"] + $pPermInputs["amount"]) > floatval(HCU_array_key_value("amount_per_day", $groupLimits)) ) {
254  throw new exception("Exceeds daily group amount", PERM_ERROR_GROUP_AMOUNT_EXCEED_DAILY);
255  }
256 
257  /** EVALUATE GROUP AMOUNT / ACCT / DAY **/
258  $accountAmount = floatval(HCU_array_key_value("$accountNumber|$accountType", $groupActivityAmounts["amount"]["account"]));
259  if ( ($accountAmount + $pPermInputs["amount"]) > floatval(HCU_array_key_value("amount_per_account_per_day", $groupLimits)) ) {
260  throw new exception("Exceeds daily group amount for selected account", PERM_ERROR_GROUP_AMOUNT_EXCEED_ACCT_PER_DAY);
261  }
262 
263  /** EVALUATE GROUP AMOUNT / MONTH **/
264  if ( ($groupActivityAmounts["amount"]["month"] + $pPermInputs["amount"]) > floatval(HCU_array_key_value("amount_per_month", $groupLimits)) ) {
265  throw new exception("Exceeds monthly group amount", PERM_ERROR_GROUP_AMOUNT_EXCEED_MONTHLY);
266  }
267  /** EVALUATE GROUP COUNT / DAY **/
268  if ( $groupActivityAmounts["count"]["day"] >= intval(HCU_array_key_value("count_per_day", $groupLimits)) ) {
269  throw new exception("Exceeds daily group count", PERM_ERROR_GROUP_COUNT_EXCEED_DAILY);
270  }
271 
272  /** EVALUATE GROUP COUNT / ACCT / Day **/
273  $countAmount = intval(HCU_array_key_value("$accountNumber|$accountType", $groupActivityAmounts["count"]["account"]));
274  if ( $countAmount >= intval(HCU_array_key_value("count_per_account_per_day", $groupLimits)) ) {
275  throw new exception("Exceeds daily group count for selected account", PERM_ERROR_GROUP_COUNT_EXCEED_ACCT_PER_DAY);
276  }
277 
278  /** EVALUATE GROUP COUNT / MONTH **/
279  if ( $groupActivityAmounts["count"]["month"] >= intval(HCU_array_key_value("count_per_month", $groupLimits)) ) {
280  throw new exception("Exceeds monthly group count", PERM_ERROR_GROUP_COUNT_EXCEED_MONTHLY);
281  }
282 
283  } // ** END GROUP LIMITS CHECK
284  // yay!
285  $success = array();
286  $success["status"]["code"] = "000";
287  } catch (Exception $ex) {
288  // log the error
289  $logInfo = array( "message" => $ex->getMessage(), "code" => $ex->getCode() );
290 
291  // return the error
292  $success = array();
293  $success["status"]["code"] = $ex->getCode();
294  $success["status"]["severity"] = "ERROR";
295  $success["status"]["error"] = $ex->getMessage();
296  }
297 
298  return $success;
299 } // end Perm_CheckLimits
300 
301 /**
302  * Get the allowed amount(s) so the caller can validate on client. Usually just the
303  * transaction amount is desired.
304  *
305  * @param integer $pDbh -- Current database handle
306  * @param array $pHBEnv -- Current HB_ENV values
307  * @param array $permInputs -- An array with information specific to the given perm
308  * -- feature
309  * @param array $pAmounts -- returns an array with the amounts in it
310  * @return True if successful; false if not.
311  */
312 function Perm_GetValidationLimits( $pDbh, $pHBEnv, $pPermInputs ) {
313  try {
314  $amounts = privPermGetAllowedLimits( $pDbh, $pHBEnv, $pPermInputs["feature"] );
315  } catch (Exception $ex) {
316  $logInfo = array( "message" => $ex->getMessage(), "code" => $ex->getCode() );
317 
318  $amounts = false;
319  }
320 
321  return $amounts;
322 } // end Perm_GetValidationAmounts
323 
324 /**
325  * Get ALL Feature Access rights for the user (uid) in question
326  *
327  * @param integer $pDbh -- Current database handle
328  * @param array $pHBEnv -- Current HB_ENV Values
329  * @param array $permInputs -- Permission input values
330  * Uid -- User in question (optional - defaults to HB_ENV['Uid'])
331  * @return array
332  * status -
333  * code - {000 (pass), 999 (fail)}
334  * data - this is the data structure of a valid list. it should be broken out as such
335  * [feature_code][create]
336  * [access] -- (NOT YET IMPLEMENTED IN DB)
337  * [confirm]
338  * [decline]
339  * [report]
340  */
341 function Perm_FeatureAccessList($pDbh, $pHBEnv, $permInputs=null) {
342 
343  $retVal = Array("status" => Array("code"=>"000", "error"=>""), "data"=>Array());
344 
345  try {
346  // ** Validate the userid is being passed in successfully
347 
348  if (is_null($permInputs) || !HCU_array_key_exists('Uid', $permInputs)) {
349  // *Default to the HB_ENV Uid
350  $userId = $pHBEnv["Uid"];
351  } else {
352  $userId = HCU_array_key_value("Uid", $permInputs);
353  }
354 
355 
356  if (intval($userId) > 0) {
357  $modList = Array("Uid" => $userId);
358 
359  $userAccessList = privPermGetAllFeatureRights($pDbh, $pHBEnv, $modList);
360  if ($userAccessList['status']['code'] != '000') {
361  // ** throw an error - problem retrieving data
362  throw new Exception ("Unable to retrieve access list");
363  }
364 
365  if (!HCU_array_key_exists("data", $userAccessList)) {
366  throw new Exception ("Unable to retrieve access list");
367  }
368 
369  // ** We have a good list -- RETURN as ['data']
370  $retVal['data'] = $userAccessList['data'];
371  } else {
372  // ** Throw up an error - the userId was NOT correct
373  throw new Exception("Invalid User Id");
374  }
375 
376 
377  } catch (Exception $ex) {
378  $retVal['status']['code'] = '999';
379  $retVal['status']['error'] = $ex->getMessage();
380  $retVal['data'] = Array(); // ** Clear data array
381 
382  }
383 
384  return $retVal;
385 }// end Perm_FeatureAccessList
386 
387 
388 /**
389  * Get the Permission Error Description related to the error Code
390  *
391  * @param class $pMc - The localization Language class
392  * @param string $pPermErrCode - The Permission Error Code, these are defined at top of this script
393  * - if not present then it will return default "perm" limit error
394  * @param integer $pDispFor - The constant used by $pMc for displaying the value
395  * default - HCU_DISPLAY_AS_HTML
396  *
397  * @return string - Localication Error
398  */
399 function Perm_GetLimitErrDesc($pMc, $pPermErrCode='', $pDispFor=HCU_DISPLAY_AS_HTML) {
400 
401  $retStr = $pMc->msg('Perm Limit - Request over authorized limit', $pDispFor);
402 
403  switch ($pPermErrCode) {
404 // Error codes, for easier lookup
405  /** START USER LIMIT ERRORS **/
406  case 1200:
407  /** "PERM_ERROR_AMOUNT_EXCEED_TRANSACTION" **/
408  $retStr = $pMc->msg('Perm Limit - Amount Exceeds Transaction', $pDispFor);
409  break;
410  case 1201:
411  /** "PERM_ERROR_AMOUNT_EXCEED_DAILY" **/
412  $retStr = $pMc->msg('Perm Limit - Amount Exceeds Daily', $pDispFor);
413  break;
414  case 1202:
415  /** "PERM_ERROR_AMOUNT_EXCEED_ACCT_PER_DAY" **/
416  $retStr = $pMc->msg('Perm Limit - Amount Exceeds Account Per Day', $pDispFor);
417  break;
418  case 1203:
419  /** "PERM_ERROR_AMOUNT_EXCEED_MONTHLY" **/
420  $retStr = $pMc->msg('Perm Limit - Amount Exceeds Monthly', $pDispFor);
421  break;
422  case 1204:
423  /** "PERM_ERROR_COUNT_EXCEED_DAILY" **/
424  $retStr = $pMc->msg('Perm Limit - Count Exceeds Daily', $pDispFor);
425  break;
426  case 1205:
427  /** "PERM_ERROR_COUNT_EXCEED_ACCT_PER_DAY" **/
428  $retStr = $pMc->msg('Perm Limit - Count Exceeds Account Per Day', $pDispFor);
429  break;
430  case 1206:
431  /** "PERM_ERROR_COUNT_EXCEED_MONTHLY" **/
432  $retStr = $pMc->msg('Perm Limit - Count Exceeds Monthly', $pDispFor);
433  break;
434  case 1207:
435  /** "PERM_ERROR_ALERT_EXCEED_LIMIT" **/
436  $retStr = $pMc->msg('Perm Limit - Exceeds Alert Limit', $pDispFor);
437  break;
438  /** END USER LIMIT ERRORS **/
439 
440 
441 
442  /** START GROUP LIMIT ERRORS **/
443  case 1208:
444  /** "PERM_ERROR_GROUP_AMOUNT_EXCEED_TRANSACTION" **/
445  $retStr = $pMc->msg('Perm Limit - Amount Exceeds Group Transaction', $pDispFor);
446  break;
447  case 1209:
448  /** "PERM_ERROR_GROUP_AMOUNT_EXCEED_DAILY" **/
449  $retStr = $pMc->msg('Perm Limit - Amount Exceeds Group Daily', $pDispFor);
450  break;
451  case 1210:
452  /** "PERM_ERROR_GROUP_AMOUNT_EXCEED_ACCT_PER_DAY" **/
453  $retStr = $pMc->msg('Perm Limit - Amount Exceeds Group Account Per Day', $pDispFor);
454  break;
455  case 1211:
456  /** "PERM_ERROR_GROUP_AMOUNT_EXCEED_MONTHLY" **/
457  $retStr = $pMc->msg('Perm Limit - Amount Exceeds Group Monthly', $pDispFor);
458  break;
459  case 1212:
460  /** "PERM_ERROR_GROUP_COUNT_EXCEED_DAILY" **/
461  $retStr = $pMc->msg('Perm Limit - Count Exceeds Group Daily', $pDispFor);
462  break;
463  case 1213:
464  /** "PERM_ERROR_GROUP_COUNT_EXCEED_ACCT_PER_DAY" **/
465  $retStr = $pMc->msg('Perm Limit - Count Exceeds Group Account Per Day', $pDispFor);
466  break;
467  case 1214:
468  /** "PERM_ERROR_GROUP_COUNT_EXCEED_MONTHLY" **/
469  $retStr = $pMc->msg('Perm Limit - Count Exceeds Group Monthly', $pDispFor);
470  break;
471 
472  /** END GROUP LIMIT ERRORS **/
473 
474  case 1250:
475  /** "PERM_ERROR_GETTING_LIMITS" **/
476  $retStr = $pMc->msg('Perm Limit - Error Getting Limits', $pDispFor);
477  break;
478  case 1251:
479  /** "PERM_ERROR_COUNTING_ALERTS" **/
480  $retStr = $pMc->msg('Perm Limit - Error Getting Alerts', $pDispFor);
481  break;
482  }
483 
484  return $retStr;
485 }
486 /**
487  * Get ALL Feature Access rights FROM the db for the user (uid) in question
488  * and set as needed
489  *
490  * @param integer $pDbh -- Current database handle
491  * @param array $pHBEnv -- Current HB_ENV Values
492  * @param array $permInputs -- Permission input values
493  * Uid -- User in question
494  * @return array
495  * status -
496  * code - {000 (pass), 999 (fail)}
497  * data - this is the data structure of a valid list. it should be broken out as such
498  * for each [uid]
499  * [feature_code][create]
500  * [access] -- (NOT YET IMPLEMENTED IN DB)
501  * [confirm]
502  * [decline]
503  * [report]
504  */
505 function privPermGetAllFeatureRights($pDbh, $pHBEnv, $permInputs) {
506  $retVal = Array("status"=>Array("code"=>"000", "error"=>""), "data"=>Array());
507 
508  $retData = Array();
509  try {
510 
511  if (HCU_array_key_exists('Uid', $permInputs)) {
512  $lUid = intval(HCU_array_key_value('Uid', $permInputs));
513  } else {
514  throw new Exception("Invalid User");
515  }
516  /*
517  * ***
518  * What I'm trying to do:::
519  * This list needs to include ALL features in a particular user rights inheritance
520  * At the top there is the cu_profilerights - All users are under a profile which joins a profile with features
521  * Next is the cu_profile - This is joined to ensure we are looking at profile list for the desired CU
522  * Next is the <cucode>group - By default a group will have access to all features in a group -- There limits may be different
523  * Next is the <cucode>user - This is used only a joining mechanism between a group and userrights
524  * Last is the <cucode>userrights - This is the table I am looking for - If a value is explicitly set to false, then maintain that value
525  * - If a value is null on account of the record not existing then this is also true
526  *
527  */
528 
529  $SQL = "SELECT cu_u.user_id,
530  cu_pr.feature_code,
531  deny_create as create,
532  deny_access as access,
533  deny_confirm as confirm,
534  deny_decline as decline,
535  deny_report as report
536  FROM cu_profilerights cu_pr
537  JOIN cu_profile as cu_p on cu_p.profile_id = cu_pr.profile_id
538  LEFT JOIN " . prep_save($pHBEnv['Cu'], 10) . "group as cu_g on cu_g.profile_id = cu_pr.profile_id
539  LEFT JOIN " . prep_save($pHBEnv['Cu'], 10) . "user as cu_u on cu_u.group_id = cu_g.group_id
540  LEFT JOIN " . prep_save($pHBEnv['Cu'], 10) . "userrights as cu_ur on cu_ur.user_id = cu_u.user_id
541  AND cu_ur.feature_code = cu_pr.feature_code
542  WHERE cu_p.cu = '" . prep_save($pHBEnv['Cu'], 10) . "'
543  AND cu_u.user_id = {$lUid}
544  ORDER BY cu_u.user_id, cu_pr.feature_code; ";
545 
546 
547  $accessRS = db_query( $SQL, $pDbh );
548  $accessRows = db_fetch_all( $accessRS);
549  // ** ALL rows are returned -- Loop through them and create the returned data array
550  for ($idx = 0; $idx < count($accessRows); $idx++) {
551  // *** Single out the row
552  $accessRow = $accessRows[$idx];
553  /*
554  * When the deny_* fields are true, this is the ONLY time the user has NO access
555  * Therefore I am negating the value to determine if they have permission
556  */
557 
558  $access= !($accessRow["access"] === 't');
559  $fromAdmin= isset( $pHBEnv["Ca"] ) && ($pHBEnv["Ca"] != "");
560  $retData[trim($accessRow['feature_code'])] = array( "access" => $access,
561  "create" => $fromAdmin ? false : !($accessRow["create"] === 't'),
562  "confirm" => !($accessRow["confirm"] === 't'),
563  "decline" => !($accessRow["decline"] === 't'),
564  "report" => !($accessRow["report"] === 't'),
565  "readonly" => $fromAdmin && $access);
566 
567  }
568  $retVal['data'] = Array(intval($pHBEnv['Uid']) => $retData);
569 
570  } catch (Exception $ex) {
571  // ** Error found -- throw back .
572  $retVal['status']['code'] = '999';
573  $retVal['status']['error'] = $ex->getMessage();
574  $retVal['data'] = Array();
575  }
576 
577 
578 
579  return $retVal;
580 }
581 
582 // Check if the user can access this feature.
583 // NOTE: the feature_create right is also being used for access rights.
584 // NOTE: implied right is TRUE
585 /*
586  * Removed use of COALESCE -- because false/null both mean the feature is allowed I will simply make comparisons against the value 't'
587  */
588 function privPermGetFeatureRights( $pDbh, $pHBEnv, $pFeature ) {
589 
590  try {
591  $SQL = "
592  SELECT
593  deny_create AS create,
594  deny_access AS access,
595  deny_confirm AS confirm,
596  deny_decline AS decline,
597  deny_report AS report
598  FROM cu_profilerights cu_pr
599  JOIN cu_profile cu_p ON cu_p.profile_id = cu_pr.profile_id
600  LEFT JOIN " . prep_save($pHBEnv['Cu'], 10) . "group as cu_g on cu_g.profile_id = cu_pr.profile_id
601  LEFT JOIN " . prep_save($pHBEnv['Cu'], 10) . "user as cu_u on cu_u.group_id = cu_g.group_id
602  LEFT JOIN " . prep_save($pHBEnv['Cu'], 10) . "userrights as cu_ur on cu_ur.user_id = cu_u.user_id
603  AND cu_ur.feature_code = cu_pr.feature_code
604  WHERE cu_p.cu = '" . prep_save($pHBEnv['Cu'], 10) . "'
605  AND cu_u.user_id = {$pHBEnv["Uid"]}
606  AND cu_pr.feature_code = '{$pFeature}'
607  ORDER BY cu_u.user_id, cu_pr.feature_code;";
608 
609  $accessRS = db_query( $SQL, $pDbh );
610  $accessRows = db_num_rows($accessRS);
611  if ($accessRows > 0) {
612  $accessRow = db_fetch_array( $accessRS, 0 );
613 
614  // for now "access" uses the "create" flag
615  $access= !($accessRow["access"] === 't');
616  $fromAdmin= HCU_array_key_value('Ca', $pHBEnv) != "";
617  $return = array(
618  "access" => $access,
619  "create" => $fromAdmin ? false : !($accessRow["create"] === 't'),
620  "confirm" => !($accessRow["confirm"] === 't'),
621  "decline" => !($accessRow["decline"] === 't'),
622  "report" => !($accessRow["report"] === 't'),
623  "readonly" => $fromAdmin && $access);
624  } else {
625  $return = array(
626  "access" => false,
627  "create" => false,
628  "confirm" => false,
629  "decline" => false,
630  "report" => false,
631  "readonly" => false
632  );
633  }
634  } catch (Exception $ex) {
635  $return = false;
636  }
637 
638  return ($return);
639 } // end privPermGetFeatureRights
640 
641 
642 // Get the total activity (OUTGOING) for the given month. Then go through and get the breakdown.
643 // NOTE: just want out-going but since it is broken down by feature it is only called for outgoing.
644 /**
645  *
646  *
647  * @param string $pType - Defaults to USER. Other option is GROUP
648  * This will determine if we are getting the activity for specific user or group
649  *
650  * return array
651  */
652 function privPermGetCurrentActivity( $pDbh, $pHBEnv, $pFeature, $pType="USER") {
653 
654  /* **
655  * MWS 9/26/2018
656  * NOTE: for TRNEXT the micro deposit gets included as part of the overall count / amount for the
657  * daily and monthly totals. It does not count towards the account/day because the aggregate
658  * key is [|]. At this time we are looking at fixing this possible discrepancy.
659  */
660 
661  try {
662  $lUid = intval(HCU_array_key_value("Uid", $pHBEnv));
663  // NOTE: postgres uses yyyy-mm-dd for the dates, and that is in sort order
664  // set the date range for the month for easy comparison
665  $firstOfMonth = date( "Y-m-01" );
666  $firstOfNextMonth = date( "Y-m-d", strtotime( "first day of next month" ) );
667 
668  if ($pType == 'GROUP') {
669  $SQL = "
670  WITH dtl AS (
671  SELECT transhdr_id, sum(amount) AS amount,
672  min(transdata::json->>'acct_source') AS acct_source,
673  min(transdata::json->>'acct_dest') AS acct_dest
674  FROM {$pHBEnv["Cu"]}transdtl GROUP BY 1
675  )
676  SELECT
677  date(hdr.posted_date) AS date, dtl.amount,
678  CASE WHEN LEFT(hdr.transactioncode, 1) = '2' THEN split_part(dtl.acct_dest, '|', 2) ELSE split_part(dtl.acct_source, '|', 2) END AS accountnumber,
679  CASE WHEN LEFT(hdr.transactioncode, 1) = '2' THEN split_part(dtl.acct_dest, '|', 3) ELSE split_part(dtl.acct_source, '|', 3) END AS accounttype
680  FROM {$pHBEnv["Cu"]}transhdr AS hdr
681  INNER JOIN dtl ON hdr.id = dtl.transhdr_id
682  JOIN {$pHBEnv["Cu"]}user AS cur_user ON cur_user.user_id = {$lUid}
683  JOIN {$pHBEnv["Cu"]}user AS group_user ON group_user.group_id = cur_user.group_id
684  WHERE hdr.posted_by = group_user.user_id
685  AND hdr.feature_code = '$pFeature'
686  AND posted_date >= '$firstOfMonth'
687  AND posted_date < '$firstOfNextMonth' ";
688  } else {
689  $SQL = "
690  WITH dtl AS (
691  SELECT transhdr_id, sum(amount) AS amount,
692  min(transdata::json->>'acct_source') AS acct_source,
693  min(transdata::json->>'acct_dest') AS acct_dest from {$pHBEnv["Cu"]}transdtl
694  GROUP BY 1
695  )
696  SELECT
697  date(hdr.posted_date) AS date, dtl.amount,
698  CASE WHEN LEFT(hdr.transactioncode, 1) = '2' THEN split_part(dtl.acct_dest, '|', 2) ELSE split_part(dtl.acct_source, '|', 2) END AS accountnumber,
699  CASE WHEN LEFT(hdr.transactioncode, 1) = '2' THEN split_part(dtl.acct_dest, '|', 3) ELSE split_part(dtl.acct_source, '|', 3) END AS accounttype
700  FROM {$pHBEnv["Cu"]}transhdr hdr
701  INNER JOIN dtl ON hdr.id = dtl.transhdr_id
702  WHERE hdr.posted_by = {$lUid}
703  AND hdr.feature_code = '$pFeature'
704  AND posted_date >= '$firstOfMonth'
705  AND posted_date < '$firstOfNextMonth' ";
706  }
707 
708  $rs = db_query( $SQL, $pDbh );
709 
710  // initialize the values
711  $return = array( "amount" => array( "day" => 0,
712  "month" => 0,
713  "account" => array() ),
714  "count" => array( "day" => 0,
715  "month" => 0,
716  "account" => array() ) );
717 
718  // set the date for today for easy comparison
719  $today = date( "Y-m-d" );
720 
721  // cycle through the rows
722  $row = 0;
723  while ( $transRow = db_fetch_array( $rs, $row++ ) ) {
724  // add the amount
725  $thisAmount = $transRow["amount"];
726  if ( $transRow["date"] == $today ) {
727  $return["amount"]["day"] += $thisAmount;
728  $return["count"]["day"]++;
729 
730  // also break up by account
731  $accountNumber = trim( $transRow["accountnumber"] );
732  $accountType = trim( $transRow["accounttype"] );
733  if ( isset( $return["amount"]["account"]["$accountNumber|$accountType"] ) ) {
734  $return["amount"]["account"]["$accountNumber|$accountType"] += $thisAmount;
735  } else {
736  // first time
737  $return["amount"]["account"]["$accountNumber|$accountType"] = $thisAmount;
738  }
739  if ( isset( $return["count"]["account"]["$accountNumber|$accountType"] ) ) {
740  $return["count"]["account"]["$accountNumber|$accountType"]++;
741  } else {
742  // first time
743  $return["count"]["account"]["$accountNumber|$accountType"] = 1;
744  }
745 
746  }
747 
748  // all of them go into the monthly amount
749  $return["amount"]["month"] += $thisAmount;
750  $return["count"]["month"]++;
751  }
752  } catch (Exception $ex) {
753  $return = false;
754  }
755 
756  return $return;
757 } // end privPermGetCurrentActivity
758 
759 // Check all three rights tables to get the allowed amounts and counts.
760 function privPermGetAllowedLimits( $pDbh, $pHBEnv, $pFeature ) {
761 
762  // get the default maximum definition
763  $maxAmount = FEATURE_LIMIT_MAX_AMOUNT;
764  $maxCount = FEATURE_LIMIT_MAX_COUNT;
765 
766  try {
767  // NOTE: profilerights is always present for allowed features but grouprights and
768  // userrights may not be.
769  // NOTE: treating "confirm_required" as a limit that cannot be esclated by a lower right
770  $SQL = "SELECT COALESCE( u.amount_per_transaction, $maxAmount) as u_apt,
771  COALESCE( u.amount_per_day, $maxAmount) as u_apd,
772  COALESCE( u.amount_per_month, $maxAmount) as u_apm,
773  COALESCE( u.amount_per_account_per_day, $maxAmount) as u_apapd,
774  COALESCE( g.amount_per_transaction, $maxAmount) as g_apt,
775  COALESCE( g.amount_per_day, $maxAmount) as g_apd,
776  COALESCE( g.amount_per_month, $maxAmount) as g_apm,
777  COALESCE( g.amount_per_account_per_day, $maxAmount) as g_apapd,
778  COALESCE( p.amount_per_transaction, $maxAmount) as p_apt,
779  COALESCE( p.amount_per_day, $maxAmount) as p_apd,
780  COALESCE( p.amount_per_month, $maxAmount) as p_apm,
781  COALESCE( p.amount_per_account_per_day, $maxAmount) as p_apapd,
782  COALESCE( u.count_per_day, $maxCount) as u_cpd,
783  COALESCE( u.count_per_month, $maxCount) as u_cpm,
784  COALESCE( u.count_per_account_per_day, $maxCount) as u_cpapd,
785  COALESCE( g.count_per_day, $maxCount) as g_cpd,
786  COALESCE( g.count_per_month, $maxCount) as g_cpm,
787  COALESCE( g.count_per_account_per_day, $maxCount) as g_cpapd,
788  COALESCE( p.count_per_day, $maxCount) as p_cpd,
789  COALESCE( p.count_per_month, $maxCount) as p_cpm,
790  COALESCE( p.count_per_account_per_day, $maxCount) as p_cpapd,
791  COALESCE( u.confirm_required, false) as u_cr,
792  COALESCE( g.confirm_required, false) as g_cr,
793  COALESCE( p.confirm_required, false) as p_cr
794  FROM {$pHBEnv["Cu"]}user usr
795  INNER JOIN {$pHBEnv["Cu"]}group grp ON grp.group_id = usr.group_id
796  INNER JOIN cu_profilerights p ON p.profile_id = grp.profile_id
797  AND p.feature_code = '$pFeature'
798  LEFT JOIN {$pHBEnv["Cu"]}grouprights g ON g.group_id = usr.group_id
799  AND g.feature_code = '$pFeature'
800  LEFT JOIN {$pHBEnv["Cu"]}userrights u ON u.user_id = usr.user_id
801  AND u.feature_code = '$pFeature'
802  WHERE usr.user_id = {$pHBEnv["Uid"]}";
803 
804  // should just be one row
805  $rs = db_query( $SQL, $pDbh );
806  $amountsRow = db_fetch_array( $rs, 0 );
807 
808  // Now put it into a usable format, using the max each, for the user check and also
809  // return the group amounts for the group check.
810  $apt = min( min( $amountsRow["u_apt"], $amountsRow["g_apt"] ), $amountsRow["p_apt"] );
811  $apd = min( min( $amountsRow["u_apd"], $amountsRow["g_apd"] ), $amountsRow["p_apd"] );
812  $apm = min( min( $amountsRow["u_apm"], $amountsRow["g_apm"] ), $amountsRow["p_apm"] );
813  $apapd = min( min( $amountsRow["u_apapd"], $amountsRow["g_apapd"] ), $amountsRow["p_apapd"] );
814 
815  $cpd = min( min( $amountsRow["u_cpd"], $amountsRow["g_cpd"] ), $amountsRow["p_cpd"] );
816  $cpm = min( min( $amountsRow["u_cpm"], $amountsRow["g_cpm"] ), $amountsRow["p_cpm"] );
817  $cpapd = min( min( $amountsRow["u_cpapd"], $amountsRow["g_cpapd"] ), $amountsRow["p_cpapd"] );
818 
819  // ** Determine Group Limits -- Minimum of Profile / Group Rights
820  $gapt = min( $amountsRow["g_apt"], $amountsRow["p_apt"] ); // Amount / Transaction
821  $gapd = min( $amountsRow["g_apd"], $amountsRow["p_apd"] ); // Amount / Day
822  $gapm = min( $amountsRow["g_apm"] , $amountsRow["p_apm"] ); // Amount / Month
823  $gapapd = min( $amountsRow["g_apapd"], $amountsRow["p_apapd"] ); // Amount Per Account / Day
824 
825  $gcpd = min( $amountsRow["g_cpd"], $amountsRow["p_cpd"] ); // Count / Day
826  $gcpm = min( $amountsRow["g_cpm"], $amountsRow["p_cpm"] ); // Count / Month
827  $gcpapd = min( $amountsRow["g_cpapd"], $amountsRow["p_cpapd"] ); // Count Per Account / Day
828 
829  // if higher level set to true then doesn't matter what lower level needs
830  $cr = ($amountsRow["u_cr"] == 't') || ($amountsRow["g_cr"] == 't') || ($amountsRow["p_cr"] == 't') ? true : false;
831 
832  $return = array( "amount_per_transaction" => $apt,
833  "amount_per_day" => $apd,
834  "amount_per_month" => $apm,
835  "amount_per_account_per_day" => $apapd,
836  "count_per_day" => $cpd,
837  "count_per_month" => $cpm,
838  "count_per_account_per_day" => $cpapd,
839  "group" => array( "amount_per_transaction" => $gapt,
840  "amount_per_day" => $gapd,
841  "amount_per_month" => $gapm,
842  "amount_per_account_per_day" => $gapapd,
843  "count_per_day" => $gcpd,
844  "count_per_month" => $gcpm,
845  "count_per_account_per_day" => $gcpapd
846  ),
847  "confirm_required" => $cr
848  );
849 
850  } catch (Exception $ex) {
851  $return = false;
852  }
853 
854  return $return;
855 } // end privPermGetAllowedLimits
856 
857 // Get the number of alerts (any type) for the user
858 function privGetCurrentAlertCount( $pDbh, $pHBEnv ) {
859  try {
860  $SQL = "SELECT count(*) as count FROM cu_alerts WHERE cu = '{$pHBEnv["Cu"]}' AND user_id = {$pHBEnv["Uid"]}";
861 
862  $rs = db_query( $SQL, $pDbh );
863  $countRow = db_fetch_array( $rs, 0 );
864 
865  $result = $countRow["count"];
866  } catch (Exception $ex) {
867  $result = false;
868  }
869 
870  return $result;
871 } // end privGetCurrentAlertCount
872 
873 // Check all three rights tables to determine if confirmation is required.
874 function privPermCheckConfirmReq( $pDbh, $pHBEnv, $pFeature ) {
875  try {
876  // Special case for single user in group (no confirmation required)
877  $SQL = "SELECT count( u.*) as user_count
878  FROM {$pHBEnv["Cu"]}user usr
879  INNER JOIN {$pHBEnv["Cu"]}user u ON u.group_id = usr.group_id
880  WHERE usr.user_id = {$pHBEnv["Uid"]}";
881  $rs = db_query( $SQL, $pDbh );
882  $countRow = db_fetch_array( $rs, 0 );
883 
884  if ( $countRow["user_count"] == 1 ) {
885  $cr = false;
886  } else {
887  // NOTE: profilerights is always present for allowed features but grouprights and
888  // userrights may not be.
889  // NOTE: treating "confirm_required" as a limit that cannot be esclated by a lower right
890  // NOTE: special case of single user in group = no confirmation required
891  $SQL = "SELECT COALESCE( u.confirm_required, false) as u_cr,
892  COALESCE( g.confirm_required, false) as g_cr,
893  COALESCE( p.confirm_required, false) as p_cr
894  FROM {$pHBEnv["Cu"]}user usr
895  INNER JOIN {$pHBEnv["Cu"]}group grp ON grp.group_id = usr.group_id
896  INNER JOIN cu_profilerights p ON p.profile_id = grp.profile_id
897  AND p.feature_code = '$pFeature'
898  LEFT JOIN {$pHBEnv["Cu"]}grouprights g ON g.group_id = usr.group_id
899  AND g.feature_code = '$pFeature'
900  LEFT JOIN {$pHBEnv["Cu"]}userrights u ON u.user_id = usr.user_id
901  AND u.feature_code = '$pFeature'
902  WHERE usr.user_id = {$pHBEnv["Uid"]}";
903 
904  // should just be one row
905  $rs = db_query( $SQL, $pDbh );
906  $confirmRow = db_fetch_array( $rs, 0 );
907 
908  // if higher level set to true then doesn't matter what lower level needs
909  $cr = ($confirmRow["u_cr"] == 't') || ($confirmRow["g_cr"] == 't') || ($confirmRow["p_cr"] == 't') ? true : false;
910  }
911 
912  $return = $cr;
913 
914  } catch (Exception $ex) {
915  // any error would mean don't get rights
916  $return = false;
917  }
918 
919  return $return;
920 } // end privPermCheckConfirmReq
921 
922 
923 /**
924  * Return the number of users in the group for the requested user
925  *
926  * @param integer $pDbh - The current database handle
927  * @param array $pHBEnv - Current Environment array
928  * @param array $permInputs - Array for parameters to be passed in
929  * Uid -- Required - this is the requested user id
930  *
931  * @return mixed
932  * false -- if error encountered
933  * 0 -- user group or user not found
934  * > 0 -- Number of users in the group
935  */
936 function privGetGroupUserCount($pDbh, $pHBEnv, $permInputs) {
937 
938  $retVal = 0;
939  try {
940 
941  if (HCU_array_key_exists('Uid', $permInputs)) {
942  $lUid = intval(HCU_array_key_value('Uid', $permInputs));
943  } else {
944  throw new Exception("Invalid User");
945  }
946 
947 
948  // ** Create the query to count the number of users for {group} of the user in question
949  $sql = "SELECT count(group_user.user_id) as user_count
950  FROM {$pHBEnv["Cu"]}user as cur_user
951  JOIN {$pHBEnv["Cu"]}user as group_user on group_user.group_id = cur_user.group_id
952  WHERE cur_user.user_id = {$lUid} ";
953 
954  $rs = db_query( $sql, $pDbh );
955 
956  if ($rs) {
957  $countRow = db_fetch_array( $rs );
958  $retVal = intval($countRow['user_count']);
959  } else {
960  throw new Exception("Group User Count sql failed");
961  }
962 
963  } catch (Exception $ex) {
964  $retVal = false;
965  }
966 
967  return $retVal;
968 } // end privGetGroupUserCount