Class | User
In: | app/models/user.rb
Parent: | ActiveRecord::Base

More information:

- EPF Wiki Data model

Copyright (c) 2006 Logica

### Methods

admin? after_create before_save before_validation_on_update cadmin cadmin? change_password confirm_account documents_path find_central_admin generate_new_pw images_path login login_basicauthentication login_bugzilla login_validemail new_cadmin new_signup set_new_pw sites token token_new try_to_login user? validate validate_on_create validate_on_update

### Constants

DOMAIN_PATTERN | = | /@.*/

### Attributes

email_extension | [RW] |
password | [RW] |
remember_me | [RW] |
user | [RW] | Changing account to admin or cadmin requires that you specify the user that is requesting the change

### Public Class methods

cadmin(from, to)

[Source]

         # File app/models/user.rb, line 242
    242:     def self.cadmin(from, to)
    243:       raise 'From needs to be central admin' if !from.cadmin?
    244:       User.transaction do
    245:         to.admin = 'C'
    246:         to.user = from
    247:         from.admin = 'Y'
    248:         to.save
    249:         from.save
    250:       end
    251:     end

find_central_admin()

[Source]

         # File app/models/user.rb, line 275
    275:     def self.find_central_admin
    276:         return  User.find(:first, :conditions => ["admin=?", "C"] )
    277:     end

login(email, password)

login searches the user on email and hashed_password and returns it, see also try_to_login

[Source]

        # File app/models/user.rb, line 81
    81:     def self.login(email, password)
    82:       user = nil
    83:       ENV['EPFWIKI_AUTH_METHODS'].split(',').each do |method|
    84:         logger.info("Doing login of #{email} using method #{method}")
    85:         if method == 'bugzilla' #&& user.nil?
    86:           user = User.login_bugzilla(email, password)
    87:         elsif method == 'validemail' #&& user.nil?
    88:           user = User.login_validemail(email, password)
    89:         elsif method == 'basic' #&& user.nil?
    90:           user = User.login_basicauthentication(email, password)
    91:         end
    92:         break if !user.nil?
    93:       end
    94:       return user
    95:     end

login_basicauthentication(account, password)

[Source]

         # File app/models/user.rb, line 149
    149:     def self.login_basicauthentication(account, password)
    150:       logger.info("Checking un/pw using basic authentication")
    151:       user = nil
    152:       hostname, fail_code, maildomain = ENV['EPFWIKI_AUTH_BASIC'].split(',')
    153:       logger.debug("BASIC AUTH Settings: #{hostname},#{fail_code},#{maildomain}")
    154:       Net::HTTP.start(hostname) {|http|
    155:         req = Net::HTTP::Get.new('/')
    156:         req.basic_auth account, password
    157:         response = http.request(req)
    158:         logger.debug("response.code: #{response.code.inspect}, fail_code #{fail_code.inspect}")
    159:         if response.code == fail_code
    160:           logger.debug("Unauthorized #{account}/#{password}: #{response.inspect}")
    161:           return nil
    162:         else
    163:           logger.debug("Authorized #{account}/#{password}: #{response.inspect}")
    164:           user = User.find_by_account(account)
    165:           if user
    166:             logger.info("User #{account} has account")
    167:           else
    168:             logger.info("Creating account #{account}")
    169:             user = User.new(:account => account, :email => "#{account}@#{maildomain}", :name => account)
    170:             user.set_new_pw
    171:             user.password_confirmation = user.password
    172:             user.hashed_password = hash_pw(user.password) if user.password
    173:             if user.save
    174:               logger.info("Succesfully created account: #{user.inspect}")
    175:             else
    176:               logger.info("Failed to create account #{user.errors.full_messages.join(", ")}")
    177:               Notifier::deliver_email(User.find_central_admin,
    178:               "[#{ENV['EPFWIKI_APP_NAME']}] Error creating account using basic authentication!",[],
    179:               "#{user.errors.full_messages.join(", ")}")
    180:               user = nil
    181:             end
    182:             #return User.create() if user.nil
    183:           end
    184:         end
    185:       }
    186:       return user
    187:     end

login_bugzilla(email, password)

