4. EPMO Open Source Coordination Office Redaction File Detail Report

Produced by Araxis Merge on 11/16/2017 4:02:22 PM Eastern Standard Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.

4.1 Files compared

# Location File Last Modified
1 CUI-CPP-v2.3.1-release.zip\app\models user.rb Fri Oct 20 20:13:45 2017 UTC
2 CUI-CPP-v2.3.1-release.zip\app\models user.rb Thu Nov 16 18:00:11 2017 UTC

4.2 Comparison summary

Description Between
Files 1 and 2
Text Blocks Lines
Unchanged 2 1316
Changed 1 2
Inserted 0 0
Removed 0 0

4.3 Comparison options

Whitespace
Character case Differences in character case are significant
Line endings Differences in line endings (CR and LF characters) are ignored
CR/LF characters Not shown in the comparison detail

4.4 Active regular expressions

No regular expressions were active.

4.5 Comparison detail

  1   # == Schem a Informat ion
  2   #
  3   # Table na me: users
  4   #
  5   #  id                       :int eger           not nu ll, primar y key
  6   #  email                    :str ing            defaul t(""), not  null
  7   #  encrypt ed_passwor d     :str ing            defaul t(""), not  null
  8   #  reset_p assword_to ken   :str ing
  9   #  reset_p assword_se nt_at :dat etime
  10   #  remembe r_created_ at    :dat etime
  11   #  sign_in _count           :int eger           defaul t(0), not  null
  12   #  current _sign_in_a t     :dat etime
  13   #  last_si gn_in_at         :dat etime
  14   #  current _sign_in_i p     :ine t
  15   #  last_si gn_in_ip         :ine t
  16   #  created _at              :dat etime
  17   #  updated _at              :dat etime
  18   #  roles                    :tex t
  19   #  first_n ame              :str ing
  20   #  last_na me               :str ing
  21   #  is_unde r_review         :boo lean           defaul t(TRUE)
  22   #  failed_ attempts         :int eger           defaul t(0)
  23   #  unlock_ token            :str ing
  24   #  locked_ at               :dat etime
  25   #  provide r                :str ing
  26   #  uid                      :str ing
  27   #  authori zation_sta te    :str ing            defaul t("none")
  28   #  action_ token            :str ing
  29   #
  30  
  31   class User  < ActiveR ecord::Bas e
  32     include  ActiveMode l::Validat ions
  33  
  34     # For Va lidations
  35     ALPHA_NU MERICS=/[0 -9A-Za-z,. ]/
  36     DIGITS=/ \d/
  37     LC_LETTE RS=/[a-z]/
  38     SPECIAL_ CHARS=/[\$ \^\*~!@#%& ]/
  39     UC_LETTE RS=/[A-Z]/
  40     MINIMUM_ PASSWORD_L ENGTH = 12   # per VA -6500 Appx . F
  41  
  42     # Includ e default  devise mod ules. Othe rs availab le are:
  43     # :confi rmable, :l ockable, : timeoutabl e and :omn iauthable
  44     devise   :database_ authentica table,
  45              :recoverab le,
  46              :remembera ble,
  47              :trackable ,
  48              :validatab le,
  49              :lockable,
  50              :registera ble,
  51              :timeoutab le,
  52              :omniautha ble,
  53              # :confirm able,
  54              omniauth_p roviders:  [:saml]
  55  
  56     # FIXME:  commented  code belo w should e ither be f ixed or re moved.
  57  
  58     # attr_a ccessible  :email, :p assword, : password_c onfirmatio n, :rememb er_me, :us ername
  59     #
  60     # valida tes_presen ce_of :use rname
  61     # valida tes_unique ness_of :u sername
  62  
  63  
  64     # NPI -  National P rovider In dex - is a  string of  NPI value s with som e non-digi t separati on
  65     attr_acc essor :npi   # only a pplies to  role 'non_ vha' users ; not part  of the us er record
  66  
  67     attr_acc essor :duz , :via_use r_name, :s ite_id # V IA_API rel ated. Used  for stori ng the duz  session k ey and sit e id.
  68  
  69     serializ e :roles,  Array
  70  
  71     has_one  :user_pref erence, de pendent: : destroy
  72  
  73     has_many  :referral s, foreign _key: 'coo rdinator_i d'
  74     has_many  :evaluati ons
  75     has_many  :examinat ion_notes,  foreign_k ey: :from_ id
  76     has_many  :claims,  -> { disti nct }, thr ough: :eva luations
  77  
  78     has_many  :incomple te_claims,  -> {
  79       where( completed_ at: nil).o rder(creat ed_at: :de sc).distin ct
  80     }, throu gh: :evalu ations, so urce: :cla im
  81  
  82     has_many  :site_rol e_sets
  83  
  84     has_many  :sites, t hrough: :s ite_role_s ets do
  85       def << (s)
  86         self .push(s) u nless self .include?( s)
  87       end
  88     end
  89  
  90     has_and_ belongs_to _many :sup ervising,
  91                               clas s_name:    "User",
  92                               join _table:    :supervise d_clinicia ns,
  93                               fore ign_key:   :user_id,
  94                               asso ciation_fo reign_key:  :supervis ed_id do
  95       def << (u)
  96         # SM ELL: why n ot use an  exception?
  97         retu rn "Use ad d_supervis ed_clinici an()"
  98       end
  99  
  100       def de lete(u)
  101         # SM ELL: why n ot use an  exception?
  102         retu rn "Use re move_super vised_clin ician()"
  103       end
  104     end # ha s_and_belo ngs_to_man y :supervi sing,
  105  
  106     has_and_ belongs_to _many :sup ervisors,
  107                               clas s_name:    "User",
  108                               join _table:    :supervisi ng_clinici ans,
  109                               fore ign_key:   :user_id,
  110                               asso ciation_fo reign_key:  :supervis or_id do
  111       def << (u)
  112         # SM ELL: why n ot use and  exception ?
  113         retu rn "Use ad d_supervis ing_clinic ian()"
  114       end
  115  
  116       def de lete(u)
  117         # SM ELL: why n ot use an  exception?
  118         retu rn "Use re move_super vising_cli nician()"
  119       end
  120     end # ha s_and_belo ngs_to_man y :supervi sors,
  121  
  122     # many-t o-many ass ociation b etween Pro vider and  User data  records.
  123     # The "p roviders"  associatio n has no r elation to  the Omnia uth "provi der" field
  124     # that i ndicates w hich ident ity provid er (SAML,  etc.) we u se for aut henticatio n.
  125     has_many  :provider s_users, d ependent:  :destroy
  126     has_many  :provider s, through : :provide rs_users
  127  
  128     before_c reate :set _default_p arameters
  129  
  130     after_sa ve do |use r|
  131       user.c reate_pref erences_if _empty
  132       if use r.is_cpp_u ser?           &&
  133          (0  == user.si gn_in_coun t)  &&   #  TODO: Thi s only app lies to cr eation and  not updat e of NPI
  134          use r.errors.e mpty?          &&
  135          !(u ser.npi.bl ank?)
  136         npi_ array      = user.npi .split(/[^ \d]/).uniq .reject{|e ntry| entr y.empty?}
  137         prov ider_ids   = Provider .where(npi : npi_arra y).pluck(: id)
  138         prov ider_ids.e ach do |pr ovider_id|
  139           #  TODO: Duri ng the rol es refacto r we will  add the ro les of the
  140           #        CPP  user w/r/t  each prov ider to th is table.
  141           be gin
  142              ProvidersU ser.new(us er_id: use r.id, prov ider_id: p rovider_id ).save!
  143           re scue Excep tion => e
  144              logger.err or "Got ex ception wh ile adding  Providers User recor d for user /provider  (#{user.id }/#{provid er_id}) =>  #{e}"
  145           en d
  146         end
  147       end
  148     end
  149  
  150     # TODO:  What about  when the  user recor d is updat ed with ch anged NPI  values?
  151     validate s_with Npi Validator,  on: :crea te, if: :i s_non_vha?
  152  
  153     validate s_presence _of :first _name, :la st_name
  154     validate s :authori zation_sta te, inclus ion: {in:  ["none", " pending",  "rejected" , "authori zed", nil] }
  155     before_c reate :pas sword_comp lexity
  156  
  157     scope :c oordinator s, -> {whe re("roles  like ?", " % vha_cc\n %")}
  158  
  159     scope :b y_last_nam e, -> { or der(last_n ame: :asc,  first_nam e: :asc) }
  160  
  161     # Scopes  that dupl icate func tionality  of User#is _cpp_user?  and User# is_non_vha ?
  162     # but pe rform fast er due to  being run  as queries  instead o f via AR.
  163     scope :c pp_users,  -> { where ("roles li ke ? or ro les like ? ", "% vha_ cc\n%", "%  non_vha\n %") }
  164     scope :c ui_users,  -> { where .not(id: c pp_users)  }
  165  
  166     scope :s ite_ids, - > (user_id ) { find(u ser_id).si tes.pluck( :id) }
  167     ######## ########## ########## ########## ########## ########## ###
  168     ###
  169     ##  All  instance m ethods
  170     #
  171  
  172     ##
  173     #   pass word-relat ed
  174     ##
  175  
  176     def pass word_requi red?
  177       super  && provide r.blank? #  NOTE: pro vider is a  SAML prov ider NOT a ssociated  with the P rovider mo del
  178     end
  179  
  180     def pass word_compl exity
  181       # if p assword.pr esent? and  not passw ord.match( /^(?=.*[a- z])(?=.*[A -Z])(?=.*\ d)./)
  182       #   er rors.add : password,  "must incl ude at lea st one low ercase let ter, one u ppercase l etter, and  one digit "
  183       # end
  184       if pas sword.pres ent? && ha s_minimum_ length? &&  has_upper case_lette rs? && has _digits? & &
  185         has_ special_ch ars? && ha s_downcase _letters?  && has_onl y_permitte d_characte rs?
  186         true
  187       else
  188         erro rs.add :pa ssword, "m ust be at  least 12 c haracters  long, must  include a t least on e lowercas e letter,  " \
  189           "o ne upperca se letter,  one digit  and one s pecial cha racter fro m the " \
  190           "f ollowing:  ~!@#$%^&*"
  191         fals e
  192       end
  193     end
  194  
  195     def upda te_with_pa ssword(par ams, *opti ons)
  196       if enc rypted_pas sword.blan k?
  197         upda te_attribu tes(params , *options )
  198       else
  199         supe r
  200       end
  201     end
  202  
  203  
  204     ##
  205     #   deco rators
  206     ##
  207  
  208     def name
  209       "#{fir st_name} # {last_name }"
  210     end
  211  
  212  
  213     def last _name_firs t_name
  214       "#{las t_name}, # {first_nam e}"
  215     end
  216  
  217  
  218     def huma n_cpp_role name
  219       is_vha _cc? ? 'VH A User' :  'Non VHA P rovider'
  220     end
  221  
  222  
  223     def npi_ list
  224       (provi ders || [] ).pluck(:n pi).join(' , ')
  225     end
  226  
  227  
  228  
  229     ##
  230     #   do s tuff to a  user recor d
  231     ##
  232  
  233  
  234     # Safe w ay to add  new roles  to user (p revents ro les array  from
  235     # gettin g duplicat e or typo  values). S hould alwa ys use thi s method.
  236     # FIXME:  refactori ng of the  roles subs ystem will  remove ri sk of rypo s.
  237  
  238     VALID_MA GIC_USER_R OLES =  %w [ site_use r
  239                                      app_admi n
  240                                      vha_cc
  241                                      non_vha
  242                                    ]
  243  
  244     def add_ role(role)
  245       return  false if  VALID_MAGI C_USER_ROL ES.exclude ?(role)
  246       roles  << role if  roles.exc lude?(role )
  247     end # de f add_role (role)
  248  
  249  
  250     def crea te_prefere nces_if_em pty
  251       create _user_pref erence if  user_prefe rence.blan k?
  252     end
  253  
  254  
  255     # Adds a  clinician  to be sup ervised. A lso ensure s the curr ent user i s added to  that clin ician's su pervisors.
  256     # SMELL:   What is  'c' a reco rd id?  a  name?
  257     def add_ supervised _clinician (c)
  258       # SMEL L: why is  there such  an obsess ion with " self" ??   its not ne cessary.
  259       if sel f.supervis ing.exclud e?(c)
  260         self .supervisi ng.push c
  261         c.su pervisors. push self
  262       end
  263     end
  264  
  265  
  266     # Remove s a clinic ian from t he group t he current  user is s upervising .
  267     # Also e nsure the  current us er is remo ved from t hat clinic ian's supe rvisors.
  268     def remo ve_supervi sed_clinic ian(c)
  269       self.s upervising .destroy(c )
  270       c.supe rvisors.de stroy(self )
  271     end
  272  
  273  
  274     # Add a  clinician  to group o f supervis ors for cu rrent user .
  275     # Also e nsure that  that clin ician is n ow supervi sing the c urrent use r.
  276     def add_ supervisin g_clinicia n(c)
  277       if sel f.supervis ors.exclud e? c
  278         self .superviso rs.push c
  279         c.su pervising. push self
  280       end
  281     end
  282  
  283  
  284     # Remove  a clinici an from th e group of  superviso rs for cur rent user.
  285     # Also e nsure that  current u ser is rem oved from  that clini cian's sup ervised gr oup.
  286     def remo ve_supervi sing_clini cian(c)
  287       self.s upervisors .destroy(c )
  288       c.supe rvising.de stroy(self )
  289     end
  290  
  291  
  292     # Return s 'Ready f or Review'  exams tha t have a c linician w ho is supe rvised by
  293     # the cu rrent user  at the si te of the  exam.
  294     def my_s upervised_ exams (all _ready_for _review_ex ams)
  295       superv ised_exams  = []
  296       all_re ady_for_re view_exams .each do | exam|
  297         clin ician_of_e xam = User .find(exam .clinician )
  298         my_s upervised_ clinicians _at_exam_s ite = self .supervisi ng.include s(:sites)
  299                                                                       .where(: sites => { id: exam.s ite_id})
  300         # We  must chec k that we  supervise  the exam's  clinician  at the ex am site. I f we super vise
  301         # th em at a di fferent si te, the ex am should  *not* be r eturned fo r us to vi ew.
  302  
  303         if m y_supervis ed_clinici ans_at_exa m_site.inc lude? clin ician_of_e xam
  304           su pervised_e xams << ex am
  305         end
  306       end
  307       return  supervise d_exams
  308     end
  309  
  310  
  311     ##
  312     #   Role -based con ditional q ueries
  313     ##
  314  
  315     # builds  all of th e is_<role >? instanc e methods
  316  
  317     ROLE_TES TING_METHO D_NAME_REG EX = /is_( .*)\?/
  318  
  319     def meth od_missing (method_sy m, *argume nts, &bloc k)
  320       method _name = me thod_sym.t o_s
  321       if met hod_name = ~ ROLE_TES TING_METHO D_NAME_REG EX
  322         role  = method_ name.match (ROLE_TEST ING_METHOD _NAME_REGE X)[1]
  323         inst ance_eval  <<~EOM
  324           de f #{method _name}
  325              has_role?( '#{role}')
  326           en d
  327         EOM
  328         send (method_na me)
  329       else
  330         supe r
  331       end
  332     end # de f method_m issing(met hod_name,  *arguments , &block)
  333  
  334  
  335     def is_v ha?
  336       !is_no n_vha?
  337     end
  338  
  339  
  340     def is_c pp_user?
  341       is_non _vha? || i s_vha_cc?
  342     end
  343  
  344     def is_c ui_user?
  345       !is_cp p_user?
  346     end
  347  
  348     #new use r is one w ho has bee n granted  access to  the app, b ut has not  been asso ciated wit h sites/ro les
  349     def is_n ew_user?
  350       is_aut horized? & & site_rol e_sets.non e?
  351     end
  352  
  353  
  354     def has_ role?(role )
  355       self.r oles.inclu de?(role)
  356     end
  357  
  358  
  359     # This i s an OR co nditional  not an AND  condition al
  360     # return s true if  the user h as any of  the specif ied roles
  361     def has_ roles?(rol es)
  362       self.r oles.any?{ |role| rol es.include ?(role) }
  363     end
  364  
  365  
  366     ##
  367     #   attr ibute-base d conditio nal querie s
  368     ##
  369  
  370     def has_ active_ale rts?
  371       self.i s_app_admi n? && Aler t.exists?( :active =>  true)
  372     end
  373  
  374  
  375     def has_ no_sites?
  376       # SMEL L: seems t o me that  if the cou nt is zero  it does n ot matter  whether th e user is  an admin o r not
  377       if sel f.sites.co unt == 0 & & self.is_ admin? ==  false
  378         retu rn true
  379       else
  380         retu rn false
  381       end
  382     end
  383  
  384  
  385     def is_a uthorized?
  386       # SMEL L: "self."  is not ne cessary
  387       #         could b e simplifi ed to just  return('a uthorized'  == author ization_st ate)
  388       if sel f.authoriz ation_stat e && self. authorizat ion_state  == "author ized"
  389         retu rn true
  390       else
  391         retu rn false
  392       end
  393     end
  394  
  395  
  396  
  397     ##
  398     #   site  oriented
  399     ##
  400  
  401  
  402     def is_s ite_admin?  (site)
  403       if sit e
  404         site _roles = s elf.get_si te_roles(s ite)
  405         if s ite_roles. admin == t rue
  406           re turn true
  407         else
  408           re turn false
  409         end
  410       else
  411         retu rn false
  412       end
  413     end
  414  
  415  
  416     def add_ site(site)
  417       self.s ites << si te
  418       self.s ave
  419     end
  420  
  421  
  422     def remo ve_site(si te)
  423       self.s ites.delet e(site)
  424     end
  425  
  426  
  427     # List a ll sites f or "CUI Us ers" displ ay
  428     def list _sites
  429       sites. pluck(:nam e).join "  • "
  430     end
  431  
  432  
  433     # Get th e roles th at this us er has on  a given si te
  434     def get_ site_roles (site)
  435       return  self.site _role_sets .find_by_s ite_id(sit e.id)
  436     end
  437  
  438  
  439     def get_ roles_stri ng(site)
  440       self.g et_site_ro les(site). try(:get_r oles_strin g) || ''
  441     end
  442  
  443  
  444     def has_ this_role_ on_any_sit e?(role)
  445       self.s ites.each  do |s|
  446         role s = self.g et_site_ro les(s).get _roles_str ing
  447         if r oles && ro les.includ e?(" < " +  role + "  > ")
  448           re turn true
  449         end
  450       end
  451       return  false
  452     end
  453  
  454  
  455     ######## ########## ########## ########## ########## ########## ###
  456     ###
  457     ##  All  class meth ods
  458     #
  459  
  460     class <<  self
  461  
  462       def ol d_from_omn iauth(auth )
  463         wher e(provider : auth.pro vider, uid : auth.uid ).first_or _create do  |user|
  464           pu ts "from_o mniauth"
  465           pu ts user
  466           #  NOTE: sett ing Onmiau th identit y provider  here, NOT  community  or VA pro vider
  467           us er.provide r = auth.p rovider
  468           us er.uid = a uth.uid
  469           us er.first_n ame = auth ["info"][" first_name "]
  470           us er.last_na me = auth[ "info"]["l ast_name"]
  471           us er.email =  auth["ext ra"]["raw_ info"].att ributes["a dEmail"]
  472  
  473           #  SMELL: Is  all of thi s debug st uff still  needed?
  474           pu ts "****** ********** ********** ********** *****"
  475           pu ts "from_o mniauth"
  476           pu ts auth
  477  
  478           pu ts "**** a uth.info"
  479           pu ts auth.in fo
  480           pu ts auth["i nfo"]
  481           pu ts auth["i nfo"]["fir st_name"]
  482  
  483           pu ts "**** a uth.creden tials"
  484           pu ts auth.cr edentials
  485           pu ts auth["c redentials "]
  486  
  487           pu ts "**** a uth.extra"
  488           pu ts auth.ex tra
  489           pu ts auth["e xtra"]
  490           pu ts auth["e xtra"]["ra w_info"]
  491           pu ts auth["e xtra"]["ra w_info"].a ttributes[ "adEmail"]
  492  
  493           pu ts "****** ********** ********** ********** *****"
  494         end
  495       end
  496  
  497       def fr om_omniaut h(response _attrs)
  498         emai l = respon se_attrs[' adEmail']. downcase
  499         user _with_emai l = where( email: ema il).first
  500         if u ser_with_e mail.prese nt?
  501           #  DO NOTHING !!!
  502         else
  503           #  Create the  user acco unt
  504           fi rst_name =  response_ attrs['fir stName']
  505           la st_name =  response_a ttrs['last Name']
  506             password =  " AI "
  507           us er_with_em ail = User .create(fi rst_name:  first_name ,
  508                                            la st_name:   last_name,
  509                                            em ail:       email,
  510                                            pa ssword:    password,
  511                                            ro les:       ['site_use r'])
  512         end
  513         retu rn user_wi th_email
  514       end
  515  
  516       def ne w_with_ses sion(param s, session )
  517         if s ession["de vise.user_ attributes "]
  518           ne w(session[ "devise.us er_attribu tes"], wit hout_prote ction: tru e) do |use r|
  519              user.attri butes = pa rams
  520              # SMELL: m ethod invo ked with n o action u pon the re turned val ue
  521              user.valid ?
  522              # SMELL: i s this deb ug stuff s till neede d?
  523              puts "**** ********** ********** ********** *******"
  524              puts "new_ with_sessi on"
  525              puts param s
  526              puts "**** ********** ********** ********** *******"
  527           en d
  528         else
  529           su per
  530         end
  531       end
  532  
  533  
  534       # Temp  Method: S imilar to  User::from _omniauth  but takes  a OneLogin ::RubySaml ::Attribut es
  535       # para meter and  performs a n email-ba sed search  based on  the email  and UUID p arameters  passed in.
  536       # A Us er record  with the s ame email  address mu st already  exist in  the system  in
  537       # orde r to be va lidated, a nd the UUI D field mu st either  match or b e empty if  the user
  538       # logs  in for th e first ti me -- in w hich case  the UUID w ill get se t to the i ncoming va lue.
  539  
  540       def fr om_idme(re sponse_att rs)
  541         user _with_emai l = where( email: res ponse_attr s['email'] ).first
  542         # on  first-tim e login on ly: set Us er#uid fie ld with ID .me UUID f rom respon se.
  543         if u ser_with_e mail.prese nt? && use r_with_ema il.uid.nil ?
  544           us er_with_em ail.uid =  response_a ttrs['uuid ']
  545           us er_with_em ail.save!
  546         end
  547         retu rn user_wi th_email i f (user_wi th_email.u id == resp onse_attrs ['uuid'])
  548       end
  549  
  550  
  551       # pret ty sure we  can't def ine this a s a scope,  due to th e serializ ation of
  552       # role s. Further more, post gres can't  natively  handle YAM L, so we h ave to loa d
  553       # all  users and  filter in  memory, un fortunatel y.
  554  
  555       def ex aminers
  556         # FI XME: self  is User; s o we can j ust start  this line  with "all. "
  557         User .all.order (last_name : :asc, fi rst_name:  :asc).sele ct { |u| ! u.roles.in dex("exami ner").nil?  }
  558       end
  559  
  560       def ge t_triage_u sers_by_si te(site_id )
  561         User .joins(:si te_role_se ts => :sit e)
  562              .where(sit es: {id: s ite_id})
  563              .where(sit e_role_set s: {triage : true})
  564       end
  565  
  566  
  567       def ge t_clinicia ns_by_site (site_id)
  568         User .joins(:si tes)
  569              .where(sit es: {id: s ite_id})
  570              .where(sit e_role_set s: {clinic ian: true} )
  571       end
  572  
  573  
  574       def ge t_all_clin icians
  575         User .joins(:si te_role_se ts => :sit e)
  576              .where(sit e_role_set s: {clinic ian: true} )
  577       end
  578  
  579       def to _csv
  580         str  = 'last_na me first_n ame email  last_sign_ in_at last _sign_in_i p' \
  581                ' roles  created_at  updated_a t is_under _review pr ovider'
  582         attr ibutes = s tr.split('  ')
  583  
  584         CSV. generate(h eaders: tr ue) do |cs v|
  585           cs v << attri butes
  586  
  587           al l.each do  |user|
  588              csv << att ributes.ma p{ |attr|  user.send( attr) }
  589           en d
  590         end
  591       end
  592     end # cl ass << sel f
  593  
  594     ######## ########## ########## ########## ########## ########## ###
  595     ###
  596     ##  All  private me thods
  597     #
  598  
  599     private
  600  
  601   # FIXME: d ead code n eeds to be  removed.
  602  
  603   #  def set _default_p arameters
  604   #    if EN V.has_key?  "CUI_DISA BLE_UNDER_ REVIEW"
  605   #      sel f.roles =  ["medical_ assistant" , "examine r"]
  606   #      sel f.is_under _review =  false
  607   #    end
  608   #
  609   #    # nee d this so  that we do n't return  false
  610   #    nil
  611   #  end
  612   # UC_LETTE RS=/[A-Z]/
  613   # LC_LETTE RS=/[a-z]/
  614   # DIGITS=/ \d/
  615   # SPECIAL_ CHARS=/[\$ \^\*~!@#%& ]/
  616   # ALPHA_NU MERICS=/[0 -9A-Za-z,. ]/
  617  
  618  
  619     def set_ default_pa rameters
  620       self.a dd_role("s ite_user")
  621  
  622       # SMEL L: nil is  conditiona lly the sa me as fals e.
  623       # need  this so t hat we don 't return  false
  624       nil
  625     end
  626  
  627     def has_ uppercase_ letters?
  628       passwo rd.match(U C_LETTERS)  ? true :  false
  629     end
  630  
  631     def has_ digits?
  632       passwo rd.match(D IGITS) ? t rue : fals e
  633       end
  634  
  635     def has_ special_ch ars?
  636       passwo rd.match(S PECIAL_CHA RS) ? true  : false
  637     end
  638  
  639     def has_ downcase_l etters?
  640       passwo rd.match(L C_LETTERS)  ? true :  false
  641     end
  642  
  643     def has_ only_permi tted_chara cters?
  644       workin g_str = pa ssword.dup
  645  
  646       specia l_chars =  working_st r.scan(SPE CIAL_CHARS )
  647       specia l_chars.ea ch do |x|
  648         work ing_str.gs ub!("#{x}" , '')
  649       end
  650  
  651       workin g_str.gsub !(ALPHA_NU MERICS, '' )
  652  
  653       workin g_str.leng th == 0
  654     end
  655  
  656     def has_ minimum_le ngth?
  657       passwo rd.length  >= MINIMUM _PASSWORD_ LENGTH ? t rue : fals e
  658     end
  659   end