summaryrefslogtreecommitdiffstats
path: root/app/controllers/account_controller.rb
blob: a1cbf5ffd9cd79b2a9e6f0565864fb686fab6f27 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# redMine - project management software
# Copyright (C) 2006-2007  Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

class AccountController < ApplicationController
  layout 'base'	
  helper :custom_fields
  include CustomFieldsHelper   
  
  # prevents login action to be filtered by check_if_login_required application scope filter
  skip_before_filter :check_if_login_required, :only => [:login, :lost_password, :register, :activate]

  # Show user's account
  def show
    @user = User.find_active(params[:id])
    @custom_values = @user.custom_values.find(:all, :include => :custom_field)
    
    # show only public projects and private projects that the logged in user is also a member of
    @memberships = @user.memberships.select do |membership|
      membership.project.is_public? || (User.current.role_for_project(membership.project))
    end
  rescue ActiveRecord::RecordNotFound
    render_404
  end

  # Login request and validation
  def login
    if request.get?
      # Logout user
      self.logged_user = nil
    else
      # Authenticate user
      user = User.try_to_login(params[:login], params[:password])
      if user
        self.logged_user = user
        # generate a key and set cookie if autologin
        if params[:autologin] && Setting.autologin?
          token = Token.create(:user => user, :action => 'autologin')
          cookies[:autologin] = { :value => token.value, :expires => 1.year.from_now }
        end
        redirect_back_or_default :controller => 'my', :action => 'page'
      else
        flash.now[:error] = l(:notice_account_invalid_creditentials)
      end
    end
  end

  # Log out current user and redirect to welcome page
  def logout
    cookies.delete :autologin
    Token.delete_all(["user_id = ? AND action = ?", User.current.id, 'autologin']) if User.current.logged?
    self.logged_user = nil
    redirect_to home_url
  end
  
  # Enable user to choose a new password
  def lost_password
    redirect_to(home_url) && return unless Setting.lost_password?
    if params[:token]
      @token = Token.find_by_action_and_value("recovery", params[:token])
      redirect_to(home_url) && return unless @token and !@token.expired?
      @user = @token.user
      if request.post?
        @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
        if @user.save
          @token.destroy
          flash[:notice] = l(:notice_account_password_updated)
          redirect_to :action => 'login'
          return
        end 
      end
      render :template => "account/password_recovery"
      return
    else
      if request.post?
        user = User.find_by_mail(params[:mail])
        # user not found in db
        flash.now[:error] = l(:notice_account_unknown_email) and return unless user
        # user uses an external authentification
        flash.now[:error] = l(:notice_can_t_change_password) and return if user.auth_source_id
        # create a new token for password recovery
        token = Token.new(:user => user, :action => "recovery")
        if token.save
          Mailer.deliver_lost_password(token)
          flash[:notice] = l(:notice_account_lost_email_sent)
          redirect_to :action => 'login'
          return
        end
      end
    end
  end
  
  # User self-registration
  def register
    redirect_to(home_url) && return unless Setting.self_registration?
    if request.get?
      @user = User.new(:language => Setting.default_language)
      @custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user) }
    else
      @user = User.new(params[:user])
      @user.admin = false
      @user.login = params[:user][:login]
      @user.status = User::STATUS_REGISTERED
      @user.password, @user.password_confirmation = params[:password], params[:password_confirmation]
      @custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, 
                                                                                :customized => @user, 
                                                                                :value => (params["custom_fields"] ? params["custom_fields"][x.id.to_s] : nil)) }
      @user.custom_values = @custom_values
      case Setting.self_registration
      when '1'
        # Email activation
        token = Token.new(:user => @user, :action => "register")
        if @user.save and token.save
          Mailer.deliver_register(token)
          flash[:notice] = l(:notice_account_register_done)
          redirect_to :action => 'login'
        end
      when '3'
        # Automatic activation
        @user.status = User::STATUS_ACTIVE
        if @user.save
          flash[:notice] = l(:notice_account_activated)
          redirect_to :action => 'login'
        end
      else
        # Manual activation by the administrator
        if @user.save
          # Sends an email to the administrators
          Mailer.deliver_account_activation_request(@user)
          flash[:notice] = l(:notice_account_pending)
          redirect_to :action => 'login'
        end
      end
    end
  end
  
  # Token based account activation
  def activate
    redirect_to(home_url) && return unless Setting.self_registration? && params[:token]
    token = Token.find_by_action_and_value('register', params[:token])
    redirect_to(home_url) && return unless token and !token.expired?
    user = token.user
    redirect_to(home_url) && return unless user.status == User::STATUS_REGISTERED
    user.status = User::STATUS_ACTIVE
    if user.save
      token.destroy
      flash[:notice] = l(:notice_account_activated)
    end
    redirect_to :action => 'login'
  end
  
private
  def logged_user=(user)
    if user && user.is_a?(User)
      User.current = user
      session[:user_id] = user.id
    else
      User.current = User.anonymous
      session[:user_id] = nil
    end
  end
end