[Source]

         # File app/models/user.rb, line 97
     97:     def self.login_bugzilla(email, password)
     98:       user = nil
     99:       host, port = ENV['EPFWIKI_AUTH_BUGZILLA'].split(',')
    100:       logger.debug("Login using bugzilla with settings: #{host} with port #{port}")
    101:       http = Net::HTTP.new(host, port)
    102:
    103:       # avoid console message "peer certificate won't be verified in this SSL session"
    104:       http.verify_mode = OpenSSL::SSL::VERIFY_NONE
    105:
    106:       http.use_ssl = true
    107:       path = '/bugs/index.cgi'
    108:
    109:       # POST request -> logging in
    110:       data = "Bugzilla_login=#{email}&Bugzilla_password=#{password}&GoAheadAndLogIn=1"
    111:       logger.debug('data = ' + data)
    112:       headers = {
    113:       'Referer' => "https://#{host}/bugs/index.cgi?GoAheadAndLogIn=",
    114:       'Content-Type' => 'application/x-www-form-urlencoded'
    115:       }
    116:
    117:       resp, data = http.post(path, data, headers)
    118:       logger.info('Code = ' + resp.code)
    119:       logger.info('Message = ' + resp.message)
    120:       resp.each {|key, val| logger.info(key + ' = ' + val)}
    121:
    122:       if resp['set-cookie'].nil?
    123:         logger.info("Unauthorized (didn't get a cookie)")
    124:       else
    125:           logger.debug("Authorized #{email}/#{password}")
    126:           user = User.find_by_email(email)
    127:           if user
    128:             logger.info("User #{email} has account")
    129:           else
    130:             logger.info("Creating account #{email}")
    131:             user = User.new(:email => email, :name => email.split('@')[0])
    132:             user.set_new_pw
    133:             user.password_confirmation = user.password
    134:             user.hashed_password = hash_pw(user.password) if user.password
    135:             if user.save
    136:               logger.info("Succesfully created account: #{user.inspect}")
    137:             else
    138:               logger.info("Failed to create account #{user.errors.full_messages.join(", ")}")
    139:               Notifier::deliver_email(User.find_central_admin,
    140:               "[#{ENV['EPFWIKI_APP_NAME']}] Error creating account using bugzilla!",[],
    141:               "#{user.errors.full_messages.join(", ")}")
    142:               user = nil
    143:             end
    144:           end
    145:         end
    146:       return user
    147:     end

login_validemail(email, password)

[Source]

         # File app/models/user.rb, line 189
    189:     def self.login_validemail(email, password)
    190:       logger.info("Checking un/pw of valid email #{email} hash_pw is #{hash_pw(password)}")
    191:         hashed_password = hash_pw(password)
    192:         user = find(:first,  :conditions => ["email = ? and hashed_password = ?", email.downcase, hashed_password])
    193:         return nil if user && (password.nil? ||  user.confirmed_on.nil?)
    194:         return user
    195:     end

new_cadmin(params)

new_cadmin creates the central adminstrator user

[Source]

        # File app/models/user.rb, line 55
    55:     def self.new_cadmin(params)
    56:       raise 'Already create central admin' if User.count > 0
    57:       u= User.new(params)
    58:       u.hashed_password = hash_pw(u.password) if u.password
    59:       u.admin = "C"
    60:       u.confirmed_on = Time.now
    61:       return u
    62:     end

new_signup(params)

new_signup creates an ordinary user account

[Source]

        # File app/models/user.rb, line 65
    65:     def self.new_signup(params)
    66:       user = User.new(params)
    67:       user.email = user.email + user.email_extension if ENV['EPFWIKI_DOMAINS'] && user.email_extension
    68:       if  ENV['EPFWIKI_GENERATE_PASSWORDS'] == '1'
    69:         logger.info("Creating account with generated password for #{user.email}")
    70:         user.password = user.generate_new_pw
    71:         user.password_confirmation = user.password
    72:         user.confirmed_on = Time.now # account does not need to be confirmed
    73:       else
    74:         logger.info("Creating account with supplied password for #{user.email}")
    75:       end
    76:       user.hashed_password = hash_pw(user.password) if user.password
    77:       return user
    78:     end

### Public Instance methods

admin?()

[Source]

         # File app/models/user.rb, line 267
    267:     def admin?
    268:         return admin == 'Y' || admin == 'C'
    269:     end

after_create()

[Source]

         # File app/models/user.rb, line 330
    330:     def after_create
    331:       create_templates if User.count == 1
    332:     end

before_save()

[Source]

         # File app/models/user.rb, line 334
    334:     def before_save
    335:       self.email = self.email.downcase
    336:     end

before_validation_on_update()

[Source]

         # File app/models/user.rb, line 292
    292:     def before_validation_on_update
    293:     end

cadmin?()

[Source]

         # File app/models/user.rb, line 271
    271:     def cadmin?
    272:         return admin  == 'C'
    273:     end

change_password(user)

change_password changes the password of a User

[Source]

         # File app/models/user.rb, line 234
    234:     def change_password(user)
    235:       raise "Password can't be blank" if user.password.blank?
    236:       self.password = user.password
    237:       self.password_confirmation = user.password_confirmation
    238:       self.hashed_password = hash_pw(user.password)
    239:       self.confirmed_on = Time.now
    240:     end

confirm_account(token)

confirm_account is used to confirm new accounts or confirm new passwords in case user requested on

