123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436 |
- require 'digest/sha2'
- class User < ApplicationModel
- include Gmaps
- before_create :check_name, :check_email, :check_login, :check_image, :check_geo, :check_password
- before_update :check_password, :check_image, :check_geo, :check_email, :check_login
- has_and_belongs_to_many :groups, :after_add => :cache_update, :after_remove => :cache_update
- has_and_belongs_to_many :roles, :after_add => :cache_update, :after_remove => :cache_update
- has_and_belongs_to_many :organizations, :after_add => :cache_update, :after_remove => :cache_update
- has_many :tokens, :after_add => :cache_update, :after_remove => :cache_update
- has_many :authorizations, :after_add => :cache_update, :after_remove => :cache_update
- belongs_to :organization, :class_name => 'Organization'
- store :preferences
- def fullname
- fullname = ''
- if self.firstname
- fullname = fullname + self.firstname
- end
- if self.lastname
- if fullname != ''
- fullname = fullname + ' '
- end
- fullname = fullname + self.lastname
- end
- return fullname
- end
- def is_role( role_name )
- self.roles.each { |role|
- return role if role.name == role_name
- }
- return false
- end
- def self.authenticate( username, password )
- # do not authenticate with nothing
- return if !username || username == ''
- return if !password || password == ''
- # try to find user based on login
- user = User.where( :login => username, :active => true ).first
- # try second lookup with email
- if !user
- user = User.where( :email => username, :active => true ).first
- end
- # no user found
- return nil if !user
- # use auth backends
- config = {
- :internal => {
- :adapter => 'internal',
- },
- :test => {
- :adapter => 'test',
- },
- :env => {
- :adapter => 'env',
- },
- :ldap => {
- :adapter => 'ldap',
- :host => 'somehost',
- :port => '3333',
- :base_dn => 'some base dn',
- :bind_user => 'some bind user',
- :bind_pw => 'some pw',
- },
- :otrs => {
- :adapter => 'otrs',
- :required_group => 'stats',
- :group_role_map => {
- 'admin' => 'Admin',
- 'stats' => 'Report',
- },
- :always_role => {
- 'Agent' => true,
- },
- },
- }
- config.each {|key, c|
- file = "auth/#{c[:adapter]}"
- require file
- user_auth = Auth.const_get("#{c[:adapter].to_s.upcase}").check( user, username, password, c )
- return user_auth if user_auth
- }
- # auth failed
- return false
- end
- def self.create_from_hash!(hash)
- url = ''
- if hash['info']['urls'] then
- url = hash['info']['urls']['Website'] || hash['info']['urls']['Twitter'] || ''
- end
- roles = Role.where( :name => 'Customer' )
- self.create(
- :login => hash['info']['nickname'] || hash['uid'],
- :firstname => hash['info']['name'],
- :email => hash['info']['email'],
- :image => hash['info']['image'],
- # :url => url.to_s,
- :note => hash['info']['description'],
- :source => hash['provider'],
- :roles => roles,
- :created_by_id => 1
- )
- end
- def self.password_reset_send(username)
- return if !username || username == ''
- # try to find user based on login
- user = User.where( :login => username, :active => true ).first
- # try second lookup with email
- if !user
- user = User.where( :email => username, :active => true ).first
- end
- # check if email address exists
- return if !user
- return if !user.email
- # generate token
- token = Token.create( :action => 'PasswordReset', :user_id => user.id )
- # send mail
- data = {}
- data[:subject] = 'Reset your #{config.product_name} password'
- data[:body] = 'Forgot your password?
- We received a request to reset the password for your #{config.product_name} account (#{user.login}).
- If you want to reset your password, click on the link below (or copy and paste the URL into your browser):
- #{config.http_type}://#{config.fqdn}/#password_reset_verify/#{token.name}
- This link takes you to a page where you can change your password.
- If you don\'t want to reset your password, please ignore this message. Your password will not be reset.
- Your #{config.product_name} Team
- '
- # prepare subject & body
- [:subject, :body].each { |key|
- data[key.to_sym] = NotificationFactory.build(
- :locale => user.locale,
- :string => data[key.to_sym],
- :objects => {
- :token => token,
- :user => user,
- }
- )
- }
- # send notification
- NotificationFactory.send(
- :recipient => user,
- :subject => data[:subject],
- :body => data[:body]
- )
- return true
- end
- # check token
- def self.password_reset_check(token)
- user = Token.check( :action => 'PasswordReset', :name => token )
- return user
- end
- def self.password_reset_via_token(token,password)
- # check token
- user = Token.check( :action => 'PasswordReset', :name => token )
- return if !user
- # reset password
- user.update_attributes( :password => password )
- # delete token
- Token.where( :action => 'PasswordReset', :name => token ).first.destroy
- return user
- end
- def self.find_fulldata(user_id)
- cache = self.cache_get(user_id, true)
- return cache if cache
- # get user
- user = User.find(user_id)
- data = user.attributes
- # do not show password
- user['password'] = ''
- # get linked accounts
- data['accounts'] = {}
- authorizations = user.authorizations() || []
- authorizations.each do | authorization |
- data['accounts'][authorization.provider] = {
- :uid => authorization[:uid],
- :username => authorization[:username]
- }
- end
- # set roles
- roles = []
- user.roles.select('id, name').where( :active => true ).each { |role|
- roles.push role.attributes
- }
- data['roles'] = roles
- data['role_ids'] = user.role_ids
- groups = []
- user.groups.select('id, name').where( :active => true ).each { |group|
- groups.push group.attributes
- }
- data['groups'] = groups
- data['group_ids'] = user.group_ids
- organization = user.organization
- if organization
- data['organization'] = organization.attributes
- end
- organizations = []
- user.organizations.select('id, name').where( :active => true ).each { |organization|
- organizations.push organization.attributes
- }
- data['organizations'] = organizations
- data['organization_ids'] = user.organization_ids
- self.cache_set(user.id, data, true)
- return data
- end
-
- def self.user_data_full (user_id)
- # get user
- user = User.find_fulldata(user_id)
- # do not show password
- user['password'] = ''
- # TEMP: compat. reasons
- user['preferences'] = {} if user['preferences'] == nil
- items = []
- if user['preferences'][:tickets_open].to_i > 0
- item = {
- :url => '',
- :name => 'open',
- :count => user['preferences'][:tickets_open] || 0,
- :title => 'Open Tickets',
- :class => 'user-tickets',
- :data => 'open'
- }
- items.push item
- end
- if user['preferences'][:tickets_closed].to_i > 0
- item = {
- :url => '',
- :name => 'closed',
- :count => user['preferences'][:tickets_closed] || 0,
- :title => 'Closed Tickets',
- :class => 'user-tickets',
- :data => 'closed'
- }
- items.push item
- end
- # show linked topics and items
- if items.count > 0
- topic = {
- :title => 'Tickets',
- :items => items,
- }
- user['links'] = []
- user['links'].push topic
- end
- return user
- end
- # update all users geo data
- def self.geo_update_all
- User.all.each { |user|
- user.geo_update
- user.save
- }
- end
- # update geo data of one user
- def geo_update
- address = ''
- location = ['street', 'zip', 'city', 'country']
- location.each { |item|
- if self[item] && self[item] != ''
- address = address + ',' + self[item]
- end
- }
- # return if no address is given
- return if address == ''
- # dp lookup
- latlng = Gmaps.geocode(address)
- if latlng
- self.preferences['lat'] = latlng[0]
- self.preferences['lng'] = latlng[1]
- end
- end
- def update_last_login
- self.last_login = Time.now
- self.save
- end
- private
- def check_geo
- # geo update if no user exists
- if !self.id
- self.geo_update
- return
- end
- location = ['street', 'zip', 'city', 'country']
- # get current user data
- current = User.where( :id => self.id ).first
- return if !current
- # check if geo update is needed
- current_location = {}
- location.each { |item|
- current_location[item] = current[item]
- }
- # get full address
- next_location = {}
- location.each { |item|
- next_location[item] = self[item]
- }
- # return if address hasn't changed and geo data is already available
- return if ( current_location == next_location ) && ( self.preferences['lat'] && self.preferences['lng'] )
- # geo update
- self.geo_update
- end
- def check_name
- if ( self.firstname && !self.firstname.empty? ) && ( !self.lastname || self.lastname.empty? )
- # Lastname, Firstname
- scan = self.firstname.scan(/, /)
- if scan[0]
- name = self.firstname.split(', ', 2)
- self.lastname = name[0]
- self.firstname = name[1]
- return
- end
- # Firstname Lastname
- name = self.firstname.split(' ', 2)
- self.firstname = name[0]
- self.lastname = name[1]
- return
- # -no name- firstname.lastname@example.com
- elsif ( !self.firstname || self.firstname.empty? ) && ( !self.lastname || self.lastname.empty? ) && ( self.email && !self.email.empty? )
- scan = self.email.scan(/^(.+?)\.(.+?)\@.+?$/)
- if scan[0]
- self.firstname = scan[0][0].capitalize
- self.lastname = scan[0][1].capitalize
- end
- end
- end
- def check_email
- if self.email
- self.email = self.email.downcase
- end
- end
- def check_login
- if self.login
- self.login = self.login.downcase
- end
- end
- def check_image
- require 'digest/md5'
- if !self.image || self.image == ''
- if self.email
- hash = Digest::MD5.hexdigest(self.email)
- self.image = "http://www.gravatar.com/avatar/#{hash}?s=48"
- end
- end
- end
- def check_password
- # set old password again if not given
- if self.password == '' || !self.password
- # get current record
- if self.id
- current = User.find(self.id)
- self.password = current.password
- end
- # create crypted password if not already crypted
- else
- if self.password !~ /^\{sha2\}/
- crypted = Digest::SHA2.hexdigest( self.password )
- self.password = "{sha2}#{crypted}"
- end
- end
- end
- end
|