Merge branch 'master' of git+ssh://repo.or.cz/srv/git/mwamko
[mwamko.git] / app / controllers / login_controller.rb
blobf86ef4e9cc85a0817ef514a5b4e36723604b7690
1 require 'password_gen'
3 class LoginController < ApplicationController
4   before_filter :authorize, :except => [:login,
5                                         :logout,
6                                         :create_student_account,
7                                         :new_account_confirmation,
8                                         :forgot_passwd,
9                                         :find_user,
10                                         :token,
11                                         :invalid_token,
12                                         :unknown_user,
13                                         :invalid_email]
15   # For these functions should not be accessiblase
16   #
17   before_filter :disable, :only => [:add_user, :delete_user]
19   layout 'application', :except => 'login'
21   def create_student_account
23     def is_allowed?(user_email)
25       user_email =~ /^.+@(.+)$/
26       user_host = $1
28       File.open(ALLOWED_EMAILS_FILE).each do |raw_line|
29         line = raw_line.strip
30         return true if user_email == line
32         # Support for * matching
33         if line =~ /^\*@(.+)/
34           return true if user_host == $1
35         end
37       end
39       return false
40     end
42     raise "Invalid Request. Expecting a specific POST" unless
43       params.include?(:user) and request.post?
45     return show_error("Please Enter an Email") if params[:user][:email] == ''
47     # SECURITY: Input Check
48     unless params[:user][:email] =~ SAFE_EMAIL
49       return show_error("Please Enter a Valid Email")
50     else
51       # De-coupled from the details of the SAFE_EMAIL regular expression
52       if params[:user][:email] =~ /^([^@]+)@(.+)$/
53         username = $1
54         hostname = $2
55         email = "#{$1}@#{$2}"
56       else
57         raise "Could not split the email into the 2 parts."
58       end
59     end
62     return show_error("Your Email is Not Authorized") unless is_allowed?(email)
64     new_password = PasswordGen.generate_pronounceable
67     new_user = User.new(:name => email,
68                         :password => new_password,
69                         :password_confirmation => new_password)
71     unless new_user.save
72       flash[:notices] ||= []
73       new_user.errors.full_messages.each do |msg|
74         flash[:notices] << msg
75       end
77       return redirect_back
78     end
80     # Send Out Email
81     NewStudent.deliver_login_info(email, username, new_password)
83     redirect_to :action => 'new_account_confirmation'
85   end
87   def add_user
88     @user = User.new(params[:user])
89     if request.post? and @user.save
90       flash[:notices] ||= []
91       flash[:notices] << "User #{@user.name} created"
92       @user = User.new
93     end
94   end
96   def delete_user
97     id = params[:id]
98     if id && user = User.find(id)
99       flash[:notices] ||= []
100       begin
101         user.safe_delete
102         flash[:notices] << "User #{user.name} deleted"
103       rescue Exception => e
104         flash[:notices] << e.message
105      end
106     end
107     redirect_to(:action => :list_users)
108   end
110   def list_users
111     @all_users = User.find(:all)
112   end
114   def login
115     session[:user_id] = nil
116     if !request.post?
117       raise "Expecting a POST request"
118     end
122     user = User.authenticate(params[:name], params[:password])
125     if user
126       session[:user_id] = user.id
128       if session[:mwamko_mode] == ['normal', 'gadget'][1]
129         redirect_to(:controller => 'gadget')
130       elsif User.find_by_id(session[:user_id]).is_admin
131         redirect_to(:controller => 'admin')
132       else
133         redirect_to(:controller => "cytoskeleton")
134       end
136     else
138       redirect_to(:controller => 'homepage')
139       flash[:notices] ||= []
140       flash[:notices] << "Invalid email/password combination."
142       return 0
143     end
145   end
147   def logout
148     unless session[:workers].nil? or session[:workers].empty?
149       add_error("Please wait. Some things are still in progress...")
150       if session[:mwamko_mode] == ['normal', 'gadget'][1]:
151         redirect_to :controller => 'gadget', :action => 'areas'
152       else
153         redirect_to :controller => 'cytoskeleton', :action => 'areas'
154       end
155       return false
156     end
158     unless session[:user_id].nil?
159       #remember the session mode before resetting, then set it back after.
160       temp_sessionmode = session[:mwamko_mode]
161       reset_session
162       session[:mwamko_mode] = temp_sessionmode
163       redirect_to
164       return false
165     end
167     add_error "Logged out"
168     if session[:mwamko_mode] == ['normal', 'gadget'][1]:
169       redirect_to :controller => 'gadget'
170     else
171       return redirect_home
172     end
173   end
175   def find_user
176     user = params['user']
177     email = user['email']
178     #get user name from the email address
179     regexp = /@/
180     ar = []
181     error = "@ was not in the email address"
182     email = email.to_s
183     if(email =~ regexp)
184       ar = email.split("@")
185       user_name = ar[0]
186       @found = User.exists?(:name => "#{user_name}")
187       if(@found == true)
188         # generate a random string containing letters and number
189         email_token = PasswordGen.generate_pronounceable(16)
190         # insert token into database
191         record = User.find_by_name("#{user_name}")
193         record.email_token = email_token
194         record.save!
196         #send email
197         NewStudent.deliver_reset_password(email, user_name, email_token)
198       else
199         redirect_to(:controller => 'login',
200                     :action => 'unknown_user',
201                     :email => email)
202       end
203     else
204       redirect_to(:controller => 'login',
205                   :action => 'invalid_email',
206                   :email => email)
207     end
208   end
210   def token
211     token = params[:id]
212     #make sure token is valid
213     record = User.find_by_email_token(token)
214     if(record.nil?)
215       #appropiate error message and redirection
216       redirect_to(:action => 'invalid_token')
217     else
218       #generate new password and email it
219       email = record.name + "@cs.ucr.edu"
220       new_password = PasswordGen.generate_pronounceable
221       record.password_confirmation = new_password
222       record.password = new_password
223       record.email_token = nil
224       record.save!
225       NewStudent.deliver_new_password(email, record.name,new_password)
226     end
227   end
229   def change_password
230     password_1 = params[:password_1]
231     password_2 = params[:password_2]
234     # simple checks to see if the passwords the user provided match and
235     # that they are not blank
236     if(password_1.empty? and password_2.empty?)
237       redirect_to({:action => 'blank_fields'})
238     elsif(password_1 == password_2)
240       def password_1.is_safe?
241         # Alphanumeric or !@#$%^&*()_+-= or comma or dot or space
242         self =~ SAFE_PASSWORD
243       end
245       if !password_1.is_safe?
246         redirect_to :action => 'unsafe_password'
247       else
249         def password_1.is_strong?
250           PASSWORD_IS_STRONG(self)
251         end
253         if !password_1.is_strong?
254           redirect_to :action => 'weak_password'
255         else
256           record =  User.find(session[:user_id])
257           record.password_confirmation = password_1
258           record.password = password_1
259           record.save!
260           redirect_to({:action => 'success'})
261         end
263       end
265     elsif(password_1 != password_2)
266       redirect_to({:action => 'no_match'})
267     end
268   end
271   private
273   def redirect_home(keywords={})
275     redirect_to({:controller => 'homepage',
276                   :action => 'about'}.merge(keywords))
277     return false
278   end
280   def redirect_back(keywords={})
281     redirect_to(:back, keywords) rescue redirect_home
282     return false
283   end
285   def add_error(msg)
286     flash[:notices] ||= []
287     flash[:notices] << msg
288   end
290   def show_error(msg)
291     add_error(msg)
292     return redirect_home()
293   end