[Source]

         # File app/models/user.rb, line 198
    198:     def confirm_account(token)
    199:       logger.debug("Confirming account with token: " + token)
    200:       logger.debug("Hashed password is: " + self.hashed_password)
    201:       logger.debug("Hashed password new is: " + (self.hashed_password_new || ''))
    202:       if  self.hashed_password && (hash_pw(self.hashed_password) == token)
    203:           logger.debug('Confirming new account:' + self.inspect)
    204:           self.confirmed_on = Time.now
    205:           return true
    206:       elsif self.hashed_password_new && (hash_pw(self.hashed_password_new) == token)
    207:           logger.debug('Confirming a lost password:' + self.inspect)
    208:           self.confirmed_on = Time.now
    209:           self.hashed_password = self.hashed_password_new
    210:           self.hashed_password_new = nil
    211:           return true
    212:       else
    213:         return false
    214:       end
    215:     end

documents_path()

[Source]

         # File app/models/user.rb, line 279
    279:     def documents_path
    280:         return "users/" + id.to_s + "/docs"
    281:     end

generate_new_pw()

[Source]

         # File app/models/user.rb, line 338
    338:     def generate_new_pw
    339:     chars = ["A".."Z","a".."z","0".."9"].collect { |r| r.to_a }.join + %q(!@$%^&*)
    340:     (1..8).collect { chars[rand(chars.size)] }.pack("C*")
    341:     end

images_path()

[Source]

         # File app/models/user.rb, line 283
    283:     def images_path
    284:         return  "users/" + id.to_s + "/images"
    285:     end

set_new_pw()

Use set_new_pw to set and return a new password for a user. Needs to be confirmed using confirm_account

[Source]

         # File app/models/user.rb, line 219
    219:     def set_new_pw
    220:         new_pw = generate_new_pw
    221:         self.password = new_pw
    222:         self.hashed_password_new = hash_pw(new_pw)
    223:         logger.debug("This is the new password #{new_pw}")
    224:     end

sites()

sites returns Site records where user created versions or comments

[Source]

         # File app/models/user.rb, line 288
    288:     def sites
    289:         return Site.find(:all, :conditions => ['exists (select * from versions where user_id = ? and wiki_id = sites.id) or exists (select * from da_texts where user_id = ? and site_id = sites.id)', id, id])
    290:     end

token()

Token that can be used to confirm a new account

[Source]

         # File app/models/user.rb, line 254
    254:     def token
    255:       return hash_pw(self.hashed_password)
    256:     end

token_new()

Token that can be used to confirm a lost password (existing account)

[Source]

         # File app/models/user.rb, line 259
    259:     def token_new
    260:       return hash_pw(self.hashed_password_new)
    261:     end

try_to_login()

Log in if the name and password (after hashing) match the database, or if the name matches an entry in the database with no password

[Source]

         # File app/models/user.rb, line 229
    229:     def try_to_login
    230:         User.login(self.email.downcase, self.password)
    231:     end

user?()

[Source]

         # File app/models/user.rb, line 263
    263:     def user?
    264:       return admin == 'N'
    265:     end

validate()

[Source]

         # File app/models/user.rb, line 295
    295:     def validate
    296:       if  ENV['EPFWIKI_DOMAINS']
    297:         valid_domain = !ENV['EPFWIKI_DOMAINS'].split(" ").index(DOMAIN_PATTERN.match(email.downcase).to_s).nil?
    298:         errors.add(:email, "domain not valid") if !valid_domain && !self.cadmin?
    299:       end
    300:     end

validate_on_create()

[Source]

         # File app/models/user.rb, line 302
    302:     def validate_on_create
    303:       if ENV['EPFWIKI_GENERATE_PASSWORDS'] == '1'
    304:       else
    305:         errors.add(:password, "can't be blank") if password.blank? || hashed_password.blank?
    306:         errors.add(:password_confirmation, "can't be blank") if password_confirmation.blank?
    307:       end
    308:       errors.add("Central admin already exists") if User.count > 0 && admin == 'C'
    309:
    310:       # all users have to agree to the terms of use (except the first user)
    311:       # errors.add_to_base("You have to agree to the terms of use") if i_agree_to_the_terms_of_use != "1" && User.count != 0
    312:     end

validate_on_update()

[Source]

         # File app/models/user.rb, line 314
    314:     def validate_on_update
    315:       errors.add(:hashed_password, "can't be blank") if hashed_password.blank?
    316:       old_admin = User.find(id).admin
    317:       if admin == 'C' and old_admin != 'C'
    318:         if user.nil? || User.find(user.id).admin != 'C'
    319:           errors.add(:admin, 'can only be set to C by the central admin')
    320:         end
    321:       end
    322:       if admin == 'Y' and old_admin == 'N'
    323:         errors.add(:admin, 'can only be set by an admin') if user.nil? || user.admin == 'N'
    324:       end
    325:       if admin == 'N' and !old_admin.index(/Y|C/).nil?
    326:         errors.add(:admin, 'can only be revoked by the central admin') if user.nil? || user.admin != 'C'
    327:       end
    328:     end

[Validate]