##// END OF EJS Templates
Ported the session_store.rb generation task from trunk....
Eric Davis -
r2940:638a9a264a89
parent child
Show More
@@ -0,0 +1,24
1 desc 'Generates a configuration file for cookie store sessions.'
2
3 file 'config/initializers/session_store.rb' do
4 path = File.join(RAILS_ROOT, 'config', 'initializers', 'session_store.rb')
5 secret = Rails::SecretKeyGenerator.new(self).generate_secret[0,40]
6 File.open(path, 'w') do |f|
7 f.write <<"EOF"
8 # This file was generated by 'rake config/initializers/session_store.rb',
9 # and should not be made visible to public.
10 # If you have a load-balancing Redmine cluster, you will need to use the
11 # same version of this file on each machine. And be sure to restart your
12 # server when you modify this file.
13
14 # Your secret key for verifying cookie session data integrity. If you
15 # change this key, all old sessions will become invalid! Make sure the
16 # secret is at least 30 characters and all random, no regular words or
17 # you'll be exposed to dictionary attacks.
18 ActionController::Base.session = {
19 :session_key => '_redmine_session',
20 :secret => '#{secret}'
21 }
22 EOF
23 end
24 end
@@ -1,241 +1,247
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require 'uri'
19 19 require 'cgi'
20 20
21 21 class ApplicationController < ActionController::Base
22 class MissingSessionSecret < Exception ; end
22 23 layout 'base'
23 24
24 25 before_filter :user_setup, :check_if_login_required, :set_localization
25 26 filter_parameter_logging :password
26 protect_from_forgery :secret => session.first[:secret]
27
28 if session.first[:secret].blank?
29 raise MissingSessionSecret, "Missing session secret. Please run 'rake config/initializers/session_store.rb' to generate one"
30 else
31 protect_from_forgery :secret => session.first[:secret]
32 end
27 33
28 34 include Redmine::MenuManager::MenuController
29 35 helper Redmine::MenuManager::MenuHelper
30 36
31 37 REDMINE_SUPPORTED_SCM.each do |scm|
32 38 require_dependency "repository/#{scm.underscore}"
33 39 end
34 40
35 41 def current_role
36 42 @current_role ||= User.current.role_for_project(@project)
37 43 end
38 44
39 45 def user_setup
40 46 # Check the settings cache for each request
41 47 Setting.check_cache
42 48 # Find the current user
43 49 User.current = find_current_user
44 50 end
45 51
46 52 # Returns the current user or nil if no user is logged in
47 53 def find_current_user
48 54 if session[:user_id]
49 55 # existing session
50 56 (User.active.find(session[:user_id]) rescue nil)
51 57 elsif cookies[:autologin] && Setting.autologin?
52 58 # auto-login feature
53 59 User.find_by_autologin_key(cookies[:autologin])
54 60 elsif params[:key] && accept_key_auth_actions.include?(params[:action])
55 61 # RSS key authentication
56 62 User.find_by_rss_key(params[:key])
57 63 end
58 64 end
59 65
60 66 # check if login is globally required to access the application
61 67 def check_if_login_required
62 68 # no check needed if user is already logged in
63 69 return true if User.current.logged?
64 70 require_login if Setting.login_required?
65 71 end
66 72
67 73 def set_localization
68 74 User.current.language = nil unless User.current.logged?
69 75 lang = begin
70 76 if !User.current.language.blank? && GLoc.valid_language?(User.current.language)
71 77 User.current.language
72 78 elsif request.env['HTTP_ACCEPT_LANGUAGE']
73 79 accept_lang = parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first.downcase
74 80 if !accept_lang.blank? && (GLoc.valid_language?(accept_lang) || GLoc.valid_language?(accept_lang = accept_lang.split('-').first))
75 81 User.current.language = accept_lang
76 82 end
77 83 end
78 84 rescue
79 85 nil
80 86 end || Setting.default_language
81 87 set_language_if_valid(lang)
82 88 end
83 89
84 90 def require_login
85 91 if !User.current.logged?
86 92 # Extract only the basic url parameters on non-GET requests
87 93 if request.get?
88 94 url = url_for(params)
89 95 else
90 96 url = url_for(:controller => params[:controller], :action => params[:action], :id => params[:id], :project_id => params[:project_id])
91 97 end
92 98 redirect_to :controller => "account", :action => "login", :back_url => url
93 99 return false
94 100 end
95 101 true
96 102 end
97 103
98 104 def require_admin
99 105 return unless require_login
100 106 if !User.current.admin?
101 107 render_403
102 108 return false
103 109 end
104 110 true
105 111 end
106 112
107 113 def deny_access
108 114 User.current.logged? ? render_403 : require_login
109 115 end
110 116
111 117 # Authorize the user for the requested action
112 118 def authorize(ctrl = params[:controller], action = params[:action])
113 119 allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @project)
114 120 allowed ? true : deny_access
115 121 end
116 122
117 123 # make sure that the user is a member of the project (or admin) if project is private
118 124 # used as a before_filter for actions that do not require any particular permission on the project
119 125 def check_project_privacy
120 126 if @project && @project.active?
121 127 if @project.is_public? || User.current.member_of?(@project) || User.current.admin?
122 128 true
123 129 else
124 130 User.current.logged? ? render_403 : require_login
125 131 end
126 132 else
127 133 @project = nil
128 134 render_404
129 135 false
130 136 end
131 137 end
132 138
133 139 def redirect_back_or_default(default)
134 140 back_url = CGI.unescape(params[:back_url].to_s)
135 141 if !back_url.blank?
136 142 begin
137 143 uri = URI.parse(back_url)
138 144 # do not redirect user to another host or to the login or register page
139 145 if (uri.relative? || (uri.host == request.host)) && !uri.path.match(%r{/(login|account/register)})
140 146 redirect_to(back_url) and return
141 147 end
142 148 rescue URI::InvalidURIError
143 149 # redirect to default
144 150 end
145 151 end
146 152 redirect_to default
147 153 end
148 154
149 155 def render_403
150 156 @project = nil
151 157 render :template => "common/403", :layout => !request.xhr?, :status => 403
152 158 return false
153 159 end
154 160
155 161 def render_404
156 162 render :template => "common/404", :layout => !request.xhr?, :status => 404
157 163 return false
158 164 end
159 165
160 166 def render_error(msg)
161 167 flash.now[:error] = msg
162 168 render :nothing => true, :layout => !request.xhr?, :status => 500
163 169 end
164 170
165 171 def render_feed(items, options={})
166 172 @items = items || []
167 173 @items.sort! {|x,y| y.event_datetime <=> x.event_datetime }
168 174 @items = @items.slice(0, Setting.feeds_limit.to_i)
169 175 @title = options[:title] || Setting.app_title
170 176 render :template => "common/feed.atom.rxml", :layout => false, :content_type => 'application/atom+xml'
171 177 end
172 178
173 179 def self.accept_key_auth(*actions)
174 180 actions = actions.flatten.map(&:to_s)
175 181 write_inheritable_attribute('accept_key_auth_actions', actions)
176 182 end
177 183
178 184 def accept_key_auth_actions
179 185 self.class.read_inheritable_attribute('accept_key_auth_actions') || []
180 186 end
181 187
182 188 # TODO: move to model
183 189 def attach_files(obj, attachments)
184 190 attached = []
185 191 unsaved = []
186 192 if attachments && attachments.is_a?(Hash)
187 193 attachments.each_value do |attachment|
188 194 file = attachment['file']
189 195 next unless file && file.size > 0
190 196 a = Attachment.create(:container => obj,
191 197 :file => file,
192 198 :description => attachment['description'].to_s.strip,
193 199 :author => User.current)
194 200 a.new_record? ? (unsaved << a) : (attached << a)
195 201 end
196 202 if unsaved.any?
197 203 flash[:warning] = l(:warning_attachments_not_saved, unsaved.size)
198 204 end
199 205 end
200 206 attached
201 207 end
202 208
203 209 # Returns the number of objects that should be displayed
204 210 # on the paginated list
205 211 def per_page_option
206 212 per_page = nil
207 213 if params[:per_page] && Setting.per_page_options_array.include?(params[:per_page].to_s.to_i)
208 214 per_page = params[:per_page].to_s.to_i
209 215 session[:per_page] = per_page
210 216 elsif session[:per_page]
211 217 per_page = session[:per_page]
212 218 else
213 219 per_page = Setting.per_page_options_array.first || 25
214 220 end
215 221 per_page
216 222 end
217 223
218 224 # qvalues http header parser
219 225 # code taken from webrick
220 226 def parse_qvalues(value)
221 227 tmp = []
222 228 if value
223 229 parts = value.split(/,\s*/)
224 230 parts.each {|part|
225 231 if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
226 232 val = m[1]
227 233 q = (m[2] or 1).to_f
228 234 tmp.push([val, q])
229 235 end
230 236 }
231 237 tmp = tmp.sort_by{|val, q| -q}
232 238 tmp.collect!{|val, q| val}
233 239 end
234 240 return tmp
235 241 end
236 242
237 243 # Returns a string that can be used as filename value in Content-Disposition header
238 244 def filename_for_content_disposition(name)
239 245 request.env['HTTP_USER_AGENT'] =~ %r{MSIE} ? ERB::Util.url_encode(name) : name
240 246 end
241 247 end
@@ -1,62 +1,65
1 1 == Redmine installation
2 2
3 3 Redmine - project management software
4 4 Copyright (C) 2006-2008 Jean-Philippe Lang
5 5 http://www.redmine.org/
6 6
7 7
8 8 == Requirements
9 9
10 10 * Ruby on Rails 2.1.2
11 11 * A database:
12 12 * MySQL (tested with MySQL 5)
13 13 * PostgreSQL (tested with PostgreSQL 8.1)
14 14 * SQLite (tested with SQLite 3)
15 15
16 16 Optional:
17 17 * SVN binaries >= 1.3 (needed for repository browsing, must be available in PATH)
18 18 * RMagick (gantt export to png)
19 19
20 20 == Installation
21 21
22 22 1. Uncompress the program archive
23 23
24 24 2. Create an empty database: "redmine" for example
25 25
26 26 3. Configure database parameters in config/database.yml
27 27 for "production" environment (default database is MySQL)
28 28
29 29 4. Create the database structure. Under the application main directory:
30 30 rake db:migrate RAILS_ENV="production"
31 31 It will create tables and an administrator account.
32 32
33 5. Setting up permissions
33 5. Generate a session store secret. Run:
34 rake config/initializers/session_store.rb
35
36 6. Setting up permissions
34 37 The user who runs Redmine must have write permission on the following
35 38 subdirectories: files, log, tmp (create the last one if not present).
36 39
37 40 Assuming you run Redmine with a user named redmine:
38 41 mkdir tmp
39 42 sudo chown -R redmine:redmine files log tmp
40 43 sudo chmod -R 755 files log tmp
41 44
42 6. Test the installation by running WEBrick web server:
45 7. Test the installation by running WEBrick web server:
43 46 ruby script/server -e production
44 47
45 48 Once WEBrick has started, point your browser to http://localhost:3000/
46 49 You should now see the application welcome page
47 50
48 7. Use default administrator account to log in:
51 8. Use default administrator account to log in:
49 52 login: admin
50 53 password: admin
51 54
52 55 Go to "Administration" to load the default configuration data (roles,
53 56 trackers, statuses, workflow) and adjust application settings
54 57
55 58
56 59 == Email delivery Configuration
57 60
58 61 Copy config/email.yml.example to config/email.yml and edit this file
59 62 to adjust your SMTP settings.
60 63 Don't forget to restart the application after any change to this file.
61 64
62 65 Please do not enter your SMTP settings in environment.rb.
General Comments 0
You need to be logged in to leave comments. Login now