RideLogicAPIQueryWrapper.pm 130 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197
  1. package RideLogicAPIQueryWrapper;
  2. use strict;
  3. use RideLogic ();
  4. use RideLogicDBI;
  5. use POSIX;
  6. require RideLogic ;
  7. require RideLogicDBI;
  8. require Exporter;
  9. use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  10. $VERSION = "0.01";
  11. @ISA = qw( Exporter RideLogicDBI );
  12. @EXPORT = qw( );
  13. @EXPORT_OK = qw( );
  14. %EXPORT_TAGS = ( DEFAULT => [ qw( ) ] );
  15. my $PACKAGE_NAME = "RideLogicAPIQueryWrapper";
  16. my $DEFAULT_GROUP_NAME = "ORG";
  17. # our constructor
  18. sub connect
  19. {
  20. my $class = shift;
  21. my $r = $class->RideLogicDBI::connect(@_);
  22. # default to raising an error
  23. if (!defined($_[3]))
  24. {
  25. my $dbh = ${$r->{'dbh_ref'}};
  26. }
  27. return $r;
  28. }
  29. ###################################################
  30. sub unix_to_readable_time {
  31. my $unix_time = shift;
  32. my @a = ( $unix_time ? localtime($unix_time) : localtime() );
  33. return sprintf('%d-%02d-%02d %02d:%02d:%02d', (1900+$a[5]), (1+$a[4]), $a[3], $a[2], $a[1], $a[0]);
  34. }
  35. sub audit_users_start
  36. {
  37. my $self = shift;
  38. my $id = shift;
  39. my $comment = shift;
  40. my $dbh = ${$self->{'dbh_ref'}};
  41. return RideLogic::audit_users_start($dbh, $id, $comment);
  42. }
  43. sub audit_users_end
  44. {
  45. my $self = shift;
  46. my $id = shift;
  47. my $audit_id = shift;
  48. my $dbh = ${$self->{'dbh_ref'}};
  49. return RideLogic::audit_users_end($dbh, $id, $audit_id);
  50. }
  51. sub audit_admins_start
  52. {
  53. my $self = shift;
  54. my $id = shift;
  55. my $comment = shift;
  56. my $dbh = ${$self->{'dbh_ref'}};
  57. return RideLogic::audit_admins_start($dbh, $id, $comment);
  58. }
  59. sub audit_admins_end
  60. {
  61. my $self = shift;
  62. my $id = shift;
  63. my $audit_id = shift;
  64. my $dbh = ${$self->{'dbh_ref'}};
  65. return RideLogic::audit_admins_end($dbh, $id, $audit_id);
  66. }
  67. sub audit_user_card_start
  68. {
  69. my $self = shift;
  70. my $id = shift;
  71. my $comment = shift;
  72. my $dbh = ${$self->{'dbh_ref'}};
  73. return RideLogic::audit_user_card_start($dbh, $id, $comment);
  74. }
  75. sub audit_user_card_end
  76. {
  77. my $self = shift;
  78. my $id = shift;
  79. my $audit_id = shift;
  80. my $dbh = ${$self->{'dbh_ref'}};
  81. return RideLogic::audit_user_card_end($dbh, $id, $audit_id);
  82. }
  83. sub audit_user_pass_start
  84. {
  85. my $self = shift;
  86. my $id = shift;
  87. my $comment = shift;
  88. my $dbh = ${$self->{'dbh_ref'}};
  89. return RideLogic::audit_user_pass_start($dbh, $id, $comment);
  90. }
  91. sub audit_user_pass_end
  92. {
  93. my $self = shift;
  94. my $id = shift;
  95. my $audit_id = shift;
  96. my $dbh = ${$self->{'dbh_ref'}};
  97. return RideLogic::audit_user_pass_end($dbh, $id, $audit_id);
  98. }
  99. #####################
  100. # Helper functions
  101. #####################
  102. sub gen_token {
  103. my $len = shift;
  104. my ($r, $tok);
  105. my @a = qw(0 1 2 3 4 5 6 7 8 9 a b c d e f);
  106. open R, "/dev/urandom";
  107. read(R, $r, $len/2);
  108. close R;
  109. my @r = split(//, $r);
  110. for (my $i=0; $i<$len/2; $i++) {
  111. $tok .= $a[ord($r[$i]) >> 4];
  112. $tok .= $a[ord($r[$i]) & 0xf];
  113. }
  114. return $tok;
  115. }
  116. ####################################################
  117. sub initiate_session {
  118. my $self = shift;
  119. my $srv_tok = shift;
  120. my $usr_tok = shift;
  121. my $ip = shift;
  122. my $dbh = ${$self->{'dbh_ref'}};
  123. $dbh->begin_work();
  124. my $q = $self->prepare("insert into
  125. org_api_session (timestamp, server_token, user_token, ip, active)
  126. values ( now(), ?, ?, ?, 1)");
  127. $q->execute($srv_tok, $usr_tok, $ip) || return 0;
  128. $dbh->commit();
  129. return 1;
  130. }
  131. ####################################################
  132. sub get_api_server_session_age {
  133. my $self = shift;
  134. my $pass = shift;
  135. my $tok = shift;
  136. my $ip = shift;
  137. my ($query, $result);
  138. my $dbh = ${$self->{'dbh_ref'}};
  139. $query = $dbh->prepare("select time_to_sec( timediff( now(), timestamp)) sec, server_token, user_token, ip, active
  140. from org_api_session
  141. where active = 1 and ip = ? and sha1( concat( ? , server_token )) = ? limit 1");
  142. $result = $query->execute($ip, $pass, $tok);
  143. my $row = $query->fetchrow_hashref;
  144. return -1 if (!$row);
  145. return $row->{'sec'};
  146. }
  147. ####################################################
  148. sub get_api_user_session_age {
  149. my $self = shift;
  150. my $pass = shift;
  151. my $tok = shift;
  152. my $ip = shift;
  153. my ($query, $result);
  154. my $dbh = ${$self->{'dbh_ref'}};
  155. $query = $self->prepare("select time_to_sec( timediff( now(), timestamp)) sec,
  156. server_token,
  157. user_token,
  158. ip,
  159. active
  160. from org_api_session
  161. where active = 1
  162. and ip = ?
  163. and sha1( concat( ? , user_token )) = ?
  164. limit 1");
  165. $result = $query->execute($ip, $pass, $tok);
  166. my $row = $query->fetchrow_hashref;
  167. return -1 if (!$row);
  168. return $row->{'sec'};
  169. }
  170. ####################################################
  171. sub deactivate_session {
  172. my $self = shift;
  173. my $pass = shift;
  174. my $tok = shift;
  175. my $ip = shift;
  176. my ($query, $result);
  177. my $dbh = ${$self->{'dbh_ref'}};
  178. $query = $self->prepare("update org_api_session
  179. set active = 0
  180. where ip = ?
  181. and active = 1
  182. and sha1(concat(?,server_token)) = ?");
  183. $result = $query->execute($ip, $pass, $tok);
  184. }
  185. ####################################################
  186. ####################################################
  187. sub set_user_reset_attempts {
  188. my $self = shift;
  189. my $user_id = shift;
  190. my $n = shift;
  191. my ($query, $result);
  192. my $dbh = ${$self->{'dbh_ref'}};
  193. my $audit_id = $self->audit_users_start($dbh, $user_id, "RideLogicAPIQueryWrapper::set_user_reset_attempts : updating reset attempts");
  194. $query = $self->prepare("update users set reset_attempts = ? where userid = ?");
  195. $result = $query->execute($n, $user_id);
  196. $self->audit_users_end($dbh, $user_id, $audit_id);
  197. }
  198. ####################################################
  199. sub update_user_reset_attempts {
  200. my $self = shift;
  201. my $user_id = shift;
  202. my ($query, $result);
  203. my $dbh = ${$self->{'dbh_ref'}};
  204. $dbh->begin_work();
  205. my $audit_id = $self->audit_users_start($dbh, $user_id, "ridelogic_web_api: updating reset attempts");
  206. $query = $self->prepare("update users set reset_attempts = 0 where userid = ?");
  207. $result = $query->execute($user_id);
  208. $self->audit_users_end($dbh, $user_id, $audit_id);
  209. $dbh->commit();
  210. }
  211. ##########################
  212. #
  213. # ...
  214. #
  215. ##########################
  216. sub create_register_email {
  217. my $self = shift;
  218. my $registration_token = shift;
  219. my $email = shift;
  220. my $FUNC_NAME = "create_register_email";
  221. my ($query, $result, $row);
  222. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  223. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  224. # $self->begin_work();
  225. $query = $self->prepare("insert into org_api_register_email (timestamp, token, active, email) values ( now() , ?, ?, ?)");
  226. $result = $query->execute( $registration_token, 1, $email);
  227. # $self->commit();
  228. $self->unlock_commit() if $lock_local;
  229. return 1;
  230. }
  231. sub get_register_email_info {
  232. my $self = shift;
  233. my $registration_token = shift;
  234. my $FUNC_NAME = "get_register_email_info";
  235. my ($query, $result, $row);
  236. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  237. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  238. $query = $self->prepare("select timestamp,
  239. token,
  240. time_to_sec(timediff(now(), timestamp)) sec,
  241. email
  242. from org_api_register_email
  243. where token = ? and active = 1
  244. limit 1");
  245. $result = $query->execute( $registration_token );
  246. $row = $query->fetchrow_arrayref;
  247. if (!$row)
  248. {
  249. $self->unlock_rollback() if $lock_local;
  250. return (-1, undef);
  251. }
  252. my ($sec, $email) = ($row->[2], $row->[3]);
  253. $self->unlock_commit() if $lock_local;
  254. return ($row->[2], $row->[3]);
  255. }
  256. ####################################################
  257. sub deactivate_register_email {
  258. my $self = shift;
  259. my $registration_token = shift;
  260. my $FUNC_NAME = "deactivate_register_email";
  261. my ($query, $result, $row);
  262. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  263. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  264. $query = $self->prepare("update org_api_register_email set active = 0 where token = ?");
  265. $result = $query->execute($registration_token);
  266. $self->unlock_commit() if $lock_local;
  267. return 1;
  268. }
  269. ####################################################
  270. sub insert_password_reset {
  271. my $self = shift;
  272. my $token = shift;
  273. my $userid = shift;
  274. my $email = shift;
  275. my $FUNC_NAME = "insert_password_reset";
  276. my ($query, $result, $row);
  277. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  278. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  279. $query = $self->prepare("insert into org_api_password_reset (timestamp, token, userid, email, active) values ( now() , ?, ?, ?, 1)");
  280. $result = $query->execute( $token, $userid, $email );
  281. $self->unlock_commit() if $lock_local;
  282. return 1;
  283. }
  284. ##########
  285. sub deactivate_stale_password_resets {
  286. my $self = shift;
  287. my $token = shift;
  288. my $userid = shift;
  289. my $FUNC_NAME = "deactivate_stale_password_resets";
  290. my ($query, $result, $row);
  291. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  292. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  293. $query = $self->prepare("update org_api_password_reset set active = 0 where userid = ? and token != ?");
  294. $result = $query->execute( $userid, $token );
  295. $self->unlock_commit() if $lock_local;
  296. return 1;
  297. }
  298. ##########
  299. sub increment_user_reset_attempts {
  300. my $self = shift;
  301. my $userid = shift;
  302. my $FUNC_NAME = "increment_user_reset_attempts";
  303. my ($query, $result, $row);
  304. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  305. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  306. my %thash;
  307. my $r =
  308. $self->GetUser(\%thash, { UserId => $userid } );
  309. if (!$r)
  310. {
  311. $self->unlock_rollback() if $lock_local;
  312. return undef;
  313. }
  314. my $new_reset_attempts = $thash{ResetAttempts}+1;
  315. %thash = ();
  316. $r =
  317. $self->SetUser( \%thash, { UserId => $userid, ResetAttempts => $new_reset_attempts } );
  318. if (!$r)
  319. {
  320. $self->unlock_rollback() if $lock_local;
  321. return undef;
  322. }
  323. $self->unlock_commit() if $lock_local;
  324. return 1;
  325. }
  326. ##########
  327. sub get_password_reset_request_age {
  328. my $self = shift;
  329. my $tok = shift;
  330. my $FUNC_NAME = 'get_password_reset_request_age';
  331. my ($query, $result, $row);
  332. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  333. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  334. $query = $self->prepare("select time_to_sec(timediff(now(), timestamp)) sec
  335. from org_api_password_reset where token = ? and active = 1
  336. order by timestamp desc
  337. limit 1");
  338. $result = $query->execute($tok);
  339. $row = $query->fetchrow_arrayref;
  340. if (!$row)
  341. {
  342. $self->unlock_rollback() if $lock_local;
  343. return undef;
  344. }
  345. $self->unlock_commit() if $lock_local;
  346. return $row->[0];
  347. }
  348. ##########
  349. sub get_password_reset_request_user_id {
  350. my $self = shift;
  351. my $tok = shift;
  352. my $FUNC_NAME = 'get_password_reset_request_user_id';
  353. my ($query, $result, $row);
  354. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  355. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  356. $query = $self->prepare("select userid
  357. from org_api_password_reset where token = ? and active = 1
  358. order by timestamp desc
  359. limit 1");
  360. $result = $query->execute($tok);
  361. $row = $query->fetchrow_arrayref;
  362. if (!$row)
  363. {
  364. $self->unlock_rollback() if $lock_local;
  365. return undef;
  366. }
  367. $self->unlock_commit() if $lock_local;
  368. return $row->[0];
  369. }
  370. ##########
  371. sub deactivate_password_reset_for_user {
  372. my $self = shift;
  373. my $userid = shift;
  374. my $FUNC_NAME = 'deactivate_password_reset';
  375. my ($query, $r);
  376. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  377. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  378. $query = $self->prepare("update org_api_password_reset set active = 0 where userid = ? ");
  379. $r = $query->execute( $userid );
  380. $self->unlock_commit() if $lock_local;
  381. }
  382. ##########
  383. my %function_locked_table_map = (
  384. '_common' => { 'user_card' => 'w',
  385. 'user_pass' => 'w',
  386. 'active_rider_table' => 'w',
  387. 'audit_user_pass' => 'w',
  388. 'audit_user_card' => 'w',
  389. 'org_card_order_queue' => 'w',
  390. 'diagnostic_log' => 'w',
  391. 'groups' => 'r',
  392. 'users' => 'r',
  393. 'admins' => 'r',
  394. 'rule_class' => 'r',
  395. 'rule_mappings' => 'r',
  396. 'org_api_session' => 'w',
  397. 'org_default_card_value' => 'r',
  398. 'org_default_pass_value' => 'r' },
  399. # inhered from common
  400. 'GetCard' => '_common',
  401. 'GetCards' => '_common',
  402. 'IssueBlankCard' => '_common',
  403. 'AddCard' => '_common',
  404. 'TransferCard' => '_common',
  405. 'RemoveCard' => '_common',
  406. 'GetPendingQueueCard' => '_common',
  407. 'ProcessPendingQueue' => '_common',
  408. 'RemovePendingQueue' => '_common',
  409. 'insert_active_rider_table' => '_common',
  410. 'CreateCard' => '_common',
  411. 'RemovePass' => '_common',
  412. 'TransferPass' => '_common',
  413. 'AddPass' => '_common',
  414. # explicit
  415. 'get_user_id' => { 'users' => 'r' , 'groups' => 'r' } ,
  416. 'CreateUser' => { 'users' => 'w', 'audit_users' => 'w' , 'groups' => 'r' } ,
  417. 'RemoveUser' => { 'users' => 'w', 'user_card' => 'w', 'audit_users' => 'w' , 'audit_user_card' => 'w', 'groups' => 'r' } ,
  418. 'GetUser' => { 'users' => 'r' , 'groups' => 'r' } ,
  419. 'SetUser' => { 'users' => 'w', 'audit_users' => 'w' , 'groups' => 'r' } ,
  420. 'username_exists' => { 'users' => 'r' } ,
  421. 'valid_user' => { 'users' => 'r' } ,
  422. 'get_default_mag_track' => { 'org_default_card_value' => 'r' } ,
  423. 'get_default_rflength' => { 'org_default_card_value' => 'r' } ,
  424. 'get_default_rfsite' => { 'org_default_card_value' => 'r' } ,
  425. 'construct_mag_token' => { 'org_default_card_value' => 'r' } ,
  426. 'construct_rfid_token' => { 'org_default_card_value' => 'r' } ,
  427. 'construct_user_card_credential_match' => { 'org_default_card_value' => 'r', 'groups' => 'r' } ,
  428. 'update_user_card' => { 'audit_user_card' => 'w', 'user_card' => 'w' } ,
  429. 'GetDefaultCardGroupInfo' => { 'groups' => 'r' } ,
  430. 'get_group_name' => { 'groups' => 'r' } ,
  431. 'get_user_pass_group_name' => { 'user_card' => 'r', 'user_pass' => 'r', 'groups' => 'r' } ,
  432. 'get_admin_group_name' => { 'groups' => 'r', 'admins' => 'r' } ,
  433. 'get_group_id' => { 'groups' => 'r' } ,
  434. # 'get_entry_group_name' => { 'groups' => 'r', $table => 'r' } ,
  435. 'disassociate_user_from_card' => { 'audit_user_card' => 'w', 'user_card' => 'w' } ,
  436. 'associate_user_to_card' => { 'audit_user_card' => 'w', 'user_card' => 'w' } ,
  437. 'GetIthacaCollegeLogicalCardId' => { 'user_card' => 'r', 'groups' => 'r', 'org_default_card_value' => 'r' } ,
  438. 'get_user_card_userid' => { 'user_card' => 'r' } ,
  439. 'get_user_card_group_id' => { 'user_card' => 'r' } ,
  440. 'GetLogicalCardId' => { 'org_default_card_value' => 'r', 'user_card' => 'r' } ,
  441. 'user_card_active_pass_count' => { 'user_pass' => 'r' } ,
  442. 'pending_card' => { 'user_card' => 'r' } ,
  443. 'delete_user_card_from_active_rider_table' => { 'active_rider_table' => 'w' } ,
  444. 'get_active_rider_table' => { 'active_rider_table' => 'r' } ,
  445. 'deactivate_user_card' => { 'audit_user_card' => 'w', 'user_card' => 'w' } ,
  446. 'user_card_credential_exists' => { 'user_card' => 'r' } ,
  447. 'insert_user_card' => { 'audit_user_card' => 'w', 'user_card' => 'w' } ,
  448. 'validate_active_rider_table_logical_card_id' => { 'active_rider_table' => 'r' } ,
  449. 'validate_rule' => { 'rule_mappings' => 'r', 'rule_class' => 'r' } ,
  450. 'get_default_rule' => { 'rule_mappings' => 'r' } ,
  451. 'get_rule_class' => { 'rule_class' => 'r' } ,
  452. 'active_user_card_exists' => { 'org_default_card_value' => 'r', 'user_card' => 'r' } ,
  453. 'insert_user_pass' => { 'audit_user_pass' => 'w', 'user_pass' => 'w' } ,
  454. 'get_user_pass_logical_card_id' => { 'user_pass' => 'r' } ,
  455. 'GetUserPass' => { 'user_card' => 'r', 'user_pass' => 'r', 'rule_class' => 'r' } ,
  456. 'GetPassesOnCard' => { 'org_default_card_value' => 'r', 'user_card' => 'r', 'user_pass' => 'r', 'rule_class' => 'r', 'groups' => 'r' } ,
  457. 'user_card_has_active_pass' => { 'user_pass' => 'r' } ,
  458. 'activate_user_card_pass' => { 'user_pass' => 'w' } ,
  459. 'user_card_pass_count' => { 'user_pass' => 'r' } ,
  460. 'get_next_queue_order' => { 'user_pass' => 'r' } ,
  461. 'deactivate_user_pass' => { 'audit_user_pass' => 'w', 'user_pass' => 'w', 'user_card' => 'r', 'rule_class' => 'r' } ,
  462. 'update_user_pass' => { 'audit_user_pass' => 'w', 'user_pass' => 'w' } ,
  463. 'get_pass_type_and_name' => { 'rule_class' => 'r', 'rule_mappings' => 'r' } ,
  464. 'GetPricePoints' => { 'user_card' => 'r', 'groups' => 'r', 'org_default_card_value' => 'r', 'org_default_pass_value' => 'r', 'price_point' => 'r' } ,
  465. 'check_dup_billing_log' => { 'billing_log' => 'r' } ,
  466. 'insert_billing_log' => { 'billing_log' => 'w' } ,
  467. 'diagnostic_log' => { 'diagnostic_log' => 'w' } ,
  468. 'api_log' => { 'org_api_log' => 'w' } ,
  469. 'admin_exists' => { 'admins' => 'r' } ,
  470. 'get_admin_id' => { 'admins' => 'r' } ,
  471. 'CreateAdmin' => { 'admins' => 'w', 'audit_admins' => 'w', 'groups' => 'r' } ,
  472. 'GetAdmin' => { 'admins' => 'r', 'groups' => 'r' } ,
  473. 'SetAdmin' => { 'admins' => 'w', 'audit_admins' => 'w', 'groups' => 'r' } ,
  474. 'RemoveAdmin' => { 'admins' => 'w', 'audit_admins' => 'w' },
  475. 'GetPendingQueue' => { 'org_card_order_queue' => 'r', user_card => 'r', 'org_default_card_value' => 'r', groups => 'r' },
  476. 'GetPassOptions' => { 'pass_option' => 'r', 'admins' => 'r', 'groups' => 'r', 'rule_class' => 'r', 'rule_mappings' => 'r', 'org_default_pass_value' => 'r' },
  477. 'SearchCards' => { 'user_card' => 'r', 'users' => 'r', 'groups' => 'r' },
  478. 'SearchUsers' => { 'user_card' => 'r', 'users' => 'r', 'groups' => 'r' },
  479. 'SearchAdmins' => { 'admins' => 'r', 'groups' => 'r' },
  480. 'create_register_email' => { 'org_api_register_email' => 'w' },
  481. 'get_register_email_info' => { 'org_api_register_email' => 'r' },
  482. 'deactivate_register_email' => { 'org_api_register_email' => 'w' },
  483. 'insert_password_reset' => { 'org_api_password_reset' => 'w' },
  484. 'increment_user_reset_attempts' => { 'users' => 'w', 'audit_users' => 'w' } ,
  485. 'get_password_reset_request_age' => { 'org_api_password_reset' => 'r' } ,
  486. 'get_password_reset_request_user_id' => { 'org_api_password_reset' => 'r' } ,
  487. 'deactivate_password_reset_for_user' => { 'org_api_password_reset' => 'w' } ,
  488. 'get_user_group_name' => { 'users' => 'r', 'groups' => 'r' },
  489. # inhereted
  490. 'get_user_card_group_name' => 'GetCard',
  491. 'get_dest_group_name' => 'get_user_card_group_name',
  492. 'get_dest_user_card_group_name' => 'GetCard',
  493. 'GetDestLogicalCardId' => 'GetLogicalCardId',
  494. 'confirm_card_user_id' => 'GetCard',
  495. # none
  496. 'valid_pass_param' => {}
  497. );
  498. #
  499. # instead of having each function list the tables it needs,
  500. # maybe store them in the database and retrieve them as needed?
  501. # will consider for later.
  502. sub get_table_access_permissions_for_function {
  503. my $self = shift;
  504. my $func_name = shift;
  505. my $key;
  506. my $val;
  507. my $max_jump = scalar(keys(%function_locked_table_map));
  508. $key = $func_name;
  509. return undef if !exists($function_locked_table_map{$key});
  510. for (my $cur=0; $cur < $max_jump; $cur++) {
  511. $val = $function_locked_table_map{$key};
  512. return $val if (ref($val) eq 'HASH');
  513. $key = $val;
  514. }
  515. return undef;
  516. }
  517. sub begin_locked_transaction_for_function {
  518. my $self = shift;
  519. my $func_name = shift;
  520. my $h = $self->get_table_access_permissions_for_function($func_name);
  521. return undef if !$h;
  522. return undef if scalar(keys(%$h))==0;
  523. return $self->begin_locked_transaction( $h ) ;
  524. }
  525. sub begin_locked_transaction_for_functions {
  526. my $self = shift;
  527. # my $faref = shift;
  528. my %lhash;
  529. # foreach my $func (@$faref)
  530. foreach my $func (@_)
  531. {
  532. my $r = $self->get_table_access_permissions_for_function($func);
  533. #return undef if !$r;
  534. foreach my $k (keys(%$r))
  535. {
  536. # upgrade read access to write
  537. # but not the other way around
  538. if ( !exists($lhash{$k}) )
  539. {
  540. $lhash{$k} = $r->{$k};
  541. }
  542. else
  543. {
  544. $lhash{$k} = 'w' if ($r->{$k} eq 'w');
  545. }
  546. }
  547. }
  548. return $self->begin_locked_transaction(\%lhash);
  549. }
  550. ## same as above but allow for additional tables to be locked
  551. sub begin_locked_transaction_for_functions_and_tables {
  552. my $self = shift;
  553. my $func_aref = shift;
  554. my $table_href = shift;
  555. my %lhash;
  556. foreach my $func (@$func_aref)
  557. {
  558. my $r = $self->get_table_access_permissions_for_function($func);
  559. #return undef if !$r;
  560. foreach my $k (keys(%$r))
  561. {
  562. # upgrade read access to write
  563. # but not the other way around
  564. if ( !exists($lhash{$k}) )
  565. {
  566. $lhash{$k} = $r->{$k};
  567. }
  568. else
  569. {
  570. $lhash{$k} = 'w' if ($r->{$k} eq 'w');
  571. }
  572. }
  573. }
  574. foreach my $table (keys(%$table_href))
  575. {
  576. $lhash{$table} = $table_href->{$table}
  577. }
  578. return $self->begin_locked_transaction(\%lhash);
  579. }
  580. ##########
  581. #sub lock_common {
  582. # my $self = shift;
  583. #
  584. ## my $lock_tables =
  585. ## $self->prepare("lock tables user_card write, " .
  586. ## " user_pass write, " .
  587. ## " active_rider_table write, " .
  588. ## " audit_user_pass write, " .
  589. ## " audit_user_card write, " .
  590. ## " org_card_order_queue write, " .
  591. ## " diagnostic_log write, " .
  592. ## " groups read, " .
  593. ## " users read, " .
  594. ## " rule_class read, " .
  595. ## " rule_mappings read, " .
  596. ## " org_default_card_value read, " .
  597. ## " org_default_pass_value read "
  598. ## );
  599. ## $lock_tables->execute();
  600. ## $self->lock_active(1);
  601. #
  602. ## $self->begin_locked_transaction_for_function("_common");
  603. #
  604. #}
  605. sub begin_locked_transaction_common {
  606. my $self = shift;
  607. # $self->lock_common();
  608. # $self->begin_work();
  609. $self->begin_locked_transaction_for_function("_common");
  610. }
  611. sub unlock {
  612. my $self = shift;
  613. my $unlock_tables = $self->prepare("unlock tables");
  614. $unlock_tables->execute();
  615. $self->lock_active(0);
  616. }
  617. sub begin_locked_transaction {
  618. my $self = shift;
  619. my $href = shift;
  620. my $n=0;
  621. my $query_str = "lock tables" ;
  622. while ( my ($k, $v) = each(%$href) )
  623. {
  624. $query_str .= "," if ($n++)>0;
  625. $query_str .= " $k ";
  626. if ( $v =~ m/^[rR]/ )
  627. {
  628. $query_str .= "read";
  629. }
  630. elsif ($v =~ m/^[wW]/ )
  631. {
  632. $query_str .= "write";
  633. }
  634. }
  635. $self->lock_active(1);
  636. my $query =
  637. $self->prepare($query_str);
  638. $query->execute();
  639. $self->begin_work();
  640. return 1;
  641. }
  642. sub unlock_rollback {
  643. my $self = shift;
  644. $self->rollback();
  645. my $query = $self->prepare("unlock tables");
  646. $query->execute();
  647. $self->lock_active(0);
  648. return 1;
  649. # return $self->rollback();
  650. }
  651. sub unlock_commit {
  652. my $self = shift;
  653. my $query = $self->prepare("unlock tables");
  654. $query->execute();
  655. $self->lock_active(0);
  656. return $self->commit();
  657. }
  658. ####################################################
  659. ##
  660. ## User Functions
  661. ##
  662. ####################################################
  663. my %users_field_map =
  664. ( userid => 'UserId',
  665. username => 'UserName',
  666. passwordhash => 'PasswordHash',
  667. first_name => 'FirstName',
  668. last_name => 'LastName',
  669. phone => 'Phone',
  670. email => 'Email',
  671. address => 'Address',
  672. city => 'City',
  673. state => 'State',
  674. zip => 'ZIP',
  675. comment => 'Comment',
  676. shipping_name => 'ShippingName',
  677. shipping_address => 'ShippingAddress',
  678. shipping_city => 'ShippingCity',
  679. shipping_state => 'ShippingState',
  680. shipping_zip => 'ShippingZIP',
  681. shipping_country_code => 'ShippingCountryCode',
  682. shipping_country_name => 'ShippingCountryName',
  683. reset_attempts => 'ResetAttempts',
  684. active => 'Active',
  685. group_id => 'GroupId'
  686. );
  687. ####################################################
  688. sub get_user_id {
  689. my $self = shift;
  690. my $phash = shift;
  691. my $FUNC_NAME = 'get_user_id';
  692. my ($query, $result, $row);
  693. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  694. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  695. my $credential_match = " active = 1 ";
  696. my @credential_val;
  697. if ( defined($phash->{'UserName'}) )
  698. {
  699. $credential_match .= " and username = ? ";
  700. push @credential_val , $phash->{'UserName'};
  701. }
  702. if ( defined($phash->{'UserId'}) )
  703. {
  704. $credential_match .= " and userid = ? ";
  705. push @credential_val, $phash->{'UserId'};
  706. }
  707. if ( defined($phash->{'PasswordHash'}) )
  708. {
  709. $credential_match .= " and passwordhash = ? ";
  710. push @credential_val, $phash->{'PasswordHash'};
  711. }
  712. return undef if scalar(@credential_val)==0;
  713. ###
  714. if ( defined($phash->{'GroupId'}) )
  715. {
  716. $credential_match .= " and group_id = ? ";
  717. push @credential_val, $phash->{'GroupId'};
  718. }
  719. elsif ( defined($phash->{'GroupName'}) )
  720. {
  721. $credential_match .= " and group_id = ? ";
  722. push @credential_val, $self->get_group_id( $phash->{'GroupName'} );
  723. }
  724. ###
  725. $query = $self->prepare( "select userid " .
  726. " from users " .
  727. " where $credential_match " .
  728. " limit 1 ");
  729. $result = $query->execute(@credential_val);
  730. $row = $query->fetchrow_arrayref;
  731. # $rhash->{'UserId'} = $row->[0];
  732. if (!$row)
  733. {
  734. $self->unlock_rollback() if $lock_local;
  735. return undef;
  736. }
  737. $self->unlock_commit() if $lock_local;
  738. return $row->[0];
  739. }
  740. ####################################################
  741. sub CreateUser {
  742. my $self = shift;
  743. my $rhash = shift;
  744. my $phash = shift;
  745. my ($query, $result);
  746. my $FUNC_NAME = "CreateUser";
  747. my %blacklist_field = ( active => 1, created => 1, reset_attempts => 1, userid => 1 );
  748. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  749. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  750. if ( !defined($phash->{'UserName'}) ||
  751. $self->username_exists($phash->{'UserName'}) )
  752. {
  753. $rhash->{'Reason'} = "Invalid username";
  754. $self->unlock_rollback() if $lock_local;
  755. return undef;
  756. }
  757. # default group or group name to group id conversion
  758. if ( !defined($phash->{GroupId}) )
  759. {
  760. my $group_id = $self->get_group_id( $phash->{GroupName} || $DEFAULT_GROUP_NAME );
  761. if (!$group_id)
  762. {
  763. $rhash->{'Reason'} = "Invalid GroupName";
  764. $self->unlock_rollback() if $lock_local;
  765. return undef;
  766. }
  767. $phash->{GroupId} = $group_id;
  768. # push @db_field, 'group_id';
  769. # push @param, $group_id;
  770. }
  771. my @db_field;
  772. my @param;
  773. while (my ($k, $v) = each(%users_field_map) )
  774. {
  775. next if ( $blacklist_field{lc($k)} );
  776. push @db_field, $k;
  777. push @param, $phash->{$v};
  778. }
  779. my $audit_id = $self->audit_users_start(undef, "$PACKAGE_NAME: $FUNC_NAME");
  780. $query = $self->prepare("insert into users " .
  781. " ( created, active, reset_attempts, " . join(", ", @db_field) . " ) values " .
  782. " ( now(), 1, 0 " . ", ?"x(scalar(@db_field)) . " )");
  783. $result = $query->execute(@param);
  784. my $user_id = $self->last_insert_id();
  785. $self->audit_users_end($user_id, $audit_id);
  786. $query = $self->prepare("select userid, " . join(', ', @db_field) . " from users where userid = ?");
  787. $query->execute($user_id);
  788. my $href = $query->fetchrow_hashref;
  789. for (my $i=0; $i<scalar(@db_field); $i++)
  790. {
  791. $rhash->{$users_field_map{$db_field[$i]}} = $href->{$db_field[$i]};
  792. }
  793. $rhash->{'UserId'} = $href->{'userid'};
  794. $self->unlock_commit() if $lock_local;
  795. return 1;
  796. }
  797. ####################################################
  798. sub RemoveUser {
  799. my $self = shift;
  800. my $rhash = shift;
  801. my $phash = shift;
  802. my ($query, $result);
  803. my $FUNC_NAME = "RemoveUser";
  804. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  805. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  806. my $user_id = $self->get_user_id($phash);
  807. if (!$user_id)
  808. {
  809. $rhash->{'Reason'} = "Invalid user credential";
  810. $self->unlock_rollback() if $lock_local;
  811. return undef;
  812. }
  813. my %cards;
  814. my $r = $self->GetCards( \%cards, { UserId => $user_id } );
  815. if (!$r)
  816. {
  817. $rhash->{'Reason'} = $cards{'Reason'};
  818. $self->unlock_rollback() if $lock_local;
  819. return undef;
  820. }
  821. my $n_card = $cards{NCard};
  822. for (my $k=0; $k < $n_card ; $k++)
  823. {
  824. my $ind = "";
  825. $ind = "[$k]" if $k;
  826. $self->disassociate_user_from_card($cards{"CardId$ind"});
  827. }
  828. my $audit_id = $self->audit_users_start(undef, "$PACKAGE_NAME: $FUNC_NAME");
  829. $query = $self->prepare("update users set active = 0 where userid = ? ");
  830. $result = $query->execute($user_id);
  831. $self->audit_users_end($user_id, $audit_id);
  832. $self->unlock_commit() if $lock_local;
  833. return 1;
  834. }
  835. ####################################################
  836. sub GetUser {
  837. my $self = shift;
  838. my $rhash = shift;
  839. my $phash = shift;
  840. my ($query, $result);
  841. my $FUNC_NAME = "GetUser";
  842. # my %blacklist_field = ( 'passwordhash' => 1 );
  843. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  844. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  845. my $userid = $self->get_user_id($phash);
  846. if (!$userid)
  847. {
  848. $rhash->{'Reason'} = "Invalid user credential";
  849. $self->unlock_rollback() if $lock_local;
  850. return undef;
  851. }
  852. my $count=0;
  853. my $fields;
  854. while ( my ($k, $v) = each(%users_field_map) )
  855. {
  856. # next if ( $blacklist_field{lc($k)} );
  857. $fields .= ", " if ($count++);
  858. $fields .= " users.$k $v ";
  859. }
  860. $query = $self->prepare("select $fields , groups.group_name GroupName " .
  861. " from users , groups ".
  862. " where users.userid = ? " .
  863. " and users.active = 1 " .
  864. " and users.group_id = groups.group_id " .
  865. " limit 1");
  866. $query->execute($userid);
  867. my $row = $query->fetchrow_hashref;
  868. if (!$row)
  869. {
  870. $rhash->{'Reason'} = "Invalid User";
  871. $self->unlock_rollback() if $lock_local;
  872. return undef;
  873. }
  874. $self->unlock_commit() if $lock_local;
  875. while ( my ($k, $v) = each(%$row) )
  876. {
  877. $rhash->{$k} = $v;
  878. }
  879. return 1;
  880. }
  881. ####################################################
  882. sub SetUser {
  883. my $self = shift;
  884. my $rhash = shift;
  885. my $phash = shift;
  886. my ($query, $result, $i, $j);
  887. my $FUNC_NAME= "SetUser";
  888. my $update_fields;
  889. my @update_val;
  890. my %blacklist_field = ( username => 1, userid => 1 );
  891. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  892. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  893. # could be updating password. only look up by username, userid and group
  894. my $userid = $self->get_user_id(
  895. {
  896. UserName => $phash->{UserName},
  897. UserId => $phash->{UserId},
  898. GroupId => $phash->{GroupId},
  899. GroupName => $phash->{GroupName}
  900. }
  901. );
  902. if (!defined($userid))
  903. {
  904. $rhash->{'Reason'} = "Invalid user credential";
  905. $self->unlock_rollback() if $lock_local;
  906. return undef;
  907. }
  908. while ( my ($k, $v) = each(%users_field_map) )
  909. {
  910. next if $blacklist_field{lc($k)} || !exists($phash->{$v});
  911. $update_fields .= ", " if $update_fields;
  912. $update_fields .= " $k = ? ";
  913. push @update_val, $phash->{$v};
  914. }
  915. # special consideration for groups
  916. if ( !defined($phash->{GroupId}) )
  917. {
  918. if ( defined($phash->{GroupName}) )
  919. {
  920. my $group_id = $self->get_group_id( $phash->{GroupName} );
  921. if ( !$group_id )
  922. {
  923. $rhash->{'Reason'} = "Invalid GroupName";
  924. $self->unlock_rollback() if $lock_local;
  925. return undef;
  926. }
  927. $update_fields .= ", " if $update_fields;
  928. $update_fields .= " group_id = ? ";
  929. push @update_val, $group_id;
  930. }
  931. }
  932. if (scalar(@update_val)==0)
  933. {
  934. $rhash->{'Reason'} = "Nothing to update";
  935. $self->unlock_rollback() if $lock_local;
  936. return undef;
  937. }
  938. push @update_val, $userid;
  939. my $audit_id =
  940. $self->audit_users_start($userid, "$PACKAGE_NAME: $FUNC_NAME");
  941. $query =
  942. $self->prepare("update users " .
  943. " set $update_fields " .
  944. " where userid = ?");
  945. $result =
  946. $query->execute(@update_val);
  947. $self->audit_users_end($userid, $audit_id );
  948. $rhash->{'UserId'} = $userid;
  949. $self->unlock_commit() if $lock_local;
  950. return 1;
  951. }
  952. ####################################################
  953. sub username_exists {
  954. my $self = shift;
  955. my $username = shift;
  956. my $FUNC_NAME = 'username_exists';
  957. my ($query, $result, $row);
  958. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  959. # $self->begin_locked_transaction( { 'users' => 'r' } ) if $lock_local;
  960. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  961. $query = $self->prepare("select count(userid) num " .
  962. " from users " .
  963. " where username = ? " .
  964. " and active = 1 ");
  965. $result = $query->execute($username);
  966. $row = $query->fetchrow_arrayref;
  967. $self->unlock_commit() if $lock_local;
  968. return ($row->[0] != 0);
  969. }
  970. ####################################################
  971. sub valid_user {
  972. my $self = shift;
  973. my $userid = shift;
  974. my $FUNC_NAME = 'valid_user';
  975. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  976. # $self->begin_locked_transaction(
  977. # {
  978. # 'users' => 'r'
  979. # }
  980. # ) if $lock_local;
  981. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  982. my $query =
  983. $self->prepare("select count(userid) num " .
  984. " from users " .
  985. " where userid = ? " .
  986. " and username is not null " .
  987. " and passwordhash is not null");
  988. my $result =
  989. $query->execute($userid);
  990. $self->unlock_commit() if $lock_local;
  991. return ($query->fetchrow_arrayref->[0] == 1);
  992. }
  993. ####################################################
  994. ##
  995. ## Card Functions
  996. ##
  997. ####################################################
  998. my @user_card_field =
  999. qw( issued
  1000. mag_token
  1001. rfid_token
  1002. comment
  1003. userid
  1004. active
  1005. deactivated
  1006. lastused
  1007. firstused
  1008. group_id
  1009. issuetype );
  1010. my %user_card_field_map =
  1011. ( mag_token => 'MagToken',
  1012. rfid_token => 'RFIDToken',
  1013. logical_card_id => 'CardId',
  1014. active => 'Active',
  1015. comment => 'Comment',
  1016. lastused => 'LastUsed',
  1017. issued => 'Issued',
  1018. firstused => 'FirstUsed',
  1019. userid => 'UserId',
  1020. deactivated => 'Deactivated',
  1021. group_id => 'GroupId',
  1022. issuetype => 'IssueType'
  1023. );
  1024. ###########
  1025. sub get_default_mag_track
  1026. {
  1027. my $self = shift;
  1028. my $group_id = shift;
  1029. my $FUNC_NAME = 'get_default_mag_track';
  1030. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1031. # $self->begin_locked_transaction(
  1032. # {
  1033. # 'org_default_card_value' => 'r'
  1034. # }
  1035. # ) if $lock_local;
  1036. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1037. my $query =
  1038. $self->prepare("select mag_track " .
  1039. " from org_default_card_value " .
  1040. " where group_id = ? " .
  1041. " or group_id is null " .
  1042. " order by group_id desc " .
  1043. " limit 1");
  1044. $query->execute($group_id);
  1045. $self->unlock_commit() if $lock_local;
  1046. return $query->fetchrow_arrayref->[0];
  1047. }
  1048. ###########
  1049. sub get_default_rflength
  1050. {
  1051. my $self = shift;
  1052. my $group_id = shift;
  1053. my $FUNC_NAME = 'get_default_rflength';
  1054. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1055. # $self->begin_locked_transaction(
  1056. # {
  1057. # 'org_default_card_value' => 'r'
  1058. # }
  1059. # ) if $lock_local;
  1060. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1061. my $query =
  1062. $self->prepare("select rf_length " .
  1063. " from org_default_card_value " .
  1064. " where group_id = ? " .
  1065. " or group_id is null " .
  1066. " order by group_id desc " .
  1067. " limit 1");
  1068. $query->execute($group_id);
  1069. $self->unlock_commit() if $lock_local;
  1070. return $query->fetchrow_arrayref->[0];
  1071. }
  1072. ###########
  1073. sub get_default_rfsite
  1074. {
  1075. my $self = shift;
  1076. my $group_id = shift;
  1077. my $FUNC_NAME = 'get_default_rfsite';
  1078. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1079. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1080. my $query =
  1081. $self->prepare("select rf_site " .
  1082. " from org_default_card_value " .
  1083. " where group_id = ? " .
  1084. " or group_id is null " .
  1085. " order by group_id desc " .
  1086. " limit 1");
  1087. $query->execute($group_id);
  1088. $self->unlock_commit() if $lock_local;
  1089. return $query->fetchrow_arrayref->[0];
  1090. }
  1091. ###
  1092. sub construct_mag_token
  1093. {
  1094. my $self = shift;
  1095. my $phash = shift;
  1096. my $FUNC_NAME = 'construct_mag_token';
  1097. return $phash->{'MagToken'} if $phash->{'MagToken'};
  1098. return undef if !$phash->{'MagStripe'};
  1099. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1100. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1101. my $mag_track = ( $phash->{'MagTrack'} || $self->get_default_mag_track( $phash->{'GroupId'} ) );
  1102. $self->unlock_commit() if $lock_local;
  1103. return $mag_track . ":" . $phash->{'MagStripe'};
  1104. }
  1105. ###
  1106. sub construct_rfid_token
  1107. {
  1108. my $self = shift;
  1109. my $phash = shift;
  1110. my $FUNC_NAME = 'construct_rfid_token';
  1111. return $phash->{'RFIDToken'} if $phash->{'RFIDToken'};
  1112. return undef if !$phash->{'RFID'};
  1113. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1114. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1115. my $rflength = ( $phash->{'RFLength'} || $self->get_default_rflength( $phash->{'GroupId'} ) );
  1116. my $rfsite = ( $phash->{'RFSite'} || $self->get_default_rfsite( $phash->{'GroupId'} ) );
  1117. $self->unlock_commit() if $lock_local;
  1118. return $rflength. ":" . $rfsite . ":" . $phash->{'RFID'};
  1119. }
  1120. ###########
  1121. sub construct_user_card_credential_match
  1122. {
  1123. my $self = shift;
  1124. my $phash = shift;
  1125. my $FUNC_NAME = 'construct_user_card_credential_match';
  1126. my $credential_match = "true";
  1127. my @credential_val;
  1128. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1129. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1130. if (defined($phash->{'MagToken'}) || defined($phash->{'MagStripe'}) )
  1131. {
  1132. $credential_match .= " and mag_token = ? ";
  1133. push @credential_val, $self->construct_mag_token($phash);
  1134. }
  1135. if (defined($phash->{'RFIDToken'}) || defined($phash->{'RFID'}) )
  1136. {
  1137. $credential_match .= " and rfid_token = ? ";
  1138. push @credential_val, $self->construct_rfid_token($phash);
  1139. }
  1140. if (defined($phash->{'CardId'}))
  1141. {
  1142. $credential_match .= " and logical_card_id = ? ";
  1143. push @credential_val, $phash->{'CardId'};
  1144. }
  1145. return ($credential_match, \@credential_val) if (scalar(@credential_val)==0);
  1146. ###
  1147. if (defined($phash->{'GroupId'}))
  1148. {
  1149. $credential_match .= " and group_id = ? ";
  1150. push @credential_val, $phash->{'GroupId'};
  1151. }
  1152. elsif (defined($phash->{'GroupName'}))
  1153. {
  1154. $credential_match .= " and group_id = ? ";
  1155. push @credential_val, $self->get_group_id( $phash->{'GroupName'} );
  1156. }
  1157. ###
  1158. $self->unlock_commit() if $lock_local;
  1159. return ($credential_match, \@credential_val);
  1160. }
  1161. ###
  1162. sub update_user_card {
  1163. my $self = shift;
  1164. my $logical_card_id = shift;
  1165. my $param_hash = shift;
  1166. my $FUNC_NAME = "update_user_card";
  1167. return undef if !$logical_card_id;
  1168. my $str;
  1169. my @val;
  1170. while ( my ($k, $v) = each(%$param_hash) )
  1171. {
  1172. next if (!$user_card_field_map{$k});
  1173. $str .= " , " if $str;
  1174. $str .= " $k = ? ";
  1175. push @val, $v;
  1176. }
  1177. return undef if (scalar(@val)==0);
  1178. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1179. # $self->begin_locked_transaction(
  1180. # {
  1181. # 'audit_user_card' => 'w',
  1182. # 'user_card' => 'w'
  1183. # }
  1184. # ) if $lock_local;
  1185. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1186. my $audit_id =
  1187. $self->audit_user_card_start($logical_card_id, "$PACKAGE_NAME: $FUNC_NAME");
  1188. my $query =
  1189. $self->prepare("update user_card set $str where logical_card_id = ? ");
  1190. $query->execute(@val, $logical_card_id);
  1191. $self->audit_user_card_end($logical_card_id, $audit_id);
  1192. $self->unlock_commit() if $lock_local;
  1193. return 1;
  1194. }
  1195. ###########
  1196. sub GetCard {
  1197. my $self = shift;
  1198. my $rhash = shift;
  1199. my $phash = shift;
  1200. my $FUNC_NAME = 'GetCard';
  1201. my ($query, $result);
  1202. my @field;
  1203. my @db_field;
  1204. my %blacklisted_field = ( acitve => '1' );
  1205. my %thash = %$phash;
  1206. while ( my ($k, $v) = each(%user_card_field_map) )
  1207. {
  1208. next if (defined($blacklisted_field{$k}));
  1209. push @field, $v;
  1210. push @db_field, "$k $v";
  1211. }
  1212. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1213. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1214. # $phash->{GroupId} = $self->get_group_id( $phash->{GroupName} || $DEFAULT_GROUP_NAME )
  1215. # if (!$phash->{GroupId});
  1216. # my $logical_card_id =
  1217. # $self->GetLogicalCardId($phash);
  1218. my $logical_card_id;
  1219. if ($thash{CardId})
  1220. {
  1221. $logical_card_id = $self->GetLogicalCardId( { CardId => $thash{CardId} } )
  1222. }
  1223. else
  1224. {
  1225. $thash{GroupId} = $self->get_group_id( $phash->{GroupName} || $DEFAULT_GROUP_NAME )
  1226. if (!$phash->{GroupId});
  1227. $logical_card_id =
  1228. $self->GetLogicalCardId(\%thash);
  1229. }
  1230. if (!$logical_card_id)
  1231. {
  1232. $self->unlock_rollback() if $lock_local;
  1233. $rhash->{'Reason'} = "Invalid Card";
  1234. return undef;
  1235. }
  1236. $query =
  1237. $self->prepare("select user_card." . join(", user_card.", @db_field) . " , groups.group_name GroupName " .
  1238. " from user_card, groups " .
  1239. " where user_card.logical_card_id = ? " .
  1240. " and user_card.active = 1 " .
  1241. " and user_card.group_id = groups.group_id " .
  1242. " order by user_card.logical_card_id " .
  1243. " limit 1");
  1244. $result = $query->execute($logical_card_id);
  1245. my $row = $query->fetchrow_hashref;
  1246. if (!$row)
  1247. {
  1248. $self->unlock_rollback() if $lock_local;
  1249. $rhash->{'Reason'} = "Invalid Credential";
  1250. return undef;
  1251. }
  1252. ($rhash->{'MagTrack'}, $rhash->{'MagStripe'}) =
  1253. split(/:/, $row->{'MagToken'});
  1254. ($rhash->{'RFLength'}, $rhash->{'RFSite'}, $rhash->{'RFID'}) =
  1255. split(/:/, $row->{'RFIDToken'});
  1256. for (my $i=0; $i<scalar(@field); $i++)
  1257. {
  1258. next if ($field[$i] =~ /Mag(Track|Stripe)|RF(Length|Site|ID)/) and ($field[$i] ne 'RFIDToken');
  1259. $rhash->{$field[$i]} = $row->{$field[$i]};
  1260. }
  1261. $rhash->{GroupName} = $row->{GroupName};
  1262. $self->unlock_commit() if $lock_local;
  1263. return 1;
  1264. }
  1265. ####################################################
  1266. #sub get_cards {
  1267. sub GetCards {
  1268. my $self = shift;
  1269. my $rhash = shift;
  1270. my $phash = shift;
  1271. my $FUNC_NAME = 'GetCards';
  1272. my ($query, $result);
  1273. my @field;
  1274. my @db_field;
  1275. my %blacklisted_field = ( active => '1' );
  1276. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1277. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1278. # my $user_id = $self->get_user_id($phash);
  1279. my $user_id = $self->get_user_id(
  1280. {
  1281. UserName => $phash->{UserName},
  1282. UserId => $phash->{UserId},
  1283. GroupId => $phash->{UserGroupId},
  1284. GroupName => $phash->{UserGroupName}
  1285. }
  1286. );
  1287. my $max_card = $phash->{'MaxCard'};
  1288. if (!defined($user_id))
  1289. {
  1290. $self->unlock_rollback() if $lock_local;
  1291. $rhash->{'Reason'} = "Invalid UserId";
  1292. return undef;
  1293. }
  1294. while ( my ($k, $v) = each(%user_card_field_map) )
  1295. {
  1296. next if (defined($blacklisted_field{$k}));
  1297. push @field, $v;
  1298. push @db_field, "$k $v";
  1299. }
  1300. my @param;
  1301. push @param, $user_id;
  1302. my $limit;
  1303. if ($max_card)
  1304. {
  1305. $limit = " limit ? ";
  1306. push @param, $max_card;
  1307. }
  1308. $query =
  1309. $self->prepare("select " . join(", ", @db_field) . " " .
  1310. " from user_card " .
  1311. " where userid = ? " .
  1312. " and active = 1 " .
  1313. " order by CardId " .
  1314. " $limit ");
  1315. $result = $query->execute(@param);
  1316. my $k=0;
  1317. my $ind = '';
  1318. while (my $row = $query->fetchrow_hashref)
  1319. {
  1320. last if $max_card && ($k>=$max_card);
  1321. ($rhash->{"MagTrack" . $ind }, $rhash->{"MagStripe" . $ind }) =
  1322. split(/:/, $row->{'MagToken'});
  1323. ($rhash->{"RFLength" . $ind }, $rhash->{"RFSite" . $ind }, $rhash->{"RFID" . $ind }) =
  1324. split(/:/, $row->{'RFIDToken'});
  1325. for (my $i=0; $i<scalar(@field); $i++)
  1326. {
  1327. next if ($field[$i] =~ /Mag(Track|Stripe)|RF(Length|Site|ID)/) and ($field[$i] ne 'RFIDToken');
  1328. $rhash->{ $field[$i] . $ind } = $row->{$field[$i]};
  1329. }
  1330. $ind = "[" . (++$k) . "]";
  1331. }
  1332. $rhash->{'NCard'} = $k;
  1333. $self->unlock_commit() if $lock_local;
  1334. return 1;
  1335. }
  1336. ####################################################
  1337. ### DEFAULT TO ORG
  1338. ### this might need to change depending on how the
  1339. ### system evolves
  1340. #sub get_default_card_group_info {
  1341. sub GetDefaultCardGroupInfo
  1342. {
  1343. my $self = shift;
  1344. my $rhash = shift;
  1345. my $phash = shift;
  1346. my $FUNC_NAME = 'GetDefaultCardGroupInfo';
  1347. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1348. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1349. my $query =
  1350. $self->prepare("select group_id GroupId, group_name GroupName from groups where group_name = ? ");
  1351. $query->execute($DEFAULT_GROUP_NAME);
  1352. my $row = $query->fetchrow_hashref;
  1353. while ( my ($k, $v) = each(%$row) )
  1354. {
  1355. $rhash->{$k} = $v;
  1356. }
  1357. $self->unlock_commit() if $lock_local;
  1358. return 1;
  1359. }
  1360. ###
  1361. sub get_group_name {
  1362. my $self = shift;
  1363. my $phash = shift;
  1364. my $FUNC_NAME = 'get_group_name';
  1365. return $phash->{GroupName} if ($phash->{GroupName});
  1366. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1367. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1368. my $query =
  1369. $self->prepare("select group_name from groups where group_id = ?");
  1370. $query->execute($phash->{GroupId});
  1371. my $row = $query->fetchrow_arrayref;
  1372. $self->unlock_commit() if $lock_local;
  1373. return $DEFAULT_GROUP_NAME if !$row;
  1374. return $row->[0];
  1375. }
  1376. ###
  1377. sub get_user_card_group_name {
  1378. my $self = shift;
  1379. my $phash = shift;
  1380. my $FUNC_NAME = 'get_user_card_group_name';
  1381. my %r;
  1382. $self->GetCard(\%r, $phash);
  1383. return $r{GroupName};
  1384. }
  1385. ###
  1386. sub get_dest_group_name {
  1387. my $self = shift;
  1388. my $phash = shift;
  1389. my %thash;
  1390. $thash{GroupId} = $phash->{DestGroupId} if $phash->{DestGroupId};
  1391. $thash{GroupName} = $phash->{DestGroupName} if $phash->{DestGroupName};
  1392. #return $self->get_user_card_group_name(\%thash);
  1393. return $self->get_group_name(\%thash);
  1394. }
  1395. sub get_dest_user_card_group_name {
  1396. my $self = shift;
  1397. my $phash = shift;
  1398. my $to_logical_card_id = $self->GetDestLogicalCardId($phash);
  1399. my %r;
  1400. $self->GetCard(\%r, { CardId => $to_logical_card_id } );
  1401. return $r{GroupName};
  1402. }
  1403. ###
  1404. sub get_user_pass_group_name {
  1405. my $self = shift;
  1406. my $phash = shift;
  1407. my $FUNC_NAME = 'get_user_pass_group_name';
  1408. return undef if (!$phash->{PassId});
  1409. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1410. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1411. my $query =
  1412. $self->prepare("select groups.group_name
  1413. from groups,
  1414. user_card,
  1415. user_pass
  1416. where user_pass.user_pass_id = ?
  1417. and user_card.logical_card_id = user_pass.logical_card_id
  1418. and groups.group_id = user_card.group_id");
  1419. $query->execute($phash->{PassId});
  1420. my $row = $query->fetchrow_arrayref;
  1421. $self->unlock_commit() if $lock_local;
  1422. return undef if !$row;
  1423. return $row->[0];
  1424. }
  1425. ###
  1426. sub get_user_group_name {
  1427. my $self = shift;
  1428. my $phash = shift;
  1429. my $FUNC_NAME = 'get_user_group_name';
  1430. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1431. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1432. my $user_id = $self->get_user_id($phash);
  1433. my $query =
  1434. $self->prepare("select groups.group_name
  1435. from users, groups
  1436. where users.userid = ?
  1437. and users.group_id = groups.group_id ");
  1438. $query->execute($user_id);
  1439. my $row = $query->fetchrow_arrayref;
  1440. $self->unlock_commit() if $lock_local;
  1441. return undef if !$row;
  1442. return $row->[0];
  1443. #return $DEFAULT_GROUP_NAME;
  1444. }
  1445. ###
  1446. sub get_admin_group_name {
  1447. my $self = shift;
  1448. my $phash = shift;
  1449. my $FUNC_NAME = 'get_admin_group_name';
  1450. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1451. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1452. my $str = " admins.active = 1 ";
  1453. my @val;
  1454. if ($phash->{UserId})
  1455. {
  1456. $str .= " and admins.userid = ? ";
  1457. push @val, $phash->{UserId};
  1458. }
  1459. if ($phash->{UserName})
  1460. {
  1461. $str .= " and admins.username = ? ";
  1462. push @val, $phash->{UserName};
  1463. }
  1464. my $query = $self->prepare("select groups.group_name
  1465. from groups,
  1466. admins
  1467. where $str
  1468. and groups.group_id = admins.group_id");
  1469. $query->execute(@val);
  1470. my $row = $query->fetchrow_arrayref;
  1471. $self->unlock_commit() if $lock_local;
  1472. return $row->[0];
  1473. }
  1474. ###
  1475. sub get_group_id
  1476. {
  1477. my $self = shift;
  1478. my $group_name = shift;
  1479. my $FUNC_NAME = 'get_group_id';
  1480. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1481. # $self->begin_locked_transaction( { 'groups' => 'r' } ) if $lock_local;
  1482. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1483. my $query =
  1484. $self->prepare("select group_id from groups where group_name = ? ");
  1485. $query->execute($group_name);
  1486. my $row = $query->fetchrow_arrayref;
  1487. $self->unlock_commit() if $lock_local;
  1488. return undef if !$row;
  1489. return $row->[0];
  1490. }
  1491. ###
  1492. my %table_id_field = (
  1493. user_card => 'logical_card_id',
  1494. );
  1495. ###
  1496. sub get_entry_group_name
  1497. {
  1498. my $self = shift;
  1499. my $table = shift;
  1500. my $id = shift;
  1501. my $FUNC_NAME = 'get_entry_group_name';
  1502. return undef if (!$table_id_field{$table});
  1503. my $lock_local = ( $self->lock_active() ? 0 : 1);
  1504. # $self->begin_locked_transaction( { 'groups' => 'r', $table => 'r' } ) if $lock_local;
  1505. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1506. my $query =
  1507. $self->prepare("select groups.group_name " .
  1508. " from $table, groups " .
  1509. " where $table." . $table_id_field{$table} . " = ?" .
  1510. " and groups.group_id = $table.group_id");
  1511. $query->execute($id);
  1512. my $row = $query->fetchrow_arrayref;
  1513. $$self->unlock_commit() if $lock_local;
  1514. return undef if !$row;
  1515. return $row->[0];
  1516. }
  1517. ############
  1518. #sub issue_blank_card {
  1519. sub IssueBlankCard
  1520. {
  1521. my $self = shift;
  1522. my $rhash = shift;
  1523. my $phash = shift;
  1524. my $FUNC_NAME = "IssueBlankCard";
  1525. my ($query, $result);
  1526. my %blacklisted_field = ( active => 1, mag_token => 1, rfid_token => 1, issued => 1, group_id => 1 );
  1527. my @val;
  1528. my @db_field;
  1529. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1530. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1531. # my $user_id = $self->get_user_id($phash);
  1532. my $user_id = $self->get_user_id(
  1533. {
  1534. UserName => $phash->{UserName},
  1535. UserId => $phash->{UserId},
  1536. GroupId => $phash->{UserGroupId},
  1537. GroupName => $phash->{UserGroupName}
  1538. }
  1539. );
  1540. if (!defined($user_id))
  1541. {
  1542. $self->unlock_rollback() if $lock_local;
  1543. $rhash->{'Reason'} = "Invalid UserId";
  1544. return undef;
  1545. }
  1546. $phash->{UserId} = $user_id;
  1547. while ( my ($k, $v) = each(%user_card_field_map) )
  1548. {
  1549. next if defined($blacklisted_field{$k});
  1550. push @db_field, $k;
  1551. push @val, $phash->{$v};
  1552. }
  1553. my %group_hash;
  1554. $self->GetDefaultCardGroupInfo(\%group_hash, $phash);
  1555. my $group_id = $group_hash{'GroupId'};
  1556. my $audit_id
  1557. = $self->audit_user_card_start(undef, "$PACKAGE_NAME: $FUNC_NAME");
  1558. $query =
  1559. $self->prepare("insert into user_card ( issued, active, group_id, " . join(", ", @db_field) . " ) " .
  1560. "values ( now(), 1, ? " . ", ?"x(scalar(@db_field)) . " ) ");
  1561. $result =
  1562. $query->execute($group_id, @val);
  1563. $rhash->{'CardId'} = $self->last_insert_id();
  1564. $self->audit_user_card_end($rhash->{'CardId'}, $audit_id );
  1565. $query =
  1566. $self->prepare("insert into org_card_order_queue (userid, logical_card_id, created, processed, comment, pending) " .
  1567. "values (?, ?, now(), null, null, 1)");
  1568. $result =
  1569. $query->execute($user_id, $rhash->{'CardId'});
  1570. $self->unlock_commit() if $lock_local;
  1571. # DO NOT put newly issued card into active_rider_table, will be handled whent he entry is removed from ordered queue
  1572. return 1;
  1573. }
  1574. sub disassociate_user_from_card
  1575. {
  1576. my $self = shift;
  1577. my $card_id = shift;
  1578. my $FUNC_NAME = "disassociate_user_from_card";
  1579. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1580. # $self->begin_locked_transaction(
  1581. # {
  1582. # 'audit_user_card' => 'w',
  1583. # 'user_card' => 'w'
  1584. # }
  1585. # ) if $lock_local;
  1586. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1587. my $audit_id =
  1588. $self->audit_user_card_start($card_id, "$PACKAGE_NAME: $FUNC_NAME");
  1589. my $query =
  1590. $self->prepare("update user_card " .
  1591. " set userid = null " .
  1592. " where logical_card_id = ?");
  1593. my $result =
  1594. $query->execute($card_id);
  1595. $self->audit_user_card_end($card_id);
  1596. $self->unlock_commit() if $lock_local;
  1597. return 1;
  1598. }
  1599. sub associate_user_to_card
  1600. {
  1601. my $self = shift;
  1602. my $card_id = shift;
  1603. my $user_id = shift;
  1604. my $FUNC_NAME = "associate_user_to_card";
  1605. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1606. # $self->begin_locked_transaction(
  1607. # {
  1608. # 'audit_user_card' => 'w',
  1609. # 'user_card' => 'w'
  1610. # }
  1611. # ) if $lock_local;
  1612. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1613. my $audit_id =
  1614. $self->audit_user_card_start($card_id, "$PACKAGE_NAME: $FUNC_NAME");
  1615. my $query =
  1616. $self->prepare("update user_card " .
  1617. " set userid = ? " .
  1618. " where logical_card_id = ?");
  1619. my $result =
  1620. $query->execute($user_id, $card_id);
  1621. $self->audit_user_card_end($card_id, $audit_id );
  1622. $self->unlock_commit() if $lock_local;
  1623. return 1;
  1624. }
  1625. #sub get_ithacacollege_logical_card_id {
  1626. sub GetIthacaCollegeLogicalCardId {
  1627. my $self = shift;
  1628. my $phash = shift;
  1629. my $FUNC_NAME = 'GetIthacaCollegeLogicalCardId';
  1630. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1631. # $self->begin_locked_transaction(
  1632. # {
  1633. # 'user_card' => 'r',
  1634. # 'groups' => 'r',
  1635. # 'org_default_card_value' => 'r'
  1636. # }
  1637. # ) if $lock_local;
  1638. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1639. my $mag_token =
  1640. $self->construct_mag_token( $phash );
  1641. if (!$mag_token)
  1642. {
  1643. $self->unlock_rollback() if $lock_local;
  1644. return undef;
  1645. }
  1646. my $query =
  1647. $self->prepare("select user_card.logical_card_id " .
  1648. " from user_card, groups " .
  1649. " where user_card.mag_token like concat(?, '__') " .
  1650. " and groups.group_name = 'ITHACACOLLEGE' " .
  1651. " and groups.group_id = user_card.group_id " .
  1652. " and user_card.active = 1 ");
  1653. $query->execute($mag_token);
  1654. my $row = $query->fetchrow_arrayref;
  1655. if (!$row)
  1656. {
  1657. $self->unlock_rollback() if $lock_local;
  1658. return undef ;
  1659. }
  1660. $self->unlock_commit() if $lock_local;
  1661. return $row->[0];
  1662. }
  1663. #########################
  1664. ##
  1665. ##
  1666. ## Search Functions
  1667. ##
  1668. ##
  1669. sub SearchCards {
  1670. my $self = shift;
  1671. my $rhash = shift;
  1672. my $phash = shift;
  1673. my $FUNC_NAME = "SearchCards";
  1674. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1675. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1676. my %group_hash;
  1677. if ($phash->{NGroup})
  1678. {
  1679. my $n_group = $phash->{NGroup};
  1680. for (my $k=0; $k<$n_group; $k++)
  1681. {
  1682. my $ind = "";
  1683. $ind = "[$k]" if $k;
  1684. $group_hash{ $phash->{"GroupName$ind"} } = 1;
  1685. }
  1686. }
  1687. my @param;
  1688. for (my $i=0; $i<8; $i++) {
  1689. push @param, '%' . $phash->{SearchText} . '%' ;
  1690. }
  1691. my $has_limit = 0;
  1692. if ($phash->{MaxItem})
  1693. {
  1694. $has_limit = 1;
  1695. push @param, $phash->{MaxItem};
  1696. }
  1697. my $query =
  1698. $self->prepare("select user_card.logical_card_id CardId, " .
  1699. " user_card.mag_token MagToken, " .
  1700. " user_card.rfid_token RFIDToken, " .
  1701. " user_card.comment Comment, " .
  1702. " user_card.userid UserId, " .
  1703. " user_card.lastused LastUsed, " .
  1704. " user_card.firstused FirstUsed, " .
  1705. " user_card.group_id GroupId, " .
  1706. " users.username UserName, " .
  1707. " groups.group_name GroupName " .
  1708. " from user_card " .
  1709. " left join users on (users.userid = user_card.userid and users.active = 1) " .
  1710. " left join groups on (groups.group_id = user_card.group_id) " .
  1711. " where user_card.active = 1 " .
  1712. " and ( user_card.mag_token like ? " .
  1713. " or user_card.rfid_token like ? " .
  1714. " or user_card.comment like ? " .
  1715. " or user_card.issued like ? " .
  1716. " or user_card.lastused like ? " .
  1717. " or user_card.firstused like ? " .
  1718. " or users.username like ? " .
  1719. " or groups.group_name like ? ) " .
  1720. ( $has_limit ? " limit ? " : "" ) );
  1721. $query->execute(@param);
  1722. my $count=0;
  1723. while (my $row = $query->fetchrow_hashref)
  1724. {
  1725. next if ( !$group_hash{ $row->{GroupName} });
  1726. my $ind = ( $count ? "[$count]" : "" );
  1727. foreach my $k (keys(%$row))
  1728. {
  1729. $rhash->{"$k$ind"} = $row->{$k};
  1730. }
  1731. $count++;
  1732. }
  1733. $rhash->{NItem} = $count;
  1734. $self->unlock_commit() if $lock_local;
  1735. return 1;
  1736. }
  1737. ##
  1738. sub SearchUsers {
  1739. my $self = shift;
  1740. my $rhash = shift;
  1741. my $phash = shift;
  1742. my $FUNC_NAME = "SearchUsers";
  1743. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1744. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1745. my %group_hash;
  1746. if ($phash->{NGroup})
  1747. {
  1748. my $n_group = $phash->{NGroup};
  1749. for (my $k=0; $k<$n_group; $k++)
  1750. {
  1751. my $ind = "";
  1752. $ind = "[$k]" if $k;
  1753. $group_hash{ $phash->{"GroupName$ind"} } = 1;
  1754. }
  1755. }
  1756. my @param;
  1757. my $has_limit = 0;
  1758. if ($phash->{MaxItem})
  1759. {
  1760. $has_limit = 1;
  1761. }
  1762. my %blacklist_field = ( active => 1, reset_attempts => 1, passwordhash => 1 );
  1763. my $search_fields = "false";
  1764. my $returned_fields;
  1765. while ( my ($k, $v) = each(%users_field_map) )
  1766. {
  1767. next if $blacklist_field{lc($k)};
  1768. $search_fields .= " or ";
  1769. $search_fields .= " users.$k like ? ";
  1770. push @param, '%' . $phash->{SearchText} . '%';
  1771. $returned_fields .= ", " if $returned_fields;
  1772. $returned_fields .= " users.$k $v ";
  1773. }
  1774. if ($has_limit)
  1775. {
  1776. push @param, $phash->{MaxItem};
  1777. }
  1778. my $query =
  1779. $self->prepare("select $returned_fields , groups.group_name GroupName " .
  1780. " from users, groups " .
  1781. " where users.active = 1 " .
  1782. " and users.group_id = groups.group_id " .
  1783. " and ( $search_fields ) " .
  1784. ( $has_limit ? " limit ? " : "" ) );
  1785. $query->execute(@param);
  1786. my $count=0;
  1787. while (my $row = $query->fetchrow_hashref)
  1788. {
  1789. next if (!$group_hash{ $row->{GroupName} });
  1790. my $ind = ( $count ? "[$count]" : "" );
  1791. foreach my $k (keys(%$row))
  1792. {
  1793. $rhash->{"$k$ind"} = $row->{$k};
  1794. }
  1795. $count++;
  1796. }
  1797. $rhash->{NItem} = $count;
  1798. $self->unlock_commit() if $lock_local;
  1799. return 1;
  1800. }
  1801. ##
  1802. my %admins_field_map = (
  1803. username => 'UserName',
  1804. password => 'PasswordHash',
  1805. userid => 'UserId',
  1806. group_id => 'GroupId'
  1807. );
  1808. sub SearchAdmins {
  1809. my $self = shift;
  1810. my $rhash = shift;
  1811. my $phash = shift;
  1812. my $FUNC_NAME = "SearchAdmins";
  1813. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1814. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1815. my %blacklist_field = ( 'password' => 1 );
  1816. my @param;
  1817. my %group_hash;
  1818. if ($phash->{NGroup})
  1819. {
  1820. my $n_group = $phash->{NGroup};
  1821. for (my $k=0; $k<$n_group; $k++)
  1822. {
  1823. my $ind = "";
  1824. $ind = "[$k]" if $k;
  1825. $group_hash{ $phash->{"GroupName$ind"} } = 1;
  1826. }
  1827. }
  1828. my $has_limit = 0;
  1829. if ($phash->{MaxItem})
  1830. {
  1831. $has_limit = 1;
  1832. }
  1833. my $search_fields = "false";
  1834. my $returned_fields;
  1835. while ( my ($k, $v) = each(%admins_field_map) )
  1836. {
  1837. next if $blacklist_field{lc($k)};
  1838. $search_fields .= " or ";
  1839. $search_fields .= " admins.$k like ? ";
  1840. push @param, '%' . $phash->{SearchText} . '%';
  1841. $returned_fields .= ", " if $returned_fields;
  1842. $returned_fields .= " admins.$k $v ";
  1843. }
  1844. if ($has_limit)
  1845. {
  1846. push @param, $phash->{MaxItem};
  1847. }
  1848. my $query =
  1849. $self->prepare("select $returned_fields , groups.group_name GroupName " .
  1850. " from admins left join groups on (admins.group_id = groups.group_id) " .
  1851. " where admins.active = 1 " .
  1852. " and ( $search_fields ) " .
  1853. ( $has_limit ? " limit ? " : "" ) );
  1854. $query->execute(@param);
  1855. my $count=0;
  1856. while (my $row = $query->fetchrow_hashref)
  1857. {
  1858. next if (!$group_hash{ $row->{GroupName} });
  1859. my $ind = ( $count ? "[$count]" : "" );
  1860. foreach my $k (keys(%$row))
  1861. {
  1862. $rhash->{"$k$ind"} = $row->{$k};
  1863. }
  1864. $count++;
  1865. }
  1866. $rhash->{NItem} = $count;
  1867. $self->unlock_commit() if $lock_local;
  1868. return 1;
  1869. }
  1870. ####################################################
  1871. #
  1872. # Associates a pre-existing card in the database to
  1873. # a user.
  1874. #
  1875. #sub add_card {
  1876. sub AddCard
  1877. {
  1878. my $self = shift;
  1879. my $rhash = shift;
  1880. my $phash = shift;
  1881. my $FUNC_NAME = "AddCard";
  1882. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1883. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1884. # my $user_id = $self->get_user_id($phash);
  1885. my $user_id = $self->get_user_id(
  1886. {
  1887. UserName => $phash->{UserName},
  1888. UserId => $phash->{UserId}
  1889. # GroupId => $phash->{UserGroupId},
  1890. # GroupName => $phash->{UserGroupName}
  1891. }
  1892. );
  1893. if (!$user_id)
  1894. {
  1895. $self->unlock_rollback() if $lock_local;
  1896. $rhash->{'Reason'} = "Invalid User";
  1897. return undef;
  1898. }
  1899. # we have to do special processing if it's an ithacacollege card
  1900. my $logical_card_id =
  1901. ( (lc($phash->{'Type'}) eq 'ithacacollege') ?
  1902. $self->GetIthacaCollegeLogicalCardId( $phash ) :
  1903. $self->GetLogicalCardId( $phash ) );
  1904. if (!$logical_card_id)
  1905. {
  1906. $self->unlock_rollback() if $lock_local;
  1907. $rhash->{'Reason'} = "Invalid Card (1)";
  1908. return undef;
  1909. }
  1910. my $card_orig_userid =
  1911. $self->get_user_card_userid( $logical_card_id );
  1912. # Card could be associated to 'ghost' user: A user
  1913. # without a username or password hash. In this
  1914. # case, assigning the card is allowed.
  1915. if ($card_orig_userid)
  1916. {
  1917. if ( $self->valid_user($card_orig_userid) )
  1918. {
  1919. $self->unlock_rollback() if $lock_local;
  1920. $rhash->{'Reason'} = "Invalid Card (2)";
  1921. return undef;
  1922. }
  1923. $self->disassociate_user_from_card($logical_card_id);
  1924. }
  1925. # set user_card entry to userid
  1926. $self->associate_user_to_card($logical_card_id, $user_id);
  1927. $self->unlock_commit() if $lock_local;
  1928. $rhash->{'CardId'} = $logical_card_id;
  1929. return 1;
  1930. }
  1931. #sub transfer_card {
  1932. sub TransferCard
  1933. {
  1934. my $self = shift;
  1935. my $rhash = shift;
  1936. my $phash = shift;
  1937. my $FUNC_NAME = 'TransferCard';
  1938. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  1939. # $self->begin_locked_transaction_common() if $lock_local;
  1940. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1941. $phash->{GroupId} = $self->get_group_id( $phash->{GroupName} || $DEFAULT_GROUP_NAME )
  1942. if (!$phash->{GroupId});
  1943. $phash->{ToGroupId} = $self->get_group_id( $phash->{ToGroupName} || $DEFAULT_GROUP_NAME )
  1944. if (!$phash->{ToGroupId});
  1945. my ($i, $j, $k, $n, $ind);
  1946. my %thash;
  1947. my $from_logical_card_id = $self->GetLogicalCardId($phash);
  1948. my $to_logical_card_id = $self->GetDestLogicalCardId($phash);
  1949. if (!$from_logical_card_id || !$to_logical_card_id)
  1950. {
  1951. $self->unlock_rollback() if $lock_local;
  1952. $rhash->{'Reason'} = "Invalid source or destination card (from $from_logical_card_id, to $to_logical_card_id)";
  1953. return undef;
  1954. }
  1955. my $user_id =
  1956. $self->get_user_card_userid($from_logical_card_id);
  1957. # my $to_card_user_id =
  1958. # $self->get_user_card_userid($to_logical_card_id);
  1959. #
  1960. # if ($to_card_user_id != $user_id)
  1961. # {
  1962. # $self->unlock_rollback();
  1963. # $rhash->{'Reason'} = "Permission Denied: Destination card not owned by user";
  1964. # return undef;
  1965. # }
  1966. $self->GetPassesOnCard( \%thash, { CardId => $from_logical_card_id } );
  1967. $n = $thash{'NPass'};
  1968. for ($i=0; $i<$n; $i++)
  1969. {
  1970. $ind = "[$i]" if $i>0;
  1971. my %dummy;
  1972. # $self->transfer_pass( \%dummy, { ToCardId => $to_logical_card_id,
  1973. $self->TransferPass( \%dummy, { ToCardId => $to_logical_card_id,
  1974. PassId => $thash{'PassId' . $ind } }, 0 );
  1975. }
  1976. $self->disassociate_user_from_card($from_logical_card_id);
  1977. $self->associate_user_to_card($to_logical_card_id, $user_id);
  1978. $self->unlock_commit() if $lock_local;
  1979. $rhash->{'CardId'} = $to_logical_card_id;
  1980. return 1;
  1981. }
  1982. ####################################################
  1983. sub get_user_card_userid {
  1984. my $self = shift;
  1985. my $logical_card_id = shift;
  1986. my $FUNC_NAME = 'get_user_card_userid';
  1987. return undef if !$logical_card_id;
  1988. my $lock_local = ($self->lock_active() ? 0 : 1);
  1989. # $self->begin_locked_transaction(
  1990. # {
  1991. # 'user_card' => 'r'
  1992. # }
  1993. # ) if $lock_local;
  1994. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  1995. my $query =
  1996. $self->prepare("select userid " .
  1997. " from user_card " .
  1998. " where logical_card_id = ? ");
  1999. $query->execute($logical_card_id);
  2000. my $row = $query->fetchrow_arrayref;
  2001. if (!$row)
  2002. {
  2003. $self->unlock_rollback() if $lock_local;
  2004. return undef;
  2005. }
  2006. $self->unlock_commit() if $lock_local;
  2007. return $row->[0];
  2008. }
  2009. ###
  2010. sub get_user_card_group_id {
  2011. my $self = shift;
  2012. my $logical_card_id = shift;
  2013. my $FUNC_NAME = 'get_user_card_group_id';
  2014. return undef if !$logical_card_id;
  2015. my $lock_local = ($self->lock_active() ? 0 : 1);
  2016. # $self->begin_locked_transaction(
  2017. # {
  2018. # 'user_card' => 'r'
  2019. # }
  2020. # ) if $lock_local;
  2021. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2022. my $query =
  2023. $self->prepare("select group_id " .
  2024. " from user_card " .
  2025. " where logical_card_id = ? ");
  2026. $query->execute($logical_card_id);
  2027. my $row = $query->fetchrow_arrayref;
  2028. if (!$row)
  2029. {
  2030. $self->unlock_rollback() if $lock_local;
  2031. return undef;
  2032. }
  2033. $self->unlock_commit() if $lock_local;
  2034. return $row->[0];
  2035. }
  2036. ###
  2037. #sub get_logical_card_id
  2038. sub GetLogicalCardId
  2039. {
  2040. my $self = shift;
  2041. my $phash = shift;
  2042. my $FUNC_NAME = 'GetLogicalCardId';
  2043. my $lock_local = ($self->lock_active() ? 0 : 1);
  2044. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2045. my ($credential_match, $credential_param_ref) =
  2046. $self->construct_user_card_credential_match($phash);
  2047. if (scalar(@$credential_param_ref)==0)
  2048. {
  2049. $self->unlock_rollback() if $lock_local;
  2050. return undef;
  2051. }
  2052. my $query =
  2053. $self->prepare("select logical_card_id " .
  2054. " from user_card " .
  2055. " where $credential_match " .
  2056. " and active = 1 " .
  2057. " limit 1 ");
  2058. $query->execute(@$credential_param_ref);
  2059. my $row = $query->fetchrow_arrayref;
  2060. $self->unlock_commit() if $lock_local;
  2061. return undef if !$row;
  2062. return $row->[0];
  2063. }
  2064. #sub get_dest_logical_card_id {
  2065. sub GetDestLogicalCardId
  2066. {
  2067. my $self = shift;
  2068. my $phash = shift;
  2069. # return $self->get_logical_card_id( { #UserId => $phash->{'UserId'},
  2070. my $FUNC_NAME = 'GetDestLogicalCardId';
  2071. return $self->GetLogicalCardId( { MagToken=> $phash->{'ToMagToken'},
  2072. MagTrack => $phash->{'ToMagTrack'},
  2073. MagStripe => $phash->{'ToMagStripe'},
  2074. RFLength => $phash->{'ToRFLength'},
  2075. RFID => $phash->{'ToRFID'},
  2076. RFIDToken => $phash->{'ToRFIDToken'},
  2077. CardId => $phash->{'ToCardId'},
  2078. GroupId => $phash->{'ToGroupId'} } );
  2079. }
  2080. ####
  2081. sub user_card_active_pass_count {
  2082. my $self = shift;
  2083. my $logical_card_id = shift;
  2084. my $FUNC_NAME = 'user_card_active_pass_count';
  2085. my $lock_local = ($self->lock_active() ? 0 : 1);
  2086. # $self->begin_locked_transaction(
  2087. # {
  2088. # 'user_pass' => 'r'
  2089. # }
  2090. # ) if $lock_local;
  2091. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2092. my $query =
  2093. $self->prepare("select count(user_pass_id) ".
  2094. " from user_pass " .
  2095. " where logical_card_id = ? " .
  2096. " and expired = 0 " .
  2097. " and active = 1 ");
  2098. $query->execute($logical_card_id);
  2099. $self->unlock_commit() if $lock_local;
  2100. return $query->fetchrow_arrayref->[0];
  2101. }
  2102. #####
  2103. sub pending_card {
  2104. my $self = shift;
  2105. my $logical_card_id = shift;
  2106. my $FUNC_NAME = 'pending_card';
  2107. my $lock_local = ($self->lock_active() ? 0 : 1);
  2108. # $self->begin_locked_transaction( { 'user_card' => 'r' }) if $lock_local;
  2109. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2110. my $query =
  2111. $self->prepare("select mag_token, rfid_token " .
  2112. " from user_card " .
  2113. " where logical_card_id = ? " .
  2114. " and active = 1 " );
  2115. $query->execute($logical_card_id);
  2116. my $row = $query->fetchrow_arrayref;
  2117. $self->unlock_commit() if $lock_local;
  2118. return 0 if !$row;
  2119. return !($row->[0]) && !($row->[1]);
  2120. }
  2121. #####
  2122. sub delete_user_card_from_active_rider_table {
  2123. my $self = shift;
  2124. my $logical_card_id = shift;
  2125. my $FUNC_NAME = 'delete_user_card_from_active_rider_table';
  2126. my $lock_local = ($self->lock_active() ? 0 : 1);
  2127. # $self->begin_locked_transaction( { 'active_rider_table' => 'w' }) if $lock_local;
  2128. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2129. if (!$self->validate_active_rider_table_logical_card_id( $logical_card_id ))
  2130. {
  2131. $self->unlock_rollback() if $lock_local;
  2132. return undef
  2133. }
  2134. my $query =
  2135. $self->prepare(" insert into " .
  2136. " active_rider_table (logical_card_id, deleted) " .
  2137. " values ( ?, 1) ");
  2138. $query->execute($logical_card_id);
  2139. $self->unlock_commit() if $lock_local;
  2140. return 1;
  2141. }
  2142. #####
  2143. sub confirm_card_user_id {
  2144. my $self = shift;
  2145. my $phash = shift;
  2146. my $user_id = shift;
  2147. my $FUNC_NAME = 'confirm_card_user_id';
  2148. my %thash;
  2149. my $r =
  2150. $self->GetCard(\%thash, $phash);
  2151. return 0 if (!$r) or ($thash{UserId} != $user_id);
  2152. return 1;
  2153. }
  2154. #####
  2155. my %active_rider_table_map = (
  2156. logical_card_id => 'logical_card_id',
  2157. seq_num => 'seq_num',
  2158. rfid_token => 'rfid_token',
  2159. mag_token => 'mag_token',
  2160. rule_name => 'rule_name',
  2161. rule_param => 'rule_param',
  2162. deleted => 'deleted'
  2163. );
  2164. sub get_active_rider_table
  2165. #sub GetActiveRiderTable
  2166. {
  2167. my $self = shift;
  2168. my $rhash = shift;
  2169. my $phash = shift;
  2170. my $FUNC_NAME = 'get_active_rider_table';
  2171. my $logical_card_id = $phash->{'logical_card_id'};
  2172. return undef if !$logical_card_id;
  2173. my $lock_local = ($self->lock_active() ? 0 : 1);
  2174. # $self->begin_locked_transaction( { 'active_rider_table' => 'r' }) if $lock_local;
  2175. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2176. my $query =
  2177. $self->prepare("select max(seq_num) m " .
  2178. " from active_rider_table " .
  2179. " where deleted = 0 " .
  2180. " and logical_card_id = ? ");
  2181. $query->execute($logical_card_id);
  2182. my $seq_num = $query->fetchrow_arrayref->[0];
  2183. if (!$seq_num)
  2184. {
  2185. $self->unlock_commit() if $lock_local;
  2186. return undef;
  2187. }
  2188. $query =
  2189. $self->prepare("select " . join(", ", keys(%active_rider_table_map)) .
  2190. " from active_rider_table " .
  2191. " where logical_card_id = ? " .
  2192. " and deleted = 0 " .
  2193. " and seq_num = ?");
  2194. $query->execute($logical_card_id, $seq_num);
  2195. my $row = $query->fetchrow_hashref;
  2196. $self->unlock_commit() if $lock_local;
  2197. return undef if (!$row);
  2198. foreach my $k (keys(%active_rider_table_map))
  2199. {
  2200. $rhash->{$active_rider_table_map{$k}} = $row->{$k};
  2201. }
  2202. return 1;
  2203. }
  2204. #####
  2205. sub deactivate_user_card {
  2206. my $self = shift;
  2207. my $logical_card_id = shift;
  2208. my $FUNC_NAME = "deactivate_user_card";
  2209. my $lock_local = ($self->lock_active() ? 0 : 1);
  2210. # $self->begin_locked_transaction( { 'audit_user_card' => 'w', 'user_card' => 'w' }) if $lock_local;
  2211. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2212. my $audit_id =
  2213. $self->audit_user_card_start($logical_card_id, "$PACKAGE_NAME: $FUNC_NAME");
  2214. my $query =
  2215. $self->prepare("update user_card " .
  2216. " set active = 0, " .
  2217. " deactivated = now() " .
  2218. " where logical_card_id = ?");
  2219. my $result =
  2220. $query->execute($logical_card_id);
  2221. $self->audit_user_card_end($logical_card_id, $audit_id);
  2222. $self->unlock_commit() if $lock_local;
  2223. }
  2224. ###
  2225. # deactivate user_card entry
  2226. ###
  2227. #sub remove_card {
  2228. sub RemoveCard
  2229. {
  2230. my $self = shift;
  2231. my $rhash = shift;
  2232. my $phash = shift;
  2233. my $FUNC_NAME = "RemoveCard";
  2234. my $lock_local = ($self->lock_active() ? 0 : 1);
  2235. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2236. # $phash->{GroupId} = $self->get_group_id( $phash->{GroupName} || $DEFAULT_GROUP_NAME )
  2237. # if (!$phash->{GroupId});
  2238. if ($phash->{GroupName} && !$phash->{GroupId})
  2239. {
  2240. $phash->{GroupId} = $self->get_group_id( $phash->{GroupName} );
  2241. }
  2242. my $logical_card_id =
  2243. $self->GetLogicalCardId($phash);
  2244. if (!$logical_card_id)
  2245. {
  2246. $self->unlock_rollback() if $lock_local;
  2247. $rhash->{'Reason'} = "Invalid CardId";
  2248. return undef;
  2249. }
  2250. # if card isn't an 'ordered' card
  2251. if ( !$self->pending_card($logical_card_id) )
  2252. {
  2253. if (!$self->delete_user_card_from_active_rider_table($logical_card_id))
  2254. {
  2255. $self->unlock_rollback() if $lock_local;
  2256. $rhash->{'Reason'} = "Internal Error";
  2257. return undef;
  2258. }
  2259. }
  2260. else # if it is, remove it from the card order queue
  2261. {
  2262. my %thash;
  2263. if (!$self->RemovePendingQueueByCardId( \%thash, { 'CardId' => $logical_card_id } ))
  2264. {
  2265. $self->unlock_rollback() if $lock_local;
  2266. $rhash->{'Reason'} = $thash{'Reason'};
  2267. return undef;
  2268. }
  2269. }
  2270. $self->deactivate_user_card($logical_card_id);
  2271. $self->unlock_commit() if $lock_local;
  2272. return 1;
  2273. }
  2274. ###
  2275. sub GetPendingQueue {
  2276. my $self = shift;
  2277. my $rhash = shift;
  2278. my $phash = shift;
  2279. my $FUNC_NAME = "GetPendingQueue";
  2280. my ($query, $result, $row);
  2281. $query = $self->prepare("select org_card_order_queue_id,
  2282. userid,
  2283. logical_card_id,
  2284. created,
  2285. processed,
  2286. comment,
  2287. pending
  2288. from org_card_order_queue
  2289. where pending = 1
  2290. order by org_card_order_queue_id");
  2291. $query->execute();
  2292. my $ind;
  2293. my $n=0;
  2294. while (my $row = $query->fetchrow_hashref)
  2295. {
  2296. $ind = "[$n]" if $n>0;
  2297. $n++;
  2298. $rhash->{'QueueId' . $ind} = $row->{org_card_order_queue_id};
  2299. $rhash->{'UserId' . $ind} = $row->{userid};
  2300. $rhash->{'CardId' . $ind} = $row->{logical_card_id};
  2301. $rhash->{'Created' . $ind} = $row->{created};
  2302. my %trhash;
  2303. my %tphash = ( CardId => $row->{logical_card_id} );
  2304. my $r =
  2305. $self->GetCard(\%trhash, \%tphash);
  2306. $rhash->{'IssueType' . $ind} = $trhash{'IssueType'};
  2307. }
  2308. $rhash->{NCard} = $n;
  2309. return 1;
  2310. }
  2311. ###
  2312. sub GetPendingQueueCard {
  2313. my $self = shift;
  2314. my $rhash = shift;
  2315. my $phash = shift;
  2316. my $FUNC_NAME = "GetPendingQueueCard";
  2317. my $lock_local = ($self->lock_active() ? 0 : 1);
  2318. my $queue_id = $phash->{QueueId};
  2319. if (!$queue_id)
  2320. {
  2321. $rhash->{Reason} = "Invalid QueueId";
  2322. return undef ;
  2323. }
  2324. # $self->begin_locked_transaction_common() if $lock_local;
  2325. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2326. my $query =
  2327. $self->prepare("select logical_card_id
  2328. from org_card_order_queue
  2329. where org_card_order_queue_id = ?
  2330. and pending = 1");
  2331. $query->execute($queue_id);
  2332. my $row = $query->fetchrow_arrayref;
  2333. if (!$row)
  2334. {
  2335. $self->unlock_rollback() if $lock_local;
  2336. $rhash->{Reason} = "No cards found";
  2337. return undef;
  2338. }
  2339. my $logical_card_id = $row->[0];
  2340. return $self->GetCard($rhash, { CardId => $logical_card_id } );
  2341. }
  2342. ###
  2343. sub ProcessPendingQueue {
  2344. my $self = shift;
  2345. my $rhash = shift;
  2346. my $phash = shift;
  2347. my $FUNC_NAME = "ProcessPendingQueue";
  2348. my ($query, $row);
  2349. my $lock_local = ($self->lock_active() ? 0 : 1);
  2350. my $queue_id = $phash->{QueueId};
  2351. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2352. $query = $self->prepare("select logical_card_id, userid
  2353. from org_card_order_queue
  2354. where org_card_order_queue_id = ?
  2355. and pending = 1");
  2356. $query->execute($queue_id);
  2357. $row = $query->fetchrow_arrayref;
  2358. if (!$row)
  2359. {
  2360. $self->unlock_rollback() if $lock_local;
  2361. $rhash->{Reason} = "No Pending Card";
  2362. return undef;
  2363. }
  2364. $phash->{UserId} = $row->[1];
  2365. $phash->{CardId} = $row->[0];
  2366. my %resp;
  2367. my $r =
  2368. $self->TransferCard(\%resp, $phash);
  2369. if (!$r)
  2370. {
  2371. $self->unlock_rollback() if $lock_local;
  2372. $rhash->{Reason} = $resp{Reason};
  2373. return undef;
  2374. }
  2375. my $card_id = $resp{CardId};
  2376. $rhash->{CardId} = $resp{CardId};
  2377. %resp = ();
  2378. $r =
  2379. $self->RemoveCard(\%resp, { CardId => $phash->{CardId} } );
  2380. if (!$r)
  2381. {
  2382. $self->unlock_rollback() if $lock_local;
  2383. $rhash->{Reason} = $resp{Reason};
  2384. return undef;
  2385. }
  2386. $query = $self->prepare("update org_card_order_queue
  2387. set pending = 0
  2388. where org_card_order_queue_id = ?");
  2389. $query->execute($queue_id);
  2390. $self->unlock_commit() if $lock_local;
  2391. return 1;
  2392. }
  2393. ###
  2394. sub RemovePendingQueue {
  2395. my $self = shift;
  2396. my $rhash = shift;
  2397. my $phash = shift;
  2398. my $FUNC_NAME = "RemovePendingQueue";
  2399. my ($query, $row, $queue_id);
  2400. $queue_id = $phash->{QueueId};
  2401. my $lock_local = ($self->lock_active() ? 0 : 1);
  2402. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2403. $query = $self->prepare("select logical_card_id
  2404. from org_card_order_queue
  2405. where org_card_order_queue_id = ?
  2406. and pending = 1");
  2407. $query->execute($queue_id);
  2408. $row = $query->fetchrow_arrayref;
  2409. $queue_id = $phash->{QueueId};
  2410. if (!$queue_id || !$row)
  2411. {
  2412. $self->unlock_rollback() if $lock_local;
  2413. $rhash->{Reason} = "No entry in card order queue";
  2414. return undef;
  2415. }
  2416. my %t;
  2417. $self->RemoveCard(\%t, { CardId => $row->[0] } );
  2418. $query = $self->prepare("update org_card_order_queue
  2419. set pending = 0
  2420. where org_card_order_queue_id = ?");
  2421. $query->execute($queue_id);
  2422. $self->unlock_commit() if $lock_local;
  2423. return (1, "RemovePendingQueue");
  2424. }
  2425. ####
  2426. #
  2427. # remove only the org_card_order_queue entry by the card id
  2428. #
  2429. sub RemovePendingQueueByCardId {
  2430. my $self = shift;
  2431. my $rhash = shift;
  2432. my $phash = shift;
  2433. my $FUNC_NAME = "RemovePendingQueueByCardId";
  2434. my ($query, $row, $card_id, $queue_id);
  2435. $card_id = $phash->{CardId};
  2436. my $lock_local = ($self->lock_active() ? 0 : 1);
  2437. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2438. $query = $self->prepare("select org_card_order_queue_id, logical_card_id
  2439. from org_card_order_queue
  2440. where pending = 1
  2441. and logical_card_id = ?");
  2442. $query->execute($card_id);
  2443. $row = $query->fetchrow_arrayref;
  2444. if (!$row)
  2445. {
  2446. $self->unlock_rollback() if $lock_local;
  2447. $rhash->{Reason} = "No entry in card order queue";
  2448. return undef;
  2449. }
  2450. $queue_id = $row->[0];
  2451. $query = $self->prepare("update org_card_order_queue set pending = 0 where org_card_order_queue_id = ?");
  2452. $query->execute( $queue_id );
  2453. $self->unlock_commit() if $lock_local;
  2454. return (1, "RemovePendigQueueByCardId");
  2455. }
  2456. ############################
  2457. #sub active_user_card
  2458. sub user_card_credential_exists
  2459. {
  2460. my $self = shift;
  2461. my $param_hash = shift;
  2462. my $FUNC_NAME = 'user_card_credential_exists';
  2463. my @field = qw( logical_card_id mag_token rfid_token );
  2464. my $query;
  2465. my $lock_local = ($self->lock_active() ? 0 : 1);
  2466. # $self->begin_locked_transaction( { 'user_card' => 'r' }) if $lock_local;
  2467. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2468. foreach my $field (@field)
  2469. {
  2470. if ($param_hash->{$field})
  2471. {
  2472. $query =
  2473. $self->prepare("select count(logical_card_id) num " .
  2474. " from user_card " .
  2475. " where " . $field . " = ? " .
  2476. " and active = 1 " .
  2477. " limit 1 ");
  2478. $query->execute($param_hash->{$field});
  2479. # return 1 if $query->fetchrow_arrayref->[0] > 0;
  2480. if ($query->fetchrow_arrayref->[0] > 0)
  2481. {
  2482. $self->unlock_commit() if $lock_local;
  2483. return 1;
  2484. }
  2485. }
  2486. }
  2487. $self->unlock_commit() if $lock_local;
  2488. return 0;
  2489. }
  2490. ############################
  2491. #
  2492. # insert user card helper function
  2493. # active defaults to 1
  2494. # issued defaults to now()
  2495. #
  2496. sub insert_user_card
  2497. {
  2498. my $self = shift;
  2499. my $param_hash = shift;
  2500. my $FUNC_NAME = "insert_user_card";
  2501. my @field;
  2502. my @val;
  2503. my $query;
  2504. my $lock_local = ($self->lock_active() ? 0 : 1);
  2505. # $self->begin_locked_transaction( { 'audit_user_card' => 'w', 'user_card' => 'w' }) if $lock_local;
  2506. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2507. if ( $self->user_card_credential_exists( $param_hash ) )
  2508. {
  2509. $self->unlock_rollback() if $lock_local;
  2510. return undef
  2511. }
  2512. my @default_field = ('issued', 'active');
  2513. my @default_value = ('now()', '1');
  2514. my @default_token;
  2515. # construct default values
  2516. for (my $i=0; $i<scalar(@default_field); $i++)
  2517. {
  2518. my $f = $default_field[$i];
  2519. push @field, $f;
  2520. if (defined($param_hash->{$f}))
  2521. {
  2522. push @default_token, "?";
  2523. push @val, $param_hash->{$f};
  2524. }
  2525. else
  2526. {
  2527. push @default_token, $default_value[$i];
  2528. }
  2529. }
  2530. # populate values
  2531. foreach my $k (keys(%user_card_field_map))
  2532. {
  2533. next if grep $_ eq $k, @default_field;
  2534. push @field, $k;
  2535. push @val, (defined($param_hash->{$k}) ? $param_hash->{$k} : undef );
  2536. }
  2537. my $audit_id =
  2538. $self->audit_user_card_start(undef, "$PACKAGE_NAME: $FUNC_NAME");
  2539. $query =
  2540. $self->prepare("insert into user_card ( " . join(', ', @field) . ") " .
  2541. "values ( " . join(', ', @default_token) . ", ?"x(scalar(@field)-scalar(@default_token)) . ")");
  2542. $query->execute(@val);
  2543. my $logical_card_id = $self->last_insert_id();
  2544. $self->audit_user_card_end($logical_card_id, $audit_id);
  2545. $self->unlock_commit() if $lock_local;
  2546. return $logical_card_id
  2547. }
  2548. ############################
  2549. ##########
  2550. ###
  2551. #
  2552. # returns 0 if logical_card_id is not found or last entry is deleted
  2553. # returns 1 if logical_card_id found
  2554. #
  2555. sub validate_active_rider_table_logical_card_id
  2556. {
  2557. my $self = shift;
  2558. my $logical_card_id = shift;
  2559. my $FUNC_NAME = "validate_active_rider_table_logical_card_id";
  2560. return 0 if !$logical_card_id;
  2561. my $lock_local = ($self->lock_active() ? 0 : 1);
  2562. # $self->begin_locked_transaction( { 'active_rider_table' => 'r' }) if $lock_local;
  2563. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2564. my $query =
  2565. $self->prepare("select max(seq_num) " .
  2566. " from active_rider_table " .
  2567. " where logical_card_id = ? ");
  2568. $query->execute($logical_card_id);
  2569. my $seq_num = $query->fetchrow_arrayref->[0];
  2570. $query =
  2571. $self->prepare("select logical_card_id, ".
  2572. " seq_num, " .
  2573. " mag_token, " .
  2574. " rfid_token, " .
  2575. " deleted " .
  2576. " from active_rider_table " .
  2577. " where seq_num = ? ");
  2578. $query->execute($seq_num);
  2579. my $aref = $query->fetchrow_arrayref;
  2580. $self->unlock_commit() if $lock_local;
  2581. return 0 if !$aref;
  2582. return 0 if $aref->[4];
  2583. return 1;
  2584. }
  2585. ##########
  2586. sub validate_rule
  2587. {
  2588. my $self = shift;
  2589. my $rule = shift;
  2590. my $rule_param = shift;
  2591. my $group_id = shift;
  2592. my $FUNC_NAME = 'validate_rule';
  2593. my $lock_local = ($self->lock_active() ? 0 : 1);
  2594. # $self->begin_locked_transaction( { 'rule_mappings' => 'r', 'rule_class' => 'r' }) if $lock_local;
  2595. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2596. my $query =
  2597. $self->prepare("select rulename, " .
  2598. " ruleclass " .
  2599. " from rule_class " .
  2600. " where rulename = ? " .
  2601. " limit 1 ");
  2602. $query->execute($rule);
  2603. my $aref = $query->fetchrow_arrayref;
  2604. if (!$aref)
  2605. {
  2606. $self->unlock_rollback() if $lock_local;
  2607. return 0;
  2608. }
  2609. my $db_rule_name = $aref->[0];
  2610. my $db_rule_class = $aref->[1];
  2611. if ( lc($db_rule_class) eq 'nride')
  2612. {
  2613. if (!$rule_param or !($rule_param =~ m/^\d+\s*$/))
  2614. {
  2615. $self->unlock_rollback() if $lock_local;
  2616. return 0;
  2617. }
  2618. }
  2619. elsif (lc($db_rule_class) eq 'nday')
  2620. {
  2621. if (!$rule_param or
  2622. ( !($rule_param =~ m/^\d+\s*$/) &&
  2623. !($rule_param =~ m/^\d+ \d\d\d\d[-\/]\d?\d[-\/]\d?\d \d\d:\d\d:\d\d\s*$/) ) )
  2624. {
  2625. $self->unlock_rollback() if $lock_local;
  2626. return 0;
  2627. }
  2628. }
  2629. if ($group_id)
  2630. {
  2631. $query =
  2632. $self->prepare("select count(group_id) num " .
  2633. " from rule_mappings " .
  2634. " where rule = ? " .
  2635. " and active = 1 " .
  2636. " and (group_id = ? or group_id is null) " .
  2637. " limit 1 ");
  2638. $query->execute($db_rule_name, $group_id);
  2639. if ($query->fetchrow_arrayref->[0] != 1)
  2640. {
  2641. $self->unlock_rollback() if $lock_local;
  2642. return 0;
  2643. }
  2644. }
  2645. $self->unlock_commit() if $lock_local;
  2646. return 1;
  2647. }
  2648. ##########
  2649. sub get_default_rule {
  2650. my $self = shift;
  2651. my $FUNC_NAME = 'get_default_rule';
  2652. my $lock_local = ($self->lock_active() ? 0 : 1);
  2653. # $self->begin_locked_transaction( { 'rule_mappings' => 'r' }) if $lock_local;
  2654. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2655. my $query =
  2656. $self->prepare("select rule " .
  2657. " from rule_mappings " .
  2658. " where group_id is null " .
  2659. " limit 1");
  2660. $query->execute();
  2661. $self->unlock_commit() if $lock_local;
  2662. return $query->fetchrow_arrayref->[0];
  2663. }
  2664. ###
  2665. sub get_rule_class {
  2666. my $self = shift;
  2667. my $rule = shift;
  2668. my $FUNC_NAME = 'get_rule_class';
  2669. my $lock_local = ($self->lock_active() ? 0 : 1);
  2670. # $self->begin_locked_transaction( { 'rule_class' => 'r' }) if $lock_local;
  2671. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2672. my $query =
  2673. $self->prepare("select ruleclass " .
  2674. " from rule_class " .
  2675. " where rulename = ? ");
  2676. $query->execute($rule);
  2677. my $row = $query->fetchrow_arrayref;
  2678. $self->unlock_commit() if $lock_local;
  2679. return undef if !$row;
  2680. return $row->[0];
  2681. }
  2682. ###
  2683. sub insert_active_rider_table
  2684. {
  2685. my $self = shift;
  2686. my $param_hash = shift;
  2687. my $FUNC_NAME = "insert_active_rider_table";
  2688. return undef if !defined($param_hash->{'logical_card_id'}) or !$param_hash->{'logical_card_id'};
  2689. my $lock_local = ($self->lock_active() ? 0 : 1);
  2690. # $self->lock_common() if $lock_local;
  2691. # $self->begin_locked_transaction_common() if $lock_local;
  2692. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2693. my $default_rule =
  2694. $self->get_default_rule();
  2695. my $query =
  2696. $self->prepare(" select user_card.mag_token, " .
  2697. " user_card.rfid_token, " .
  2698. " user_card.group_id, " .
  2699. " case when user_pass.rule is null then '" . $default_rule . "' " .
  2700. " else user_pass.rule end, " .
  2701. " user_pass.nrides_remain, " .
  2702. " user_pass.nday_orig, " .
  2703. " user_pass.nday_expiration, " .
  2704. " user_pass.comment " .
  2705. " from user_card left join user_pass " .
  2706. " on (user_card.logical_card_id = user_pass.logical_card_id and" .
  2707. " user_pass.active = 1) " .
  2708. " where user_card.logical_card_id = ? " .
  2709. " and user_card.active = 1 ");
  2710. $query->execute( $param_hash->{'logical_card_id'} );
  2711. my $aref = $query->fetchrow_arrayref;
  2712. # return undef if !$aref;
  2713. if (!$aref)
  2714. {
  2715. $self->unlock_rollback() if $lock_local;
  2716. return undef;
  2717. }
  2718. my @field = qw(
  2719. logical_card_id
  2720. rfid_token
  2721. mag_token
  2722. rule_name
  2723. rule_param
  2724. deleted
  2725. );
  2726. my $rule = $aref->[3];
  2727. my $nride = $aref->[4];
  2728. my $nday = $aref->[5];
  2729. my $nday_exp = $aref->[6];
  2730. my $art_param = $aref->[7];
  2731. my $rule_type =
  2732. $self->get_rule_class($rule);
  2733. if (lc($rule_type) eq 'nride')
  2734. {
  2735. $art_param = $nride;
  2736. }
  2737. elsif (lc($rule_type) eq 'nday')
  2738. {
  2739. $art_param = $nday;
  2740. if ($nday_exp)
  2741. {
  2742. $art_param .= " $nday_exp";
  2743. }
  2744. }
  2745. if ( !$self->validate_rule( $rule, $art_param ) )
  2746. {
  2747. $self->unlock_rollback() if $lock_local;
  2748. die "$PACKAGE_NAME: $FUNC_NAME: invalid logical_card_id, rule or rule_param ($rule, $nride, $nday, $nday_exp)";
  2749. }
  2750. $query =
  2751. $self->prepare("insert into active_rider_table ( " . join(', ', @field) . ") " .
  2752. " values ( ?" . ", ?"x(scalar(@field)-1) . ") ");
  2753. $query->execute($param_hash->{'logical_card_id'},
  2754. $aref->[1],
  2755. $aref->[0],
  2756. $rule,
  2757. $art_param,
  2758. 0);
  2759. $self->unlock_commit() if $lock_local;
  2760. return 1;
  2761. }
  2762. ###
  2763. sub active_user_card_exists {
  2764. my $self = shift;
  2765. my $phash = shift;
  2766. my $FUNC_NAME = 'active_user_card_exists';
  2767. my @fields = qw(MagToken MagStripe RFIDToken RFID CardId);
  2768. my $lock_local = ($self->lock_active() ? 0 : 1);
  2769. # $self->begin_locked_transaction( { 'org_default_card_value' => 'r', 'user_card' => 'r' }) if $lock_local;
  2770. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2771. foreach my $f (@fields)
  2772. {
  2773. next if $f =~ /^Group(Id|Name)$/;
  2774. next if !$phash->{$f};
  2775. my $card_id;
  2776. if ($phash->{GroupId})
  2777. {
  2778. $card_id =
  2779. $self->GetLogicalCardId( { $f => $phash->{$f}, GroupId => $phash->{GroupId} } );
  2780. }
  2781. else
  2782. {
  2783. $card_id =
  2784. $self->GetLogicalCardId( { $f => $phash->{$f} } );
  2785. }
  2786. if ($card_id)
  2787. {
  2788. $self->unlock_commit() if $lock_local;
  2789. return 1;
  2790. }
  2791. }
  2792. $self->unlock_commit() if $lock_local;
  2793. return undef;
  2794. }
  2795. ######
  2796. #
  2797. # create a credential in database
  2798. # 1) lock relevant tables (active_rider_table, user_card, user_pass, audit_user_card, audit_user_pass)
  2799. # 2) insert into user_card
  2800. # 3) insert into active_rider_table
  2801. # 4) unlock tables
  2802. #
  2803. ######
  2804. #sub create_card
  2805. sub CreateCard
  2806. {
  2807. my $self = shift;
  2808. my $rhash = shift;
  2809. my $phash = shift;
  2810. my $FUNC_NAME = "CreateCard";
  2811. my $lock_local = ($self->lock_active() ? 0 : 1);
  2812. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2813. $phash->{GroupId} = $self->get_group_id( $phash->{GroupName} || $DEFAULT_GROUP_NAME )
  2814. if (!$phash->{GroupId});
  2815. my %insert_param;
  2816. while ( my ($k, $v) = each(%user_card_field_map) )
  2817. {
  2818. $insert_param{$k} = $phash->{$v};
  2819. }
  2820. $insert_param{'active'} = 1 if !defined($phash->{'Active'}); # default to active card
  2821. $insert_param{'mag_token'} = $self->construct_mag_token( $phash );
  2822. $insert_param{'rfid_token'} = $self->construct_rfid_token( $phash );
  2823. if (!$insert_param{'group_id'})
  2824. {
  2825. my %rhash;
  2826. $self->GetDefaultCardGroupInfo(\%rhash, $phash);
  2827. $insert_param{'group_id'} = $rhash{'GroupId'};
  2828. }
  2829. if ($self->active_user_card_exists( $phash ))
  2830. {
  2831. $self->unlock_rollback() if $lock_local;
  2832. $rhash->{'Reason'} = "Active card already exists";
  2833. return undef;
  2834. }
  2835. $rhash->{'CardId'} =
  2836. $self->insert_user_card( \%insert_param );
  2837. if (!$rhash->{'CardId'}) {
  2838. $rhash->{'Reason'} = "Insert Failed!";
  2839. $self->unlock_rollback() if $lock_local;
  2840. return undef;
  2841. }
  2842. $self->insert_active_rider_table( { logical_card_id => $rhash->{'CardId'} } );
  2843. $self->unlock_commit() if $lock_local;
  2844. return $rhash->{'CardId'};
  2845. }
  2846. ################################
  2847. ##
  2848. ##
  2849. ## user_pass functions
  2850. ##
  2851. ##
  2852. ################################
  2853. my %user_pass_field_map =
  2854. ( user_pass_id => "PassId",
  2855. logical_card_id => "CardId",
  2856. issued => "Issued",
  2857. firstused => "FirstUsed",
  2858. lastused => "LastUsed",
  2859. activated => "Activated",
  2860. deactivated => "Deactivated",
  2861. rule => "Rule",
  2862. nrides_orig => "NRideOrig",
  2863. nrides_remain => "NRideRemain",
  2864. nday_orig => "NDayOrig",
  2865. nday_expiration => "NDayExpiration",
  2866. queue_order => "QueueOrder",
  2867. comment => "Comment",
  2868. active => "Active",
  2869. expired => "Expired",
  2870. paytype => "PaymentType",
  2871. comment => "Comment"
  2872. );
  2873. #
  2874. # insert user pass helper function
  2875. # issued defaults to now()
  2876. # if active is set, activated defaults to now
  2877. #
  2878. sub insert_user_pass
  2879. {
  2880. my $self = shift;
  2881. my $param_hash = shift;
  2882. my $FUNC_NAME = "insert_user_pass";
  2883. my @field;
  2884. my @val;
  2885. my $query;
  2886. my @default_field = ('issued', 'activated');
  2887. my @default_value = ('now()' , 'now()');
  2888. my @default_token;
  2889. my $lock_local = ($self->lock_active() ? 0 : 1);
  2890. # $self->begin_locked_transaction( { 'audit_user_pass' => 'w', 'user_pass' => 'w' }) if $lock_local;
  2891. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2892. # set defaults
  2893. for (my $i=0; $i<scalar(@default_field); $i++)
  2894. {
  2895. my $f = $default_field[$i];
  2896. push @field, $f;
  2897. if (defined($param_hash->{$f}))
  2898. {
  2899. push @default_token, "?";
  2900. push @val, $param_hash->{$f};
  2901. }
  2902. else
  2903. {
  2904. push @default_token, $default_value[$i];
  2905. }
  2906. }
  2907. # set value array
  2908. foreach my $k (keys(%user_pass_field_map))
  2909. {
  2910. next if grep $_ eq $k, @default_field;
  2911. push @field, $k;
  2912. push @val, (defined($param_hash->{$k}) ? $param_hash->{$k} : undef );
  2913. }
  2914. my $audit_id =
  2915. $self->audit_user_pass_start(undef, "$PACKAGE_NAME: $FUNC_NAME");
  2916. $query =
  2917. $self->prepare("insert into user_pass ( " . join(', ', @field) . ") " .
  2918. "values ( " . join(', ', @default_token) . ", ?"x(scalar(@field)-scalar(@default_token)) . ")");
  2919. $query->execute(@val);
  2920. my $pass_id =
  2921. $self->last_insert_id();
  2922. $self->audit_user_pass_end($pass_id, $audit_id);
  2923. $self->unlock_commit() if $lock_local;
  2924. return $pass_id;
  2925. }
  2926. ###
  2927. sub get_user_pass_logical_card_id {
  2928. my $self = shift;
  2929. my $pass_id = shift;
  2930. my $FUNC_NAME = 'get_user_pass_logical_card_id';
  2931. return undef if !$pass_id;
  2932. my $lock_local = ($self->lock_active() ? 0 : 1);
  2933. # $self->begin_locked_transaction( { 'user_pass' => 'r' }) if $lock_local;
  2934. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2935. my $query =
  2936. $self->prepare("select logical_card_id " .
  2937. " from user_pass " .
  2938. " where user_pass_id = ? ");
  2939. $query->execute($pass_id);
  2940. my $row = $query->fetchrow_arrayref;
  2941. $self->unlock_commit() if $lock_local;
  2942. return undef if !$row;
  2943. return $row->[0];
  2944. }
  2945. #sub get_user_pass {
  2946. sub GetUserPass
  2947. {
  2948. my $self = shift;
  2949. my $rhash = shift;
  2950. my $phash = shift;
  2951. my $FUNC_NAME = 'GetUserPass';
  2952. my ($query, $result);
  2953. if ( !$phash->{'CardId'} and !$phash->{'PassId'} )
  2954. {
  2955. $rhash->{'Reason'} = "Invalid Parameters";
  2956. return undef;
  2957. }
  2958. my $fields = "rule_class.ruleclass Type";
  2959. while ( my ($k, $v) = each(%user_pass_field_map) )
  2960. {
  2961. $fields .= ", user_pass.$k $v";
  2962. }
  2963. my @param;
  2964. push @param, $phash->{'CardId'} if $phash->{'CardId'};
  2965. push @param, $phash->{'UserId'} if $phash->{'UserId'};
  2966. push @param, $phash->{'PassId'} if $phash->{'PassId'};
  2967. push @param, $phash->{'Active'} if $phash->{'Active'};
  2968. my $lock_local = ($self->lock_active() ? 0 : 1);
  2969. # $self->begin_locked_transaction( { 'user_card' => 'r', 'user_pass' => 'r', 'rule_class' => 'r' }) if $lock_local;
  2970. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  2971. $query =
  2972. $self->prepare("select $fields " .
  2973. " from user_pass, " .
  2974. " user_card, " .
  2975. " rule_class " .
  2976. "where user_card.logical_card_id = user_pass.logical_card_id ".
  2977. " and user_card.active = 1 " .
  2978. " and user_pass.expired = 0 " .
  2979. ( defined($phash->{'CardId'}) ? " and user_card.logical_card_id = ? " : "" ) .
  2980. ( defined($phash->{'UserId'}) ? " and user_card.userid = ? " : "" ) .
  2981. ( defined($phash->{'PassId'}) ? " and user_pass.user_pass_id = ? " : "") .
  2982. ( defined($phash->{'Active'}) ? " and user_pass.active = ? " : "" ) .
  2983. " and user_pass.rule = rule_class.rulename ");
  2984. $query->execute(@param);
  2985. my $row = $query->fetchrow_hashref;
  2986. $self->unlock_commit() if $lock_local;
  2987. if (!$row)
  2988. {
  2989. $rhash->{'Reason'} = "No Results";
  2990. return undef;
  2991. }
  2992. while ( my ($k, $v) = each(%$row) )
  2993. {
  2994. $rhash->{$k} = $v;
  2995. }
  2996. return 1;
  2997. }
  2998. ###
  2999. #
  3000. #sub get_user_pass_old {
  3001. # my $self = shift;
  3002. # my $rhash = shift;
  3003. # my $phash = shift;
  3004. #
  3005. # my ($query, $result);
  3006. #
  3007. # if (!$phash->{'PassId'})
  3008. # {
  3009. # $rhash->{'Reason'} = "Invalid PassId";
  3010. # return undef;
  3011. # }
  3012. #
  3013. # my $fields = "rule_class.ruleclass Type";
  3014. # while ( my ($k, $v) = each(%user_pass_field_map) )
  3015. # {
  3016. # $fields .= ", user_pass.$k $v";
  3017. # }
  3018. #
  3019. # my @param;
  3020. # push @param, $phash->{'PassId'};
  3021. # push @param, $phash->{'UserId'} if $phash->{'UserId'};
  3022. #
  3023. # $query =
  3024. # $self->prepare("select $fields " .
  3025. # " from user_pass, " .
  3026. # " user_card, " .
  3027. # " rule_class " .
  3028. # "where user_pass.user_pass_id = ? ".
  3029. # " and user_card.logical_card_id = user_pass.logical_card_id ".
  3030. # " and user_card.active = 1 " .
  3031. # ( defined($phash->{'UserId'}) ? " and user_card.userid = ? " : "" ) .
  3032. # " and user_pass.rule = rule_class.rulename ");
  3033. # $query->execute(@param);
  3034. # my $row = $query->fetchrow_hashref;
  3035. # if (!$row)
  3036. # {
  3037. # $rhash->{'Reason'} = "Invalid UserId or PassId";
  3038. # return undef;
  3039. # }
  3040. #
  3041. # while ( my ($k, $v) = each(%$row) )
  3042. # {
  3043. # $rhash->{$k} = $v;
  3044. # }
  3045. #
  3046. # return 1;
  3047. #
  3048. #}
  3049. #
  3050. ###
  3051. #sub get_passes_on_card {
  3052. sub GetPassesOnCard
  3053. {
  3054. my $self = shift;
  3055. my $rhash = shift;
  3056. my $phash = shift;
  3057. my $FUNC_NAME = 'GetPassesOnCard';
  3058. my $lock_local = ($self->lock_active() ? 0 : 1);
  3059. # $self->begin_locked_transaction( { 'org_default_card_value' => 'r', 'user_card' => 'r', 'user_pass' => 'r', 'rule_class' => 'r' }) if $lock_local;
  3060. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3061. my $logical_card_id =
  3062. $self->GetLogicalCardId($phash);
  3063. my $fields = " case when rule_class.rulename is null then 'OTHER' " .
  3064. " else rule_class.ruleclass end Type ";
  3065. while ( my ($k, $v) = each(%user_pass_field_map) )
  3066. {
  3067. $fields .= ", user_pass.$k $v";
  3068. }
  3069. my $query =
  3070. $self->prepare(" select $fields " .
  3071. " from user_pass left join rule_class " .
  3072. " on rule_class.rulename = user_pass.rule " .
  3073. " where user_pass.logical_card_id = ? " .
  3074. " and user_pass.expired = 0 " .
  3075. " order by user_pass.queue_order asc ");
  3076. my $result = $query->execute($logical_card_id);
  3077. my $ind = '';
  3078. my $pos = 0;
  3079. while (my $row = $query->fetchrow_hashref) {
  3080. last if ($phash->{'MaxPass'} && ($pos >= $phash->{'MaxPass'}));
  3081. while ( my ($k, $v) = each(%$row) )
  3082. {
  3083. $rhash->{$k . $ind} = $v;
  3084. }
  3085. $ind = "[" . (++$pos) . "]";
  3086. }
  3087. $rhash->{'NPass'} = '0';
  3088. $rhash->{'NPass'} = $pos if $pos;
  3089. $self->unlock_commit() if $lock_local;
  3090. return 1;
  3091. }
  3092. ###
  3093. sub user_card_has_active_pass {
  3094. my $self = shift;
  3095. my $logical_card_id = shift;
  3096. my $FUNC_NAME = 'user_card_has_active_pass';
  3097. my $lock_local = ($self->lock_active() ? 0 : 1);
  3098. # $self->begin_locked_transaction( { 'user_pass' => 'r' }) if $lock_local;
  3099. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3100. my $query =
  3101. $self->prepare("select count(user_pass_id) num " .
  3102. " from user_pass " .
  3103. " where logical_card_id = ? " .
  3104. " and active = 1 " .
  3105. " and expired = 0 " );
  3106. $query->execute($logical_card_id);
  3107. $self->unlock_commit() if $lock_local;
  3108. return ($query->fetchrow_arrayref->[0]==1);
  3109. }
  3110. ###
  3111. sub activate_user_card_pass {
  3112. my $self = shift;
  3113. my $card_id = shift;
  3114. my $FUNC_NAME = 'activate_user_card_pass';
  3115. my $lock_local = ($self->lock_active() ? 0 : 1);
  3116. # $self->begin_locked_transaction( { 'user_pass' => 'w' }) if $lock_local;
  3117. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3118. my $query =
  3119. $self->prepare("select min(queue_order) " .
  3120. " from user_pass " .
  3121. " where logical_card_id = ? " .
  3122. " and expired = 0 ");
  3123. $query->execute($card_id);
  3124. my $q = $query->fetchrow_arrayref->[0];
  3125. if (!defined($q))
  3126. {
  3127. $self->unlock_rollback() if $lock_local;
  3128. return undef;
  3129. }
  3130. $query =
  3131. $self->prepare("select user_pass_id " .
  3132. " from user_pass " .
  3133. " where logical_card_id = ? " .
  3134. " and queue_order = ? ");
  3135. $query->execute($card_id, $q);
  3136. my $user_pass_id = $query->fetchrow_arrayref->[0];
  3137. $query =
  3138. $self->prepare("update user_pass " .
  3139. " set active = 1, " .
  3140. " activated = now() " .
  3141. " where user_pass_id = ? ");
  3142. $query->execute($user_pass_id);
  3143. $self->unlock_commit() if $lock_local;
  3144. return 1;
  3145. }
  3146. ####
  3147. sub user_card_pass_count {
  3148. my $self = shift;
  3149. my $card_id = shift;
  3150. my $FUNC_NAME = 'user_card_pass_count';
  3151. my $lock_local = ($self->lock_active() ? 0 : 1);
  3152. # $self->begin_locked_transaction( { 'user_pass' => 'r' }) if $lock_local;
  3153. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3154. my $query =
  3155. $self->prepare("select count(user_pass_id) num " .
  3156. " from user_pass " .
  3157. "where logical_card_id = ? " .
  3158. " and expired = 0 ");
  3159. $query->execute($card_id);
  3160. $self->unlock_commit() if $lock_local;
  3161. return $query->fetchrow_arrayref->[0];
  3162. }
  3163. ###
  3164. sub get_next_queue_order {
  3165. my $self = shift;
  3166. my $logical_card_id = shift;
  3167. my $FUNC_NAME = 'get_next_queue_order';
  3168. my $lock_local = ($self->lock_active() ? 0 : 1);
  3169. # $self->begin_locked_transaction( { 'user_pass' => 'r' }) if $lock_local;
  3170. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3171. my $query =
  3172. $self->prepare("select max(queue_order) num " .
  3173. " from user_pass " .
  3174. " where logical_card_id = ? ");
  3175. $query->execute($logical_card_id);
  3176. my $q = $query->fetchrow_arrayref->[0];
  3177. $self->unlock_commit() if $lock_local;
  3178. return ( $q ? ($q+1) : 1 );
  3179. }
  3180. ###
  3181. sub RemovePass {
  3182. my $self = shift;
  3183. my $rhash = shift;
  3184. my $phash = shift;
  3185. my $FUNC_NAME = 'RemovePass';
  3186. my $lock_local = ($self->lock_active() ? 0 : 1);
  3187. # $self->begin_locked_transaction_common() if $lock_local;
  3188. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3189. my %pass;
  3190. my $r = $self->GetUserPass(\%pass, $phash);
  3191. if ( (!$pass{PassId}) || (!$r) )
  3192. {
  3193. $self->unlock_rollback() if $lock_local;
  3194. $rhash->{Reason} = ($pass{Reason} || "Invalid PassId");
  3195. return undef;
  3196. }
  3197. my $pass_id = $pass{PassId};
  3198. my $card_id = $pass{CardId};
  3199. my $ret =
  3200. $self->update_user_pass($pass_id,
  3201. {
  3202. active => 0,
  3203. expired => 1,
  3204. deactivated => unix_to_readable_time()
  3205. }
  3206. );
  3207. if ($pass{Active})
  3208. {
  3209. $self->activate_user_card_pass($card_id);
  3210. $self->insert_active_rider_table( { logical_card_id => $card_id } );
  3211. }
  3212. $self->unlock_commit() if $lock_local;
  3213. return 1;
  3214. }
  3215. ##
  3216. sub deactivate_user_pass {
  3217. my $self = shift;
  3218. my $pass_id = shift;
  3219. my $FUNC_NAME = "deactivate_user_pass";
  3220. return undef if !$pass_id;
  3221. my $lock_local = ($self->lock_active() ? 0 : 1);
  3222. # $self->begin_locked_transaction( { 'audit_user_pass' => 'w', 'user_pass' => 'w', 'user_card' => 'r', 'rule_class' => 'r' }) if $lock_local;
  3223. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3224. my %pass;
  3225. # $self->get_user_pass(\%pass, { PassId => $pass_id });
  3226. $self->GetUserPass(\%pass, { PassId => $pass_id });
  3227. # return undef if (!$pass{'PassId'} or !$pass{'Active'});
  3228. if ((!$pass{'PassId'} or !$pass{'Active'}))
  3229. {
  3230. $self->unlock_rollback() if $lock_local;
  3231. return undef;
  3232. }
  3233. # return $self->update_user_pass($pass_id, { active => 0, expired => 1, deactivated => unix_to_readable_time() } );
  3234. my $ret =
  3235. $self->update_user_pass($pass_id,
  3236. {
  3237. active => 0,
  3238. expired => 1,
  3239. deactivated => unix_to_readable_time()
  3240. }
  3241. );
  3242. $self->unlock_commit() if $lock_local;
  3243. # return $ret;
  3244. return 1;
  3245. }
  3246. ###
  3247. sub update_user_pass {
  3248. my $self = shift;
  3249. my $pass_id = shift;
  3250. my $fields = shift;
  3251. my $FUNC_NAME = "update_user_pass";
  3252. return undef if !$pass_id;
  3253. my $str;
  3254. my @val;
  3255. while ( my ($k, $v) = each(%$fields) )
  3256. {
  3257. next if (!$user_pass_field_map{$k});
  3258. $str .= " , " if $str;
  3259. $str .= " $k = ? ";
  3260. push @val, $v;
  3261. }
  3262. return undef if (scalar(@val)==0);
  3263. my $lock_local = ($self->lock_active() ? 0 : 1);
  3264. # $self->begin_locked_transaction( { 'audit_user_pass' => 'w', 'user_pass' => 'w' }) if $lock_local;
  3265. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3266. my $audit_id =
  3267. $self->audit_user_pass_start($pass_id, "$PACKAGE_NAME: $FUNC_NAME");
  3268. my $query =
  3269. $self->prepare("update user_pass set $str where user_pass_id = ? ");
  3270. $query->execute(@val, $pass_id);
  3271. $self->audit_user_pass_end($pass_id, $audit_id);
  3272. $self->unlock_commit() if $lock_local;
  3273. return 1;
  3274. }
  3275. ####
  3276. #sub transfer_pass {
  3277. sub TransferPass
  3278. {
  3279. my $self = shift;
  3280. my $rhash = shift;
  3281. my $phash = shift;
  3282. my $FUNC_NAME = 'TransferPass';
  3283. my $pass_id = $phash->{'PassId'};
  3284. my $lock_local = ($self->lock_active() ? 0 : 1);
  3285. # $self->lock_common() if $lock_local;
  3286. # $self->begin_locked_transaction_common() if $lock_local;
  3287. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3288. my $from_card_id =
  3289. $self->get_user_pass_logical_card_id( $pass_id );
  3290. my $to_card_id =
  3291. $self->GetDestLogicalCardId( $phash );
  3292. # $self->get_dest_logical_card_id( $phash );
  3293. if (!$from_card_id || !$to_card_id)
  3294. {
  3295. $self->unlock_rollback() if $lock_local;
  3296. $rhash->{'Reason'} = "Invalid Card (from id $from_card_id, to id $to_card_id)";
  3297. return undef;
  3298. }
  3299. my $queue_order =
  3300. $self->get_next_queue_order($to_card_id);
  3301. # move pass to new card
  3302. $self->update_user_pass($pass_id, { logical_card_id => $to_card_id,
  3303. queue_order => $queue_order,
  3304. active => 0 } );
  3305. # if we removed an active pass, activate the current pass and update the art
  3306. if ( !$self->user_card_has_active_pass($from_card_id) )
  3307. {
  3308. if ($self->user_card_pass_count($from_card_id) > 0)
  3309. {
  3310. $self->activate_user_card_pass($from_card_id);
  3311. }
  3312. if (!$self->pending_card($from_card_id))
  3313. {
  3314. $self->insert_active_rider_table( { logical_card_id => $from_card_id } );
  3315. }
  3316. }
  3317. # if we added an active pass, activate the current pass and update the art
  3318. if ( !$self->user_card_has_active_pass($to_card_id) )
  3319. {
  3320. if ($self->user_card_pass_count($to_card_id) > 0)
  3321. {
  3322. $self->activate_user_card_pass($to_card_id);
  3323. }
  3324. if (!$self->pending_card($to_card_id))
  3325. {
  3326. $self->insert_active_rider_table( { logical_card_id => $to_card_id } );
  3327. }
  3328. }
  3329. $self->unlock_commit() if $lock_local;
  3330. $rhash->{'PassId'} = $pass_id;
  3331. return 1;
  3332. }
  3333. ###
  3334. sub get_pass_type_and_name {
  3335. my $self = shift;
  3336. my $group_id = shift;
  3337. my $type = shift;
  3338. my $FUNC_NAME = 'get_pass_type_and_name';
  3339. my $lock_local = ($self->lock_active() ? 0 : 1);
  3340. # $self->begin_locked_transaction( { 'rule_class' => 'r', 'rule_mappings' => 'r' }) if $lock_local;
  3341. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3342. my $query =
  3343. $self->prepare("select rule_class.ruleclass, " .
  3344. " rule_class.rulename " .
  3345. " from rule_mappings, rule_class " .
  3346. " where rule_mappings.group_id = ? " .
  3347. " and rule_mappings.rule like ? " .
  3348. " and rule_class.rulename = rule_mappings.rule " .
  3349. " and rule_mappings.active = 1 ");
  3350. $query->execute($group_id, '%-' . $type);
  3351. my $row = $query->fetchrow_arrayref;
  3352. $self->unlock_commit() if $lock_local;
  3353. return undef if !$row;
  3354. return ($row->[0], $row->[1]);
  3355. }
  3356. ###
  3357. sub valid_pass_param {
  3358. my $self = shift;
  3359. my $pass_type = shift;
  3360. my $phash= shift;
  3361. my $FUNC_NAME = 'valid_pass_param';
  3362. return 0
  3363. if ( (lc($pass_type) eq 'nride') &&
  3364. (!$phash->{'NRideOrig'} || !$phash->{'NRideRemain'}) );
  3365. # !$phash->{'NRideOrig'} && !$phash->{'NRideRemain'} );
  3366. return 0
  3367. if ( (lc($pass_type) eq 'nride') &&
  3368. ($phash->{'NRideOrig'} < $phash->{'NRideRemain'}) );
  3369. return 0
  3370. if ( (lc($pass_type) eq 'nday') &&
  3371. !$phash->{'NDayOrig'} );
  3372. return 0
  3373. if ( (lc($pass_type) eq 'nday') &&
  3374. $phash->{'NDayExpiration'} &&
  3375. (!($phash->{'NDayExpiration'} =~ m/^\d\d\d\d[-\/]\d\d?[-\/]\d\d? *\d\d?:\d\d?:\d\d?$/)) );
  3376. return 1;
  3377. }
  3378. ###
  3379. #sub add_pass {
  3380. sub AddPass
  3381. {
  3382. my $self = shift;
  3383. my $rhash = shift;
  3384. my $phash = shift;
  3385. my $FUNC_NAME = 'AddPass';
  3386. my %blacklisted_fields =
  3387. ( PassId => 1,
  3388. Active => 1,
  3389. Expired => 1 );
  3390. my $lock_local = ($self->lock_active() ? 0 : 1);
  3391. # $self->lock_common() if $lock_local;
  3392. # $self->begin_locked_transaction_common() if $lock_local;
  3393. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3394. # my $logical_card_id = $self->GetLogicalCardId($phash);
  3395. my $logical_card_id = $self->GetLogicalCardId(
  3396. {
  3397. CardId => $phash->{CardId},
  3398. MagTrack => $phash->{MagTrack},
  3399. MagStripe => $phash->{MagStripe},
  3400. MagToken=> $phash->{MagToken},
  3401. RFLength => $phash->{RFLength},
  3402. RFSite => $phash->{RFSite},
  3403. RFID => $phash->{RFID},
  3404. RFIDToken => $phash->{RFIDToken},
  3405. GroupId => $phash->{CardGroupId},
  3406. GroupName => $phash->{CardGroupName}
  3407. } );
  3408. #my $group_id = $self->get_user_card_group_id($logical_card_id);
  3409. my $group_id;
  3410. if ($phash->{GroupId})
  3411. {
  3412. $group_id = $phash->{GroupId};
  3413. }
  3414. else
  3415. {
  3416. $group_id = $self->get_group_id( $phash->{GroupName} || $DEFAULT_GROUP_NAME );
  3417. }
  3418. if (!$logical_card_id || !$group_id)
  3419. {
  3420. $self->unlock_rollback() if $lock_local;
  3421. $rhash->{'Reason'} = "Invalid Card ($logical_card_id, $group_id)";
  3422. return undef;
  3423. }
  3424. my ($pass_type, $rule_name) =
  3425. $self->get_pass_type_and_name($group_id, $phash->{'Type'});
  3426. if (!$pass_type || !$rule_name)
  3427. {
  3428. $self->unlock_rollback() if $lock_local;
  3429. $rhash->{'Reason'} = "Invalid rule";
  3430. return undef;
  3431. }
  3432. if ( !$self->valid_pass_param($pass_type, $phash) )
  3433. {
  3434. $self->unlock_rollback() if $lock_local;
  3435. $rhash->{'Reason'} = "Invalid rule/parameter combination for $pass_type";
  3436. ### DEBUG
  3437. if (lc($pass_type) eq 'nday') {
  3438. $rhash->{'Reason'} .= "(NDayOrig " . $phash->{NDayOrig} . ", NDay " . $phash->{NDay} . ", NDayExpiration " . $phash->{NDayExpiration} . ")";
  3439. } elsif (lc($pass_type) eq 'nride') {
  3440. $rhash->{'Reason'} .= "(NRideOrig " . $phash->{NRideOrig} . ", NRideRemain" . $phash->{NRideRemain} . ")";
  3441. }
  3442. ### DEBUG
  3443. return undef;
  3444. }
  3445. my %insert_param;
  3446. while ( my ($k, $v) = each(%user_pass_field_map) )
  3447. {
  3448. next if !$phash->{$v} || $blacklisted_fields{$v};
  3449. $insert_param{$k} = $phash->{$v};
  3450. }
  3451. $insert_param{'rule'} = $rule_name;
  3452. $insert_param{'logical_card_id'} = $logical_card_id;
  3453. $insert_param{'active'} = 0;
  3454. $insert_param{'expired'} = 0;
  3455. $insert_param{'queue_order'} =
  3456. $self->get_next_queue_order($logical_card_id);
  3457. my $pass_id =
  3458. $self->insert_user_pass( \%insert_param );
  3459. if (!$self->pending_card($logical_card_id) &&
  3460. !$self->user_card_has_active_pass($logical_card_id))
  3461. {
  3462. $self->activate_user_card_pass($logical_card_id);
  3463. $self->insert_active_rider_table( { logical_card_id => $logical_card_id } );
  3464. }
  3465. $self->unlock_commit() if $lock_local;
  3466. $rhash->{'PassId'} = $pass_id;
  3467. return 1;
  3468. }
  3469. ###
  3470. my %pass_option_map =
  3471. ( id => "PassOptionId",
  3472. group_id => "GroupId",
  3473. param => "Param",
  3474. name => "Name",
  3475. rule => "Rule",
  3476. type => "Type",
  3477. description => "Description",
  3478. num_opt => "NumPassOption",
  3479. option0 => "Option0",
  3480. option1 => "Option1",
  3481. option2 => "Option2",
  3482. option3 => "Option3"
  3483. );
  3484. my %default_pass_value_map =
  3485. ( start => "Start",
  3486. end => "Expiration",
  3487. nday => "DefaultNDay",
  3488. nride => "DefaultNRide"
  3489. );
  3490. sub GetPassOptions
  3491. {
  3492. my $self = shift;
  3493. my $rhash = shift;
  3494. my $phash = shift;
  3495. my $FUNC_NAME = 'GetPassOptions';
  3496. my ($query, $row);
  3497. my $group_inclusion;
  3498. my @group_name;
  3499. my @gruop_id;
  3500. my $n;
  3501. $n = $phash->{NGroup};
  3502. if (!$n)
  3503. {
  3504. $rhash->{Reason} = "Invalid NGroup";
  3505. return undef;
  3506. }
  3507. $group_inclusion = "(false ";
  3508. for (my $i=0; $i<$n; $i++)
  3509. {
  3510. my $key = "GroupName";
  3511. $key = "${key}[$i]" if $i;
  3512. push @group_name, $phash->{$key};
  3513. $group_inclusion .= " or groups.group_name = ? ";
  3514. }
  3515. $group_inclusion .= ")";
  3516. my $lock_local = ($self->lock_active() ? 0 : 1);
  3517. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3518. $query =
  3519. $self->prepare("select group_id from groups where $group_inclusion");
  3520. $query->execute(@group_name);
  3521. $group_inclusion = "(false ";
  3522. my @group_id;
  3523. while ($row = $query->fetchrow_arrayref)
  3524. {
  3525. push @group_id, $row->[0];
  3526. $group_inclusion .= " or pass_option.group_id = ? ";
  3527. }
  3528. $group_inclusion .= ")";
  3529. $query =
  3530. $self->prepare("select pass_option." . join(", pass_option.", keys(%pass_option_map) ) . " , " .
  3531. " org_default_pass_value." . join(", org_default_pass_value.", keys(%default_pass_value_map)) . "," .
  3532. " groups.group_name GroupName " .
  3533. " from groups, pass_option left join org_default_pass_value " .
  3534. " on ( pass_option.rule = org_default_pass_value.name " .
  3535. " and pass_option.group_id = org_default_pass_value.group_id ) " .
  3536. " where $group_inclusion " .
  3537. " and pass_option.active = 1 " .
  3538. " and groups.group_id = pass_option.group_id " .
  3539. " order by pass_option.id ");
  3540. $query->execute(@group_id);
  3541. my $ind = '';
  3542. my $pos = 0;
  3543. while ($row = $query->fetchrow_hashref)
  3544. {
  3545. while (my ($key, $val) = each(%pass_option_map))
  3546. {
  3547. $rhash->{$val . $ind} = $row->{$key};
  3548. }
  3549. while (my ($key, $val) = each(%default_pass_value_map))
  3550. {
  3551. $rhash->{$val . $ind} = $row->{$key};
  3552. }
  3553. $rhash->{"GroupName$ind"} = $row->{GroupName};
  3554. $ind = "[" . (++$pos) . "]";
  3555. }
  3556. $rhash->{'NPassOption'} = $pos;
  3557. $self->unlock_commit() if $lock_local;
  3558. return 1;
  3559. }
  3560. ####
  3561. my %price_point_map =
  3562. ( id => "PricePointId",
  3563. price => "Price",
  3564. param => "Param",
  3565. name => "Name",
  3566. rule => "Rule",
  3567. type => "Type",
  3568. description => "Description",
  3569. num_opt => "NumPriceOption",
  3570. price_option0 => "PriceOption0",
  3571. price_option1 => "PriceOption1",
  3572. price_option2 => "PriceOption2",
  3573. price_option3 => "PriceOption3"
  3574. );
  3575. ####
  3576. #sub get_price_points {
  3577. sub GetPricePoints
  3578. {
  3579. my $self = shift;
  3580. my $rhash = shift;
  3581. my $phash = shift;
  3582. my $FUNC_NAME = 'GetPricePoints';
  3583. my ($query, $row);
  3584. my $lock_local = ($self->lock_active() ? 0 : 1);
  3585. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3586. my $logical_card_id =
  3587. $self->GetLogicalCardId($phash);
  3588. my %group_hash;
  3589. $self->GetDefaultCardGroupInfo(\%group_hash, $phash);
  3590. my $group_id = $group_hash{'GroupId'};
  3591. my $group_name = $group_hash{'GroupName'};
  3592. if ($logical_card_id)
  3593. {
  3594. $query =
  3595. $self->prepare("select user_card.group_id, " .
  3596. " groups.group_name " .
  3597. " from user_card, groups " .
  3598. " where user_card.logical_card_id = ? " .
  3599. " and groups.group_id = user_card.group_id " .
  3600. " limit 1 ");
  3601. $query->execute($logical_card_id);
  3602. $row = $query->fetchrow_arrayref;
  3603. if ($row) {
  3604. $group_id = $row->[0];
  3605. $group_name = $row->[1];
  3606. }
  3607. }
  3608. $query =
  3609. $self->prepare("select price_point." . join(", price_point.", keys(%price_point_map) ) . " , " .
  3610. " org_default_pass_value." . join(", org_default_pass_value.", keys(%default_pass_value_map)) .
  3611. " from price_point left join org_default_pass_value " .
  3612. " on (price_point.name = org_default_pass_value.name) " .
  3613. " where price_point.group_id = ? and price_point.active = 1 " .
  3614. " order by price_point.id ");
  3615. $query->execute($group_id);
  3616. #$rhash->{'GroupId'} = $group_id;
  3617. #$rhash->{'GroupName'} = $group_name;
  3618. my $ind = '';
  3619. my $pos = 0;
  3620. while ($row = $query->fetchrow_hashref)
  3621. {
  3622. while (my ($key, $val) = each(%price_point_map))
  3623. {
  3624. $rhash->{$val . $ind} = $row->{$key};
  3625. }
  3626. while (my ($key, $val) = each(%default_pass_value_map))
  3627. {
  3628. $rhash->{$val . $ind} = $row->{$key};
  3629. }
  3630. $rhash->{'GroupId' . $ind} = $group_id;
  3631. $rhash->{'GroupName' . $ind} = $group_name;
  3632. $ind = "[" . (++$pos) . "]";
  3633. }
  3634. $rhash->{'NPricePoint'} = $pos;
  3635. $self->unlock_commit() if $lock_local;
  3636. return 1;
  3637. }
  3638. ###
  3639. sub check_dup_billing_log {
  3640. my $self = shift;
  3641. my $unix_ts = shift;
  3642. my $md5 = shift;
  3643. my $FUNC_NAME = 'check_dup_billing_log';
  3644. my $lock_local = ($self->lock_active() ? 0 : 1);
  3645. # $self->begin_locked_transaction( { 'billing_log' => 'r' }) if $lock_local;
  3646. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3647. my $query =
  3648. $self->prepare("select count(*) num
  3649. from billing_log
  3650. where ride_time = FROM_UNIXTIME(?)
  3651. and conf_checksum = ?");
  3652. my $r = $query->execute($unix_ts, $md5);
  3653. $self->unlock_commit() if $lock_local;
  3654. return $query->fetchrow_arrayref->[0] ;
  3655. }
  3656. ###
  3657. sub insert_billing_log {
  3658. my $self = shift;
  3659. my $FUNC_NAME = 'insert_billing_log';
  3660. my $lock_local = ($self->lock_active() ? 0 : 1);
  3661. # $self->begin_locked_transaction( { 'billing_log' => 'w' }) if $lock_local;
  3662. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3663. my $query =
  3664. $self->prepare("REPLACE INTO billing_log
  3665. (conf_checksum,
  3666. equip_num,
  3667. driver,
  3668. paddle,
  3669. route,
  3670. trip,
  3671. stop,
  3672. ride_time,
  3673. latitude,
  3674. longitude,
  3675. action,
  3676. rule,
  3677. ruleparam,
  3678. reason,
  3679. credential,
  3680. logical_card_id,
  3681. cash_value,
  3682. stop_name)
  3683. VALUES (?, ?, ?, ?, ?, ?, ?, FROM_UNIXTIME(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
  3684. ");
  3685. my $r = $query->execute(@_);
  3686. $self->unlock_commit() if $lock_local;
  3687. return $r;
  3688. }
  3689. ###
  3690. sub diagnostic_log {
  3691. my $self = shift;
  3692. my $loglvl = shift;
  3693. my $str = shift;
  3694. my $FUNC_NAME = 'diagnostic_log';
  3695. my $lock_local = ($self->lock_active() ? 0 : 1);
  3696. # $self->begin_locked_transaction( { 'diagnostic_log' => 'w' }) if $lock_local;
  3697. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3698. my $ins =
  3699. $self->prepare("insert into diagnostic_log (loglvl, message) values (?, ?)");
  3700. my $ret = $ins->execute($loglvl, $str);
  3701. $self->unlock_commit() if $lock_local;
  3702. return $ret;
  3703. }
  3704. sub api_log {
  3705. my $self = shift;
  3706. my $msg = shift;
  3707. my $FUNC_NAME = "api_log";
  3708. my $lock_local = ($self->lock_active() ? 0 : 1);
  3709. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3710. my $ins =
  3711. $self->prepare("insert into org_api_log (log) values (?)");
  3712. my $ret = $ins->execute($msg);
  3713. $self->unlock_commit() if $lock_local;
  3714. return $ret;
  3715. }
  3716. ### Admin specific functions
  3717. sub admin_exists {
  3718. my $self = shift;
  3719. my $username = shift;
  3720. my $FUNC_NAME = 'admin_exists';
  3721. my $lock_local = ($self->lock_active() ? 0 : 1);
  3722. # $self->begin_locked_transaction( { 'admins' => 'r' }) if $lock_local;
  3723. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3724. my $query = $self->prepare("select username from admins where active = 1 and username = ? "); # and active = 1 ");
  3725. $query->execute($username);
  3726. my $row = $query->fetchrow_arrayref;
  3727. $self->unlock_commit() if $lock_local;
  3728. return 0 if !$row or ($row->[0] ne $username);
  3729. return 1;
  3730. }
  3731. ##
  3732. sub get_admin_id {
  3733. my $self = shift;
  3734. my $phash = shift;
  3735. my $FUNC_NAME = 'get_admin_id';
  3736. my ($query, $result, $row);
  3737. my $credential_match = " active = 1 ";
  3738. my @credential_val;
  3739. if ( defined($phash->{'UserName'}) )
  3740. {
  3741. $credential_match .= " and username = ? ";
  3742. push @credential_val , $phash->{'UserName'};
  3743. }
  3744. if ( defined($phash->{'UserId'}) )
  3745. {
  3746. $credential_match .= " and userid = ? ";
  3747. push @credential_val, $phash->{'UserId'};
  3748. }
  3749. if ( defined($phash->{'PasswordHash'}) )
  3750. {
  3751. # $credential_match .= " and passwordhash = ? ";
  3752. $credential_match .= " and password = ? ";
  3753. push @credential_val, $phash->{'PasswordHash'};
  3754. }
  3755. return undef if scalar(@credential_val)==0;
  3756. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  3757. # $self->begin_locked_transaction( { 'admins' => 'r' } ) if $lock_local;
  3758. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3759. $query = $self->prepare( "select userid " .
  3760. " from admins " .
  3761. " where $credential_match " .
  3762. " limit 1 ");
  3763. $result = $query->execute(@credential_val);
  3764. $row = $query->fetchrow_arrayref;
  3765. if (!$row)
  3766. {
  3767. $self->unlock_rollback() if $lock_local;
  3768. return undef;
  3769. }
  3770. $self->unlock_commit() if $lock_local;
  3771. return $row->[0];
  3772. }
  3773. ###
  3774. sub CreateAdmin {
  3775. my $self = shift;
  3776. my $rhash = shift;
  3777. my $phash = shift;
  3778. my ($query, $result);
  3779. my $FUNC_NAME = "CreateAdmin";
  3780. my %blacklist_field = ( userid => 1 );
  3781. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  3782. # $self->begin_locked_transaction( { 'admins' => 'w', 'audit_admins' => 'w' }) if $lock_local;
  3783. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3784. if ( !defined($phash->{'UserName'}) ||
  3785. $self->admin_exists($phash->{'UserName'}) )
  3786. {
  3787. $rhash->{'Reason'} = "Invalid admin";
  3788. $self->unlock_rollback() if $lock_local;
  3789. return undef;
  3790. }
  3791. my $group_id;
  3792. if ($phash->{GroupId})
  3793. {
  3794. $group_id = $phash->{GroupId};
  3795. }
  3796. else
  3797. {
  3798. $group_id = $self->get_group_id( $phash->{GroupName} || $DEFAULT_GROUP_NAME );
  3799. }
  3800. if (!$group_id)
  3801. {
  3802. $rhash->{Reason} = "Bad GroupId";
  3803. $self->unlock_rollback() if $lock_local;
  3804. return undef;
  3805. }
  3806. my @db_field;
  3807. my @param;
  3808. while (my ($k, $v) = each(%admins_field_map) )
  3809. {
  3810. next if ( $blacklist_field{lc($k)} );
  3811. push @db_field, $k;
  3812. if ($v eq 'GroupId')
  3813. {
  3814. push @param, $group_id;
  3815. }
  3816. else
  3817. {
  3818. push @param, $phash->{$v};
  3819. }
  3820. }
  3821. my $audit_id = $self->audit_admins_start(undef, "$PACKAGE_NAME: $FUNC_NAME");
  3822. my $query_str = "insert into admins " .
  3823. " ( " . join(", ", @db_field) . " ) values " .
  3824. " ( ? " . ", ?"x(scalar(@db_field)-1) . " )";
  3825. $query = $self->prepare($query_str);
  3826. $result = $query->execute(@param);
  3827. my $user_id = $self->last_insert_id();
  3828. $self->audit_admins_end($user_id, $audit_id);
  3829. $query = $self->prepare("select userid, " . join(', ', @db_field) . " from admins where userid = ?");
  3830. $query->execute($user_id);
  3831. my $href = $query->fetchrow_hashref;
  3832. for (my $i=0; $i<scalar(@db_field); $i++)
  3833. {
  3834. $rhash->{$admins_field_map{$db_field[$i]}} = $href->{$db_field[$i]};
  3835. }
  3836. $rhash->{'UserId'} = $href->{'userid'};
  3837. $self->unlock_commit() if $lock_local;
  3838. return 1;
  3839. }
  3840. ####
  3841. sub GetAdmin {
  3842. my $self = shift;
  3843. my $rhash = shift;
  3844. my $phash = shift;
  3845. my ($query, $result);
  3846. my $FUNC_NAME = "GetAdmin";
  3847. # my %blacklist_field = ( 'password' => 1 );
  3848. my %blacklist_field = ( );
  3849. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  3850. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3851. my $userid = $self->get_admin_id($phash);
  3852. if (!$userid)
  3853. {
  3854. $rhash->{'Reason'} = "Invalid user credential";
  3855. $self->unlock_rollback() if $lock_local;
  3856. return undef;
  3857. }
  3858. my $count=0;
  3859. my $fields;
  3860. while ( my ($k, $v) = each(%admins_field_map) )
  3861. {
  3862. next if ( $blacklist_field{lc($k)} );
  3863. $fields .= ", " if ($count++);
  3864. $fields .= " admins.$k $v ";
  3865. }
  3866. $query = $self->prepare("select groups.group_name GroupName, " .
  3867. " $fields " .
  3868. " from admins left join groups on (admins.group_id = groups.group_id) ".
  3869. " where admins.userid = ? " .
  3870. " and admins.active = 1 " .
  3871. " limit 1");
  3872. $query->execute($userid);
  3873. my $row = $query->fetchrow_hashref;
  3874. if (!$row)
  3875. {
  3876. $rhash->{'Reason'} = "Invalid Admin";
  3877. $self->unlock_rollback() if $lock_local;
  3878. return undef;
  3879. }
  3880. $self->unlock_commit() if $lock_local;
  3881. while ( my ($k, $v) = each(%$row) )
  3882. {
  3883. $rhash->{$k} = $v;
  3884. }
  3885. return 1;
  3886. }
  3887. ###
  3888. sub SetAdmin {
  3889. my $self = shift;
  3890. my $rhash = shift;
  3891. my $phash = shift;
  3892. my ($query, $result, $i, $j);
  3893. my $FUNC_NAME= "SetAdmin";
  3894. my $update_fields;
  3895. my @update_val;
  3896. my %blacklist_field = ( username => 1, userid => 1 );
  3897. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  3898. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3899. my $userid = $self->get_admin_id(
  3900. {
  3901. UserName => $phash->{UserName},
  3902. UserId => $phash->{UserId}
  3903. }
  3904. );
  3905. if (!defined($userid))
  3906. {
  3907. $rhash->{'Reason'} = "Invalid user credential";
  3908. $self->unlock_rollback() if $lock_local;
  3909. return undef;
  3910. }
  3911. while ( my ($k, $v) = each(%admins_field_map) )
  3912. {
  3913. next if $blacklist_field{lc($k)} || !exists($phash->{$v});
  3914. $update_fields .= ", " if $update_fields;
  3915. $update_fields .= " $k = ? ";
  3916. push @update_val, $phash->{$v};
  3917. }
  3918. if (scalar(@update_val)==0)
  3919. {
  3920. $rhash->{'Reason'} = "Nothing to update";
  3921. $self->unlock_rollback() if $lock_local;
  3922. return undef;
  3923. }
  3924. push @update_val, $userid;
  3925. my $audit_id =
  3926. $self->audit_admins_start($userid, "$PACKAGE_NAME: $FUNC_NAME");
  3927. $query =
  3928. $self->prepare("update admins " .
  3929. " set $update_fields " .
  3930. " where userid = ?");
  3931. $result =
  3932. $query->execute(@update_val);
  3933. $self->audit_admins_end($userid, $audit_id );
  3934. $rhash->{'UserId'} = $userid;
  3935. $self->unlock_commit() if $lock_local;
  3936. return 1;
  3937. }
  3938. ###
  3939. sub RemoveAdmin {
  3940. my $self = shift;
  3941. my $rhash = shift;
  3942. my $phash = shift;
  3943. my ($query, $result);
  3944. my $FUNC_NAME = "RemoveAdmin";
  3945. my $lock_local = ( $self->lock_active() ? 0 : 1 );
  3946. # $self->begin_locked_transaction( { 'admins' => 'w', 'audit_admins' => 'w' }) if $lock_local;
  3947. $self->begin_locked_transaction_for_function($FUNC_NAME) if $lock_local;
  3948. my $user_id = $self->get_admin_id($phash);
  3949. if (!$user_id)
  3950. {
  3951. $rhash->{'Reason'} = "Invalid user credential";
  3952. $self->unlock_rollback() if $lock_local;
  3953. return undef;
  3954. }
  3955. my $audit_id = $self->audit_admins_start(undef, "$PACKAGE_NAME: $FUNC_NAME");
  3956. $query = $self->prepare("update admins set active = 0 where userid = ? ");
  3957. $result = $query->execute($user_id);
  3958. $self->audit_admins_end($user_id, $audit_id);
  3959. $self->unlock_commit() if $lock_local;
  3960. return 1;
  3961. }
  3962. return 1;