Revision 1298:4f746d8966dd .svn/pristine/00
| .svn/pristine/00/0009a621965fc195e93ba67a7d3500cbcd38b084.svn-base | ||
|---|---|---|
| 1 |
# Redmine - project management software |
|
| 2 |
# Copyright (C) 2006-2013 Jean-Philippe Lang |
|
| 3 |
# |
|
| 4 |
# This program is free software; you can redistribute it and/or |
|
| 5 |
# modify it under the terms of the GNU General Public License |
|
| 6 |
# as published by the Free Software Foundation; either version 2 |
|
| 7 |
# of the License, or (at your option) any later version. |
|
| 8 |
# |
|
| 9 |
# This program is distributed in the hope that it will be useful, |
|
| 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
# GNU General Public License for more details. |
|
| 13 |
# |
|
| 14 |
# You should have received a copy of the GNU General Public License |
|
| 15 |
# along with this program; if not, write to the Free Software |
|
| 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 17 |
|
|
| 18 |
class DocumentsController < ApplicationController |
|
| 19 |
default_search_scope :documents |
|
| 20 |
model_object Document |
|
| 21 |
before_filter :find_project_by_project_id, :only => [:index, :new, :create] |
|
| 22 |
before_filter :find_model_object, :except => [:index, :new, :create] |
|
| 23 |
before_filter :find_project_from_association, :except => [:index, :new, :create] |
|
| 24 |
before_filter :authorize |
|
| 25 |
|
|
| 26 |
helper :attachments |
|
| 27 |
|
|
| 28 |
def index |
|
| 29 |
@sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category' |
|
| 30 |
documents = @project.documents.includes(:attachments, :category).all |
|
| 31 |
case @sort_by |
|
| 32 |
when 'date' |
|
| 33 |
@grouped = documents.group_by {|d| d.updated_on.to_date }
|
|
| 34 |
when 'title' |
|
| 35 |
@grouped = documents.group_by {|d| d.title.first.upcase}
|
|
| 36 |
when 'author' |
|
| 37 |
@grouped = documents.select{|d| d.attachments.any?}.group_by {|d| d.attachments.last.author}
|
|
| 38 |
else |
|
| 39 |
@grouped = documents.group_by(&:category) |
|
| 40 |
end |
|
| 41 |
@document = @project.documents.build |
|
| 42 |
render :layout => false if request.xhr? |
|
| 43 |
end |
|
| 44 |
|
|
| 45 |
def show |
|
| 46 |
@attachments = @document.attachments.all |
|
| 47 |
end |
|
| 48 |
|
|
| 49 |
def new |
|
| 50 |
@document = @project.documents.build |
|
| 51 |
@document.safe_attributes = params[:document] |
|
| 52 |
end |
|
| 53 |
|
|
| 54 |
def create |
|
| 55 |
@document = @project.documents.build |
|
| 56 |
@document.safe_attributes = params[:document] |
|
| 57 |
@document.save_attachments(params[:attachments]) |
|
| 58 |
if @document.save |
|
| 59 |
render_attachment_warning_if_needed(@document) |
|
| 60 |
flash[:notice] = l(:notice_successful_create) |
|
| 61 |
redirect_to project_documents_path(@project) |
|
| 62 |
else |
|
| 63 |
render :action => 'new' |
|
| 64 |
end |
|
| 65 |
end |
|
| 66 |
|
|
| 67 |
def edit |
|
| 68 |
end |
|
| 69 |
|
|
| 70 |
def update |
|
| 71 |
@document.safe_attributes = params[:document] |
|
| 72 |
if request.put? and @document.save |
|
| 73 |
flash[:notice] = l(:notice_successful_update) |
|
| 74 |
redirect_to document_path(@document) |
|
| 75 |
else |
|
| 76 |
render :action => 'edit' |
|
| 77 |
end |
|
| 78 |
end |
|
| 79 |
|
|
| 80 |
def destroy |
|
| 81 |
@document.destroy if request.delete? |
|
| 82 |
redirect_to project_documents_path(@project) |
|
| 83 |
end |
|
| 84 |
|
|
| 85 |
def add_attachment |
|
| 86 |
attachments = Attachment.attach_files(@document, params[:attachments]) |
|
| 87 |
render_attachment_warning_if_needed(@document) |
|
| 88 |
|
|
| 89 |
if attachments.present? && attachments[:files].present? && Setting.notified_events.include?('document_added')
|
|
| 90 |
Mailer.attachments_added(attachments[:files]).deliver |
|
| 91 |
end |
|
| 92 |
redirect_to document_path(@document) |
|
| 93 |
end |
|
| 94 |
end |
|
| .svn/pristine/00/002d478f30849d26745d0ec7b1c75e9c7796a254.svn-base | ||
|---|---|---|
| 1 |
# Redmine - project management software |
|
| 2 |
# Copyright (C) 2006-2013 Jean-Philippe Lang |
|
| 3 |
# |
|
| 4 |
# This program is free software; you can redistribute it and/or |
|
| 5 |
# modify it under the terms of the GNU General Public License |
|
| 6 |
# as published by the Free Software Foundation; either version 2 |
|
| 7 |
# of the License, or (at your option) any later version. |
|
| 8 |
# |
|
| 9 |
# This program is distributed in the hope that it will be useful, |
|
| 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
# GNU General Public License for more details. |
|
| 13 |
# |
|
| 14 |
# You should have received a copy of the GNU General Public License |
|
| 15 |
# along with this program; if not, write to the Free Software |
|
| 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 17 |
|
|
| 18 |
require File.expand_path('../../test_helper', __FILE__)
|
|
| 19 |
|
|
| 20 |
class MailerTest < ActiveSupport::TestCase |
|
| 21 |
include Redmine::I18n |
|
| 22 |
include ActionDispatch::Assertions::SelectorAssertions |
|
| 23 |
fixtures :projects, :enabled_modules, :issues, :users, :members, |
|
| 24 |
:member_roles, :roles, :documents, :attachments, :news, |
|
| 25 |
:tokens, :journals, :journal_details, :changesets, |
|
| 26 |
:trackers, :projects_trackers, |
|
| 27 |
:issue_statuses, :enumerations, :messages, :boards, :repositories, |
|
| 28 |
:wikis, :wiki_pages, :wiki_contents, :wiki_content_versions, |
|
| 29 |
:versions, |
|
| 30 |
:comments |
|
| 31 |
|
|
| 32 |
def setup |
|
| 33 |
ActionMailer::Base.deliveries.clear |
|
| 34 |
Setting.host_name = 'mydomain.foo' |
|
| 35 |
Setting.protocol = 'http' |
|
| 36 |
Setting.plain_text_mail = '0' |
|
| 37 |
end |
|
| 38 |
|
|
| 39 |
def test_generated_links_in_emails |
|
| 40 |
Setting.default_language = 'en' |
|
| 41 |
Setting.host_name = 'mydomain.foo' |
|
| 42 |
Setting.protocol = 'https' |
|
| 43 |
|
|
| 44 |
journal = Journal.find(3) |
|
| 45 |
assert Mailer.issue_edit(journal).deliver |
|
| 46 |
|
|
| 47 |
mail = last_email |
|
| 48 |
assert_not_nil mail |
|
| 49 |
|
|
| 50 |
assert_select_email do |
|
| 51 |
# link to the main ticket |
|
| 52 |
assert_select 'a[href=?]', |
|
| 53 |
'https://mydomain.foo/issues/2#change-3', |
|
| 54 |
:text => 'Feature request #2: Add ingredients categories' |
|
| 55 |
# link to a referenced ticket |
|
| 56 |
assert_select 'a[href=?][title=?]', |
|
| 57 |
'https://mydomain.foo/issues/1', |
|
| 58 |
'Can't print recipes (New)', |
|
| 59 |
:text => '#1' |
|
| 60 |
# link to a changeset |
|
| 61 |
assert_select 'a[href=?][title=?]', |
|
| 62 |
'https://mydomain.foo/projects/ecookbook/repository/revisions/2', |
|
| 63 |
'This commit fixes #1, #2 and references #1 & #3', |
|
| 64 |
:text => 'r2' |
|
| 65 |
# link to a description diff |
|
| 66 |
assert_select 'a[href=?][title=?]', |
|
| 67 |
'https://mydomain.foo/journals/diff/3?detail_id=4', |
|
| 68 |
'View differences', |
|
| 69 |
:text => 'diff' |
|
| 70 |
# link to an attachment |
|
| 71 |
assert_select 'a[href=?]', |
|
| 72 |
'https://mydomain.foo/attachments/download/4/source.rb', |
|
| 73 |
:text => 'source.rb' |
|
| 74 |
end |
|
| 75 |
end |
|
| 76 |
|
|
| 77 |
def test_generated_links_with_prefix |
|
| 78 |
Setting.default_language = 'en' |
|
| 79 |
relative_url_root = Redmine::Utils.relative_url_root |
|
| 80 |
Setting.host_name = 'mydomain.foo/rdm' |
|
| 81 |
Setting.protocol = 'http' |
|
| 82 |
|
|
| 83 |
journal = Journal.find(3) |
|
| 84 |
assert Mailer.issue_edit(journal).deliver |
|
| 85 |
|
|
| 86 |
mail = last_email |
|
| 87 |
assert_not_nil mail |
|
| 88 |
|
|
| 89 |
assert_select_email do |
|
| 90 |
# link to the main ticket |
|
| 91 |
assert_select 'a[href=?]', |
|
| 92 |
'http://mydomain.foo/rdm/issues/2#change-3', |
|
| 93 |
:text => 'Feature request #2: Add ingredients categories' |
|
| 94 |
# link to a referenced ticket |
|
| 95 |
assert_select 'a[href=?][title=?]', |
|
| 96 |
'http://mydomain.foo/rdm/issues/1', |
|
| 97 |
'Can't print recipes (New)', |
|
| 98 |
:text => '#1' |
|
| 99 |
# link to a changeset |
|
| 100 |
assert_select 'a[href=?][title=?]', |
|
| 101 |
'http://mydomain.foo/rdm/projects/ecookbook/repository/revisions/2', |
|
| 102 |
'This commit fixes #1, #2 and references #1 & #3', |
|
| 103 |
:text => 'r2' |
|
| 104 |
# link to a description diff |
|
| 105 |
assert_select 'a[href=?][title=?]', |
|
| 106 |
'http://mydomain.foo/rdm/journals/diff/3?detail_id=4', |
|
| 107 |
'View differences', |
|
| 108 |
:text => 'diff' |
|
| 109 |
# link to an attachment |
|
| 110 |
assert_select 'a[href=?]', |
|
| 111 |
'http://mydomain.foo/rdm/attachments/download/4/source.rb', |
|
| 112 |
:text => 'source.rb' |
|
| 113 |
end |
|
| 114 |
end |
|
| 115 |
|
|
| 116 |
def test_generated_links_with_prefix_and_no_relative_url_root |
|
| 117 |
Setting.default_language = 'en' |
|
| 118 |
relative_url_root = Redmine::Utils.relative_url_root |
|
| 119 |
Setting.host_name = 'mydomain.foo/rdm' |
|
| 120 |
Setting.protocol = 'http' |
|
| 121 |
Redmine::Utils.relative_url_root = nil |
|
| 122 |
|
|
| 123 |
journal = Journal.find(3) |
|
| 124 |
assert Mailer.issue_edit(journal).deliver |
|
| 125 |
|
|
| 126 |
mail = last_email |
|
| 127 |
assert_not_nil mail |
|
| 128 |
|
|
| 129 |
assert_select_email do |
|
| 130 |
# link to the main ticket |
|
| 131 |
assert_select 'a[href=?]', |
|
| 132 |
'http://mydomain.foo/rdm/issues/2#change-3', |
|
| 133 |
:text => 'Feature request #2: Add ingredients categories' |
|
| 134 |
# link to a referenced ticket |
|
| 135 |
assert_select 'a[href=?][title=?]', |
|
| 136 |
'http://mydomain.foo/rdm/issues/1', |
|
| 137 |
'Can't print recipes (New)', |
|
| 138 |
:text => '#1' |
|
| 139 |
# link to a changeset |
|
| 140 |
assert_select 'a[href=?][title=?]', |
|
| 141 |
'http://mydomain.foo/rdm/projects/ecookbook/repository/revisions/2', |
|
| 142 |
'This commit fixes #1, #2 and references #1 & #3', |
|
| 143 |
:text => 'r2' |
|
| 144 |
# link to a description diff |
|
| 145 |
assert_select 'a[href=?][title=?]', |
|
| 146 |
'http://mydomain.foo/rdm/journals/diff/3?detail_id=4', |
|
| 147 |
'View differences', |
|
| 148 |
:text => 'diff' |
|
| 149 |
# link to an attachment |
|
| 150 |
assert_select 'a[href=?]', |
|
| 151 |
'http://mydomain.foo/rdm/attachments/download/4/source.rb', |
|
| 152 |
:text => 'source.rb' |
|
| 153 |
end |
|
| 154 |
ensure |
|
| 155 |
# restore it |
|
| 156 |
Redmine::Utils.relative_url_root = relative_url_root |
|
| 157 |
end |
|
| 158 |
|
|
| 159 |
def test_email_headers |
|
| 160 |
issue = Issue.find(1) |
|
| 161 |
Mailer.issue_add(issue).deliver |
|
| 162 |
mail = last_email |
|
| 163 |
assert_not_nil mail |
|
| 164 |
assert_equal 'OOF', mail.header['X-Auto-Response-Suppress'].to_s |
|
| 165 |
assert_equal 'auto-generated', mail.header['Auto-Submitted'].to_s |
|
| 166 |
assert_equal '<redmine.example.net>', mail.header['List-Id'].to_s |
|
| 167 |
end |
|
| 168 |
|
|
| 169 |
def test_email_headers_should_include_sender |
|
| 170 |
issue = Issue.find(1) |
|
| 171 |
Mailer.issue_add(issue).deliver |
|
| 172 |
mail = last_email |
|
| 173 |
assert_equal issue.author.login, mail.header['X-Redmine-Sender'].to_s |
|
| 174 |
end |
|
| 175 |
|
|
| 176 |
def test_plain_text_mail |
|
| 177 |
Setting.plain_text_mail = 1 |
|
| 178 |
journal = Journal.find(2) |
|
| 179 |
Mailer.issue_edit(journal).deliver |
|
| 180 |
mail = last_email |
|
| 181 |
assert_equal "text/plain; charset=UTF-8", mail.content_type |
|
| 182 |
assert_equal 0, mail.parts.size |
|
| 183 |
assert !mail.encoded.include?('href')
|
|
| 184 |
end |
|
| 185 |
|
|
| 186 |
def test_html_mail |
|
| 187 |
Setting.plain_text_mail = 0 |
|
| 188 |
journal = Journal.find(2) |
|
| 189 |
Mailer.issue_edit(journal).deliver |
|
| 190 |
mail = last_email |
|
| 191 |
assert_equal 2, mail.parts.size |
|
| 192 |
assert mail.encoded.include?('href')
|
|
| 193 |
end |
|
| 194 |
|
|
| 195 |
def test_from_header |
|
| 196 |
with_settings :mail_from => 'redmine@example.net' do |
|
| 197 |
Mailer.test_email(User.find(1)).deliver |
|
| 198 |
end |
|
| 199 |
mail = last_email |
|
| 200 |
assert_equal 'redmine@example.net', mail.from_addrs.first |
|
| 201 |
end |
|
| 202 |
|
|
| 203 |
def test_from_header_with_phrase |
|
| 204 |
with_settings :mail_from => 'Redmine app <redmine@example.net>' do |
|
| 205 |
Mailer.test_email(User.find(1)).deliver |
|
| 206 |
end |
|
| 207 |
mail = last_email |
|
| 208 |
assert_equal 'redmine@example.net', mail.from_addrs.first |
|
| 209 |
assert_equal 'Redmine app <redmine@example.net>', mail.header['From'].to_s |
|
| 210 |
end |
|
| 211 |
|
|
| 212 |
def test_should_not_send_email_without_recipient |
|
| 213 |
news = News.first |
|
| 214 |
user = news.author |
|
| 215 |
# Remove members except news author |
|
| 216 |
news.project.memberships.each {|m| m.destroy unless m.user == user}
|
|
| 217 |
|
|
| 218 |
user.pref[:no_self_notified] = false |
|
| 219 |
user.pref.save |
|
| 220 |
User.current = user |
|
| 221 |
Mailer.news_added(news.reload).deliver |
|
| 222 |
assert_equal 1, last_email.bcc.size |
|
| 223 |
|
|
| 224 |
# nobody to notify |
|
| 225 |
user.pref[:no_self_notified] = true |
|
| 226 |
user.pref.save |
|
| 227 |
User.current = user |
|
| 228 |
ActionMailer::Base.deliveries.clear |
|
| 229 |
Mailer.news_added(news.reload).deliver |
|
| 230 |
assert ActionMailer::Base.deliveries.empty? |
|
| 231 |
end |
|
| 232 |
|
|
| 233 |
def test_issue_add_message_id |
|
| 234 |
issue = Issue.find(1) |
|
| 235 |
Mailer.issue_add(issue).deliver |
|
| 236 |
mail = last_email |
|
| 237 |
assert_equal Mailer.message_id_for(issue), mail.message_id |
|
| 238 |
assert_nil mail.references |
|
| 239 |
end |
|
| 240 |
|
|
| 241 |
def test_issue_edit_message_id |
|
| 242 |
journal = Journal.find(1) |
|
| 243 |
Mailer.issue_edit(journal).deliver |
|
| 244 |
mail = last_email |
|
| 245 |
assert_equal Mailer.message_id_for(journal), mail.message_id |
|
| 246 |
assert_include Mailer.message_id_for(journal.issue), mail.references |
|
| 247 |
assert_select_email do |
|
| 248 |
# link to the update |
|
| 249 |
assert_select "a[href=?]", |
|
| 250 |
"http://mydomain.foo/issues/#{journal.journalized_id}#change-#{journal.id}"
|
|
| 251 |
end |
|
| 252 |
end |
|
| 253 |
|
|
| 254 |
def test_message_posted_message_id |
|
| 255 |
message = Message.find(1) |
|
| 256 |
Mailer.message_posted(message).deliver |
|
| 257 |
mail = last_email |
|
| 258 |
assert_equal Mailer.message_id_for(message), mail.message_id |
|
| 259 |
assert_nil mail.references |
|
| 260 |
assert_select_email do |
|
| 261 |
# link to the message |
|
| 262 |
assert_select "a[href=?]", |
|
| 263 |
"http://mydomain.foo/boards/#{message.board.id}/topics/#{message.id}",
|
|
| 264 |
:text => message.subject |
|
| 265 |
end |
|
| 266 |
end |
|
| 267 |
|
|
| 268 |
def test_reply_posted_message_id |
|
| 269 |
message = Message.find(3) |
|
| 270 |
Mailer.message_posted(message).deliver |
|
| 271 |
mail = last_email |
|
| 272 |
assert_equal Mailer.message_id_for(message), mail.message_id |
|
| 273 |
assert_include Mailer.message_id_for(message.parent), mail.references |
|
| 274 |
assert_select_email do |
|
| 275 |
# link to the reply |
|
| 276 |
assert_select "a[href=?]", |
|
| 277 |
"http://mydomain.foo/boards/#{message.board.id}/topics/#{message.root.id}?r=#{message.id}#message-#{message.id}",
|
|
| 278 |
:text => message.subject |
|
| 279 |
end |
|
| 280 |
end |
|
| 281 |
|
|
| 282 |
test "#issue_add should notify project members" do |
|
| 283 |
issue = Issue.find(1) |
|
| 284 |
assert Mailer.issue_add(issue).deliver |
|
| 285 |
assert last_email.bcc.include?('dlopper@somenet.foo')
|
|
| 286 |
end |
|
| 287 |
|
|
| 288 |
test "#issue_add should not notify project members that are not allow to view the issue" do |
|
| 289 |
issue = Issue.find(1) |
|
| 290 |
Role.find(2).remove_permission!(:view_issues) |
|
| 291 |
assert Mailer.issue_add(issue).deliver |
|
| 292 |
assert !last_email.bcc.include?('dlopper@somenet.foo')
|
|
| 293 |
end |
|
| 294 |
|
|
| 295 |
test "#issue_add should notify issue watchers" do |
|
| 296 |
issue = Issue.find(1) |
|
| 297 |
user = User.find(9) |
|
| 298 |
# minimal email notification options |
|
| 299 |
user.pref[:no_self_notified] = '1' |
|
| 300 |
user.pref.save |
|
| 301 |
user.mail_notification = false |
|
| 302 |
user.save |
|
| 303 |
|
|
| 304 |
Watcher.create!(:watchable => issue, :user => user) |
|
| 305 |
assert Mailer.issue_add(issue).deliver |
|
| 306 |
assert last_email.bcc.include?(user.mail) |
|
| 307 |
end |
|
| 308 |
|
|
| 309 |
test "#issue_add should not notify watchers not allowed to view the issue" do |
|
| 310 |
issue = Issue.find(1) |
|
| 311 |
user = User.find(9) |
|
| 312 |
Watcher.create!(:watchable => issue, :user => user) |
|
| 313 |
Role.non_member.remove_permission!(:view_issues) |
|
| 314 |
assert Mailer.issue_add(issue).deliver |
|
| 315 |
assert !last_email.bcc.include?(user.mail) |
|
| 316 |
end |
|
| 317 |
|
|
| 318 |
# test mailer methods for each language |
|
| 319 |
def test_issue_add |
|
| 320 |
issue = Issue.find(1) |
|
| 321 |
valid_languages.each do |lang| |
|
| 322 |
Setting.default_language = lang.to_s |
|
| 323 |
assert Mailer.issue_add(issue).deliver |
|
| 324 |
end |
|
| 325 |
end |
|
| 326 |
|
|
| 327 |
def test_issue_edit |
|
| 328 |
journal = Journal.find(1) |
|
| 329 |
valid_languages.each do |lang| |
|
| 330 |
Setting.default_language = lang.to_s |
|
| 331 |
assert Mailer.issue_edit(journal).deliver |
|
| 332 |
end |
|
| 333 |
end |
|
| 334 |
|
|
| 335 |
def test_issue_edit_should_send_private_notes_to_users_with_permission_only |
|
| 336 |
journal = Journal.find(1) |
|
| 337 |
journal.private_notes = true |
|
| 338 |
journal.save! |
|
| 339 |
|
|
| 340 |
Role.find(2).add_permission! :view_private_notes |
|
| 341 |
Mailer.issue_edit(journal).deliver |
|
| 342 |
assert_equal %w(dlopper@somenet.foo jsmith@somenet.foo), ActionMailer::Base.deliveries.last.bcc.sort |
|
| 343 |
|
|
| 344 |
Role.find(2).remove_permission! :view_private_notes |
|
| 345 |
Mailer.issue_edit(journal).deliver |
|
| 346 |
assert_equal %w(jsmith@somenet.foo), ActionMailer::Base.deliveries.last.bcc.sort |
|
| 347 |
end |
|
| 348 |
|
|
| 349 |
def test_issue_edit_should_send_private_notes_to_watchers_with_permission_only |
|
| 350 |
Issue.find(1).set_watcher(User.find_by_login('someone'))
|
|
| 351 |
journal = Journal.find(1) |
|
| 352 |
journal.private_notes = true |
|
| 353 |
journal.save! |
|
| 354 |
|
|
| 355 |
Role.non_member.add_permission! :view_private_notes |
|
| 356 |
Mailer.issue_edit(journal).deliver |
|
| 357 |
assert_include 'someone@foo.bar', ActionMailer::Base.deliveries.last.bcc.sort |
|
| 358 |
|
|
| 359 |
Role.non_member.remove_permission! :view_private_notes |
|
| 360 |
Mailer.issue_edit(journal).deliver |
|
| 361 |
assert_not_include 'someone@foo.bar', ActionMailer::Base.deliveries.last.bcc.sort |
|
| 362 |
end |
|
| 363 |
|
|
| 364 |
def test_document_added |
|
| 365 |
document = Document.find(1) |
|
| 366 |
valid_languages.each do |lang| |
|
| 367 |
Setting.default_language = lang.to_s |
|
| 368 |
assert Mailer.document_added(document).deliver |
|
| 369 |
end |
|
| 370 |
end |
|
| 371 |
|
|
| 372 |
def test_attachments_added |
|
| 373 |
attachements = [ Attachment.find_by_container_type('Document') ]
|
|
| 374 |
valid_languages.each do |lang| |
|
| 375 |
Setting.default_language = lang.to_s |
|
| 376 |
assert Mailer.attachments_added(attachements).deliver |
|
| 377 |
end |
|
| 378 |
end |
|
| 379 |
|
|
| 380 |
def test_version_file_added |
|
| 381 |
attachements = [ Attachment.find_by_container_type('Version') ]
|
|
| 382 |
assert Mailer.attachments_added(attachements).deliver |
|
| 383 |
assert_not_nil last_email.bcc |
|
| 384 |
assert last_email.bcc.any? |
|
| 385 |
assert_select_email do |
|
| 386 |
assert_select "a[href=?]", "http://mydomain.foo/projects/ecookbook/files" |
|
| 387 |
end |
|
| 388 |
end |
|
| 389 |
|
|
| 390 |
def test_project_file_added |
|
| 391 |
attachements = [ Attachment.find_by_container_type('Project') ]
|
|
| 392 |
assert Mailer.attachments_added(attachements).deliver |
|
| 393 |
assert_not_nil last_email.bcc |
|
| 394 |
assert last_email.bcc.any? |
|
| 395 |
assert_select_email do |
|
| 396 |
assert_select "a[href=?]", "http://mydomain.foo/projects/ecookbook/files" |
|
| 397 |
end |
|
| 398 |
end |
|
| 399 |
|
|
| 400 |
def test_news_added |
|
| 401 |
news = News.first |
|
| 402 |
valid_languages.each do |lang| |
|
| 403 |
Setting.default_language = lang.to_s |
|
| 404 |
assert Mailer.news_added(news).deliver |
|
| 405 |
end |
|
| 406 |
end |
|
| 407 |
|
|
| 408 |
def test_news_comment_added |
|
| 409 |
comment = Comment.find(2) |
|
| 410 |
valid_languages.each do |lang| |
|
| 411 |
Setting.default_language = lang.to_s |
|
| 412 |
assert Mailer.news_comment_added(comment).deliver |
|
| 413 |
end |
|
| 414 |
end |
|
| 415 |
|
|
| 416 |
def test_message_posted |
|
| 417 |
message = Message.first |
|
| 418 |
recipients = ([message.root] + message.root.children).collect {|m| m.author.mail if m.author}
|
|
| 419 |
recipients = recipients.compact.uniq |
|
| 420 |
valid_languages.each do |lang| |
|
| 421 |
Setting.default_language = lang.to_s |
|
| 422 |
assert Mailer.message_posted(message).deliver |
|
| 423 |
end |
|
| 424 |
end |
|
| 425 |
|
|
| 426 |
def test_wiki_content_added |
|
| 427 |
content = WikiContent.find(1) |
|
| 428 |
valid_languages.each do |lang| |
|
| 429 |
Setting.default_language = lang.to_s |
|
| 430 |
assert_difference 'ActionMailer::Base.deliveries.size' do |
|
| 431 |
assert Mailer.wiki_content_added(content).deliver |
|
| 432 |
assert_select_email do |
|
| 433 |
assert_select 'a[href=?]', |
|
| 434 |
'http://mydomain.foo/projects/ecookbook/wiki/CookBook_documentation', |
|
| 435 |
:text => 'CookBook documentation' |
|
| 436 |
end |
|
| 437 |
end |
|
| 438 |
end |
|
| 439 |
end |
|
| 440 |
|
|
| 441 |
def test_wiki_content_updated |
|
| 442 |
content = WikiContent.find(1) |
|
| 443 |
valid_languages.each do |lang| |
|
| 444 |
Setting.default_language = lang.to_s |
|
| 445 |
assert_difference 'ActionMailer::Base.deliveries.size' do |
|
| 446 |
assert Mailer.wiki_content_updated(content).deliver |
|
| 447 |
assert_select_email do |
|
| 448 |
assert_select 'a[href=?]', |
|
| 449 |
'http://mydomain.foo/projects/ecookbook/wiki/CookBook_documentation', |
|
| 450 |
:text => 'CookBook documentation' |
|
| 451 |
end |
|
| 452 |
end |
|
| 453 |
end |
|
| 454 |
end |
|
| 455 |
|
|
| 456 |
def test_account_information |
|
| 457 |
user = User.find(2) |
|
| 458 |
valid_languages.each do |lang| |
|
| 459 |
user.update_attribute :language, lang.to_s |
|
| 460 |
user.reload |
|
| 461 |
assert Mailer.account_information(user, 'pAsswORd').deliver |
|
| 462 |
end |
|
| 463 |
end |
|
| 464 |
|
|
| 465 |
def test_lost_password |
|
| 466 |
token = Token.find(2) |
|
| 467 |
valid_languages.each do |lang| |
|
| 468 |
token.user.update_attribute :language, lang.to_s |
|
| 469 |
token.reload |
|
| 470 |
assert Mailer.lost_password(token).deliver |
|
| 471 |
end |
|
| 472 |
end |
|
| 473 |
|
|
| 474 |
def test_register |
|
| 475 |
token = Token.find(1) |
|
| 476 |
Setting.host_name = 'redmine.foo' |
|
| 477 |
Setting.protocol = 'https' |
|
| 478 |
|
|
| 479 |
valid_languages.each do |lang| |
|
| 480 |
token.user.update_attribute :language, lang.to_s |
|
| 481 |
token.reload |
|
| 482 |
ActionMailer::Base.deliveries.clear |
|
| 483 |
assert Mailer.register(token).deliver |
|
| 484 |
mail = last_email |
|
| 485 |
assert_select_email do |
|
| 486 |
assert_select "a[href=?]", |
|
| 487 |
"https://redmine.foo/account/activate?token=#{token.value}",
|
|
| 488 |
:text => "https://redmine.foo/account/activate?token=#{token.value}"
|
|
| 489 |
end |
|
| 490 |
end |
|
| 491 |
end |
|
| 492 |
|
|
| 493 |
def test_test |
|
| 494 |
user = User.find(1) |
|
| 495 |
valid_languages.each do |lang| |
|
| 496 |
user.update_attribute :language, lang.to_s |
|
| 497 |
assert Mailer.test_email(user).deliver |
|
| 498 |
end |
|
| 499 |
end |
|
| 500 |
|
|
| 501 |
def test_reminders |
|
| 502 |
Mailer.reminders(:days => 42) |
|
| 503 |
assert_equal 1, ActionMailer::Base.deliveries.size |
|
| 504 |
mail = last_email |
|
| 505 |
assert mail.bcc.include?('dlopper@somenet.foo')
|
|
| 506 |
assert_mail_body_match 'Bug #3: Error 281 when updating a recipe', mail |
|
| 507 |
assert_equal '1 issue(s) due in the next 42 days', mail.subject |
|
| 508 |
end |
|
| 509 |
|
|
| 510 |
def test_reminders_should_not_include_closed_issues |
|
| 511 |
with_settings :default_language => 'en' do |
|
| 512 |
Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 5, |
|
| 513 |
:subject => 'Closed issue', :assigned_to_id => 3, |
|
| 514 |
:due_date => 5.days.from_now, |
|
| 515 |
:author_id => 2) |
|
| 516 |
ActionMailer::Base.deliveries.clear |
|
| 517 |
|
|
| 518 |
Mailer.reminders(:days => 42) |
|
| 519 |
assert_equal 1, ActionMailer::Base.deliveries.size |
|
| 520 |
mail = last_email |
|
| 521 |
assert mail.bcc.include?('dlopper@somenet.foo')
|
|
| 522 |
assert_mail_body_no_match 'Closed issue', mail |
|
| 523 |
end |
|
| 524 |
end |
|
| 525 |
|
|
| 526 |
def test_reminders_for_users |
|
| 527 |
Mailer.reminders(:days => 42, :users => ['5']) |
|
| 528 |
assert_equal 0, ActionMailer::Base.deliveries.size # No mail for dlopper |
|
| 529 |
Mailer.reminders(:days => 42, :users => ['3']) |
|
| 530 |
assert_equal 1, ActionMailer::Base.deliveries.size # No mail for dlopper |
|
| 531 |
mail = last_email |
|
| 532 |
assert mail.bcc.include?('dlopper@somenet.foo')
|
|
| 533 |
assert_mail_body_match 'Bug #3: Error 281 when updating a recipe', mail |
|
| 534 |
end |
|
| 535 |
|
|
| 536 |
def test_reminder_should_include_issues_assigned_to_groups |
|
| 537 |
with_settings :default_language => 'en' do |
|
| 538 |
group = Group.generate! |
|
| 539 |
group.users << User.find(2) |
|
| 540 |
group.users << User.find(3) |
|
| 541 |
|
|
| 542 |
Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 1, |
|
| 543 |
:subject => 'Assigned to group', :assigned_to => group, |
|
| 544 |
:due_date => 5.days.from_now, |
|
| 545 |
:author_id => 2) |
|
| 546 |
ActionMailer::Base.deliveries.clear |
|
| 547 |
|
|
| 548 |
Mailer.reminders(:days => 7) |
|
| 549 |
assert_equal 2, ActionMailer::Base.deliveries.size |
|
| 550 |
assert_equal %w(dlopper@somenet.foo jsmith@somenet.foo), ActionMailer::Base.deliveries.map(&:bcc).flatten.sort |
|
| 551 |
ActionMailer::Base.deliveries.each do |mail| |
|
| 552 |
assert_mail_body_match 'Assigned to group', mail |
|
| 553 |
end |
|
| 554 |
end |
|
| 555 |
end |
|
| 556 |
|
|
| 557 |
def test_mailer_should_not_change_locale |
|
| 558 |
Setting.default_language = 'en' |
|
| 559 |
# Set current language to italian |
|
| 560 |
set_language_if_valid 'it' |
|
| 561 |
# Send an email to a french user |
|
| 562 |
user = User.find(1) |
|
| 563 |
user.language = 'fr' |
|
| 564 |
Mailer.account_activated(user).deliver |
|
| 565 |
mail = last_email |
|
| 566 |
assert_mail_body_match 'Votre compte', mail |
|
| 567 |
|
|
| 568 |
assert_equal :it, current_language |
|
| 569 |
end |
|
| 570 |
|
|
| 571 |
def test_with_deliveries_off |
|
| 572 |
Mailer.with_deliveries false do |
|
| 573 |
Mailer.test_email(User.find(1)).deliver |
|
| 574 |
end |
|
| 575 |
assert ActionMailer::Base.deliveries.empty? |
|
| 576 |
# should restore perform_deliveries |
|
| 577 |
assert ActionMailer::Base.perform_deliveries |
|
| 578 |
end |
|
| 579 |
|
|
| 580 |
def test_layout_should_include_the_emails_header |
|
| 581 |
with_settings :emails_header => "*Header content*" do |
|
| 582 |
assert Mailer.test_email(User.find(1)).deliver |
|
| 583 |
assert_select_email do |
|
| 584 |
assert_select ".header" do |
|
| 585 |
assert_select "strong", :text => "Header content" |
|
| 586 |
end |
|
| 587 |
end |
|
| 588 |
end |
|
| 589 |
end |
|
| 590 |
|
|
| 591 |
def test_should_escape_html_templates_only |
|
| 592 |
Issue.generate!(:project_id => 1, :tracker_id => 1, :subject => 'Subject with a <tag>') |
|
| 593 |
mail = last_email |
|
| 594 |
assert_equal 2, mail.parts.size |
|
| 595 |
assert_include '<tag>', text_part.body.encoded |
|
| 596 |
assert_include '<tag>', html_part.body.encoded |
|
| 597 |
end |
|
| 598 |
|
|
| 599 |
private |
|
| 600 |
|
|
| 601 |
def last_email |
|
| 602 |
mail = ActionMailer::Base.deliveries.last |
|
| 603 |
assert_not_nil mail |
|
| 604 |
|
|
| 605 |
end |
|
| 606 |
|
|
| 607 |
def text_part |
|
| 608 |
last_email.parts.detect {|part| part.content_type.include?('text/plain')}
|
|
| 609 |
end |
|
| 610 |
|
|
| 611 |
def html_part |
|
| 612 |
last_email.parts.detect {|part| part.content_type.include?('text/html')}
|
|
| 613 |
end |
|
| 614 |
end |
|
| .svn/pristine/00/007e22f777adc578342260747f72f3fcfceb129d.svn-base | ||
|---|---|---|
| 1 |
# Redmine - project management software |
|
| 2 |
# Copyright (C) 2006-2011 Jean-Philippe Lang |
|
| 3 |
# |
|
| 4 |
# This program is free software; you can redistribute it and/or |
|
| 5 |
# modify it under the terms of the GNU General Public License |
|
| 6 |
# as published by the Free Software Foundation; either version 2 |
|
| 7 |
# of the License, or (at your option) any later version. |
|
| 8 |
# |
|
| 9 |
# This program is distributed in the hope that it will be useful, |
|
| 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
# GNU General Public License for more details. |
|
| 13 |
# |
|
| 14 |
# You should have received a copy of the GNU General Public License |
|
| 15 |
# along with this program; if not, write to the Free Software |
|
| 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 17 |
|
|
| 18 |
class ProjectCustomField < CustomField |
|
| 19 |
def type_name |
|
| 20 |
:label_project_plural |
|
| 21 |
end |
|
| 22 |
end |
|
| .svn/pristine/00/0081b5051789911922bdd0b18a28f0ad87c64e8d.svn-base | ||
|---|---|---|
| 1 |
<div class="contextual"> |
|
| 2 |
<%= link_to l(:label_tracker_new), new_tracker_path, :class => 'icon icon-add' %> |
|
| 3 |
<%= link_to l(:field_summary), fields_trackers_path, :class => 'icon icon-summary' %> |
|
| 4 |
</div> |
|
| 5 |
|
|
| 6 |
<h2><%=l(:label_tracker_plural)%></h2> |
|
| 7 |
|
|
| 8 |
<table class="list"> |
|
| 9 |
<thead><tr> |
|
| 10 |
<th><%=l(:label_tracker)%></th> |
|
| 11 |
<th></th> |
|
| 12 |
<th><%=l(:button_sort)%></th> |
|
| 13 |
<th></th> |
|
| 14 |
</tr></thead> |
|
| 15 |
<tbody> |
|
| 16 |
<% for tracker in @trackers %> |
|
| 17 |
<tr class="<%= cycle("odd", "even") %>">
|
|
| 18 |
<td><%= link_to h(tracker.name), edit_tracker_path(tracker) %></td> |
|
| 19 |
<td align="center"> |
|
| 20 |
<% unless tracker.workflow_rules.count > 0 %> |
|
| 21 |
<span class="icon icon-warning"> |
|
| 22 |
<%= l(:text_tracker_no_workflow) %> (<%= link_to l(:button_edit), workflows_edit_path(:tracker_id => tracker) %>) |
|
| 23 |
</span> |
|
| 24 |
<% end %> |
|
| 25 |
</td> |
|
| 26 |
<td align="center" style="width:15%;"> |
|
| 27 |
<%= reorder_links('tracker', {:action => 'update', :id => tracker}, :put) %>
|
|
| 28 |
</td> |
|
| 29 |
<td class="buttons"> |
|
| 30 |
<%= delete_link tracker_path(tracker) %> |
|
| 31 |
</td> |
|
| 32 |
</tr> |
|
| 33 |
<% end %> |
|
| 34 |
</tbody> |
|
| 35 |
</table> |
|
| 36 |
|
|
| 37 |
<p class="pagination"><%= pagination_links_full @tracker_pages %></p> |
|
| 38 |
|
|
| 39 |
<% html_title(l(:label_tracker_plural)) -%> |
|
| .svn/pristine/00/00bd76ee7194e922fe9340f2d39d910c9f79b20e.svn-base | ||
|---|---|---|
| 1 |
module ObjectHelpers |
|
| 2 |
def User.generate!(attributes={})
|
|
| 3 |
@generated_user_login ||= 'user0' |
|
| 4 |
@generated_user_login.succ! |
|
| 5 |
user = User.new(attributes) |
|
| 6 |
user.login = @generated_user_login.dup if user.login.blank? |
|
| 7 |
user.mail = "#{@generated_user_login}@example.com" if user.mail.blank?
|
|
| 8 |
user.firstname = "Bob" if user.firstname.blank? |
|
| 9 |
user.lastname = "Doe" if user.lastname.blank? |
|
| 10 |
yield user if block_given? |
|
| 11 |
user.save! |
|
| 12 |
user |
|
| 13 |
end |
|
| 14 |
|
|
| 15 |
def User.add_to_project(user, project, roles=nil) |
|
| 16 |
roles = Role.find(1) if roles.nil? |
|
| 17 |
roles = [roles] unless roles.is_a?(Array) |
|
| 18 |
Member.create!(:principal => user, :project => project, :roles => roles) |
|
| 19 |
end |
|
| 20 |
|
|
| 21 |
def Group.generate!(attributes={})
|
|
| 22 |
@generated_group_name ||= 'Group 0' |
|
| 23 |
@generated_group_name.succ! |
|
| 24 |
group = Group.new(attributes) |
|
| 25 |
group.name = @generated_group_name.dup if group.name.blank? |
|
| 26 |
yield group if block_given? |
|
| 27 |
group.save! |
|
| 28 |
group |
|
| 29 |
end |
|
| 30 |
|
|
| 31 |
def Project.generate!(attributes={})
|
|
| 32 |
@generated_project_identifier ||= 'project-0000' |
|
| 33 |
@generated_project_identifier.succ! |
|
| 34 |
project = Project.new(attributes) |
|
| 35 |
project.name = @generated_project_identifier.dup if project.name.blank? |
|
| 36 |
project.identifier = @generated_project_identifier.dup if project.identifier.blank? |
|
| 37 |
yield project if block_given? |
|
| 38 |
project.save! |
|
| 39 |
project |
|
| 40 |
end |
|
| 41 |
|
|
| 42 |
def Project.generate_with_parent!(parent, attributes={})
|
|
| 43 |
project = Project.generate!(attributes) |
|
| 44 |
project.set_parent!(parent) |
|
| 45 |
project |
|
| 46 |
end |
|
| 47 |
|
|
| 48 |
def Tracker.generate!(attributes={})
|
|
| 49 |
@generated_tracker_name ||= 'Tracker 0' |
|
| 50 |
@generated_tracker_name.succ! |
|
| 51 |
tracker = Tracker.new(attributes) |
|
| 52 |
tracker.name = @generated_tracker_name.dup if tracker.name.blank? |
|
| 53 |
yield tracker if block_given? |
|
| 54 |
tracker.save! |
|
| 55 |
tracker |
|
| 56 |
end |
|
| 57 |
|
|
| 58 |
def Role.generate!(attributes={})
|
|
| 59 |
@generated_role_name ||= 'Role 0' |
|
| 60 |
@generated_role_name.succ! |
|
| 61 |
role = Role.new(attributes) |
|
| 62 |
role.name = @generated_role_name.dup if role.name.blank? |
|
| 63 |
yield role if block_given? |
|
| 64 |
role.save! |
|
| 65 |
role |
|
| 66 |
end |
|
| 67 |
|
|
| 68 |
def Issue.generate!(attributes={})
|
|
| 69 |
issue = Issue.new(attributes) |
|
| 70 |
issue.project ||= Project.find(1) |
|
| 71 |
issue.tracker ||= issue.project.trackers.first |
|
| 72 |
issue.subject = 'Generated' if issue.subject.blank? |
|
| 73 |
issue.author ||= User.find(2) |
|
| 74 |
yield issue if block_given? |
|
| 75 |
issue.save! |
|
| 76 |
issue |
|
| 77 |
end |
|
| 78 |
|
|
| 79 |
# Generates an issue with 2 children and a grandchild |
|
| 80 |
def Issue.generate_with_descendants!(attributes={})
|
|
| 81 |
issue = Issue.generate!(attributes) |
|
| 82 |
child = Issue.generate!(:project => issue.project, :subject => 'Child1', :parent_issue_id => issue.id) |
|
| 83 |
Issue.generate!(:project => issue.project, :subject => 'Child2', :parent_issue_id => issue.id) |
|
| 84 |
Issue.generate!(:project => issue.project, :subject => 'Child11', :parent_issue_id => child.id) |
|
| 85 |
issue.reload |
|
| 86 |
end |
|
| 87 |
|
|
| 88 |
def Journal.generate!(attributes={})
|
|
| 89 |
journal = Journal.new(attributes) |
|
| 90 |
journal.user ||= User.first |
|
| 91 |
journal.journalized ||= Issue.first |
|
| 92 |
yield journal if block_given? |
|
| 93 |
journal.save! |
|
| 94 |
journal |
|
| 95 |
end |
|
| 96 |
|
|
| 97 |
def Version.generate!(attributes={})
|
|
| 98 |
@generated_version_name ||= 'Version 0' |
|
| 99 |
@generated_version_name.succ! |
|
| 100 |
version = Version.new(attributes) |
|
| 101 |
version.name = @generated_version_name.dup if version.name.blank? |
|
| 102 |
yield version if block_given? |
|
| 103 |
version.save! |
|
| 104 |
version |
|
| 105 |
end |
|
| 106 |
|
|
| 107 |
def TimeEntry.generate!(attributes={})
|
|
| 108 |
entry = TimeEntry.new(attributes) |
|
| 109 |
entry.user ||= User.find(2) |
|
| 110 |
entry.issue ||= Issue.find(1) unless entry.project |
|
| 111 |
entry.project ||= entry.issue.project |
|
| 112 |
entry.activity ||= TimeEntryActivity.first |
|
| 113 |
entry.spent_on ||= Date.today |
|
| 114 |
entry.hours ||= 1.0 |
|
| 115 |
entry.save! |
|
| 116 |
entry |
|
| 117 |
end |
|
| 118 |
|
|
| 119 |
def AuthSource.generate!(attributes={})
|
|
| 120 |
@generated_auth_source_name ||= 'Auth 0' |
|
| 121 |
@generated_auth_source_name.succ! |
|
| 122 |
source = AuthSource.new(attributes) |
|
| 123 |
source.name = @generated_auth_source_name.dup if source.name.blank? |
|
| 124 |
yield source if block_given? |
|
| 125 |
source.save! |
|
| 126 |
source |
|
| 127 |
end |
|
| 128 |
|
|
| 129 |
def Board.generate!(attributes={})
|
|
| 130 |
@generated_board_name ||= 'Forum 0' |
|
| 131 |
@generated_board_name.succ! |
|
| 132 |
board = Board.new(attributes) |
|
| 133 |
board.name = @generated_board_name.dup if board.name.blank? |
|
| 134 |
board.description = @generated_board_name.dup if board.description.blank? |
|
| 135 |
yield board if block_given? |
|
| 136 |
board.save! |
|
| 137 |
board |
|
| 138 |
end |
|
| 139 |
|
|
| 140 |
def Attachment.generate!(attributes={})
|
|
| 141 |
@generated_filename ||= 'testfile0' |
|
| 142 |
@generated_filename.succ! |
|
| 143 |
attributes = attributes.dup |
|
| 144 |
attachment = Attachment.new(attributes) |
|
| 145 |
attachment.container ||= Issue.find(1) |
|
| 146 |
attachment.author ||= User.find(2) |
|
| 147 |
attachment.filename = @generated_filename.dup if attachment.filename.blank? |
|
| 148 |
attachment.save! |
|
| 149 |
attachment |
|
| 150 |
end |
|
| 151 |
|
|
| 152 |
def CustomField.generate!(attributes={})
|
|
| 153 |
@generated_custom_field_name ||= 'Custom field 0' |
|
| 154 |
@generated_custom_field_name.succ! |
|
| 155 |
field = new(attributes) |
|
| 156 |
field.name = @generated_custom_field_name.dup if field.name.blank? |
|
| 157 |
field.field_format = 'string' if field.field_format.blank? |
|
| 158 |
yield field if block_given? |
|
| 159 |
field.save! |
|
| 160 |
field |
|
| 161 |
end |
|
| 162 |
end |
|
| .svn/pristine/00/00c1a9b51dc321ecb980f25b62c13dfa7fd628ff.svn-base | ||
|---|---|---|
| 1 |
<%= error_messages_for 'auth_source' %> |
|
| 2 |
|
|
| 3 |
<div class="box tabular"> |
|
| 4 |
<p><%= f.text_field :name, :required => true %></p> |
|
| 5 |
<p><%= f.text_field :host, :required => true %></p> |
|
| 6 |
<p><%= f.text_field :port, :required => true, :size => 6 %> <%= f.check_box :tls, :no_label => true %> LDAPS</p> |
|
| 7 |
<p><%= f.text_field :account %></p> |
|
| 8 |
<p><%= f.password_field :account_password, :label => :field_password, |
|
| 9 |
:name => 'dummy_password', |
|
| 10 |
:value => ((@auth_source.new_record? || @auth_source.account_password.blank?) ? '' : ('x'*15)),
|
|
| 11 |
:onfocus => "this.value=''; this.name='auth_source[account_password]';", |
|
| 12 |
:onchange => "this.name='auth_source[account_password]';" %></p> |
|
| 13 |
<p><%= f.text_field :base_dn, :required => true, :size => 60 %></p> |
|
| 14 |
<p><%= f.text_field :filter, :size => 60, :label => :field_auth_source_ldap_filter %></p> |
|
| 15 |
<p><%= f.text_field :timeout, :size => 4 %></p> |
|
| 16 |
<p><%= f.check_box :onthefly_register, :label => :field_onthefly %></p> |
|
| 17 |
</div> |
|
| 18 |
|
|
| 19 |
<fieldset class="box tabular"><legend><%=l(:label_attribute_plural)%></legend> |
|
| 20 |
<p><%= f.text_field :attr_login, :required => true, :size => 20 %></p> |
|
| 21 |
<p><%= f.text_field :attr_firstname, :size => 20 %></p> |
|
| 22 |
<p><%= f.text_field :attr_lastname, :size => 20 %></p> |
|
| 23 |
<p><%= f.text_field :attr_mail, :size => 20 %></p> |
|
| 24 |
</fieldset> |
|
| .svn/pristine/00/00c4bd6691f32db8720a826db98aecc930f926d9.svn-base | ||
|---|---|---|
| 1 |
# $Id: entry.rb 123 2006-05-18 03:52:38Z blackhedd $ |
|
| 2 |
# |
|
| 3 |
# LDAP Entry (search-result) support classes |
|
| 4 |
# |
|
| 5 |
# |
|
| 6 |
#---------------------------------------------------------------------------- |
|
| 7 |
# |
|
| 8 |
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved. |
|
| 9 |
# |
|
| 10 |
# Gmail: garbagecat10 |
|
| 11 |
# |
|
| 12 |
# This program is free software; you can redistribute it and/or modify |
|
| 13 |
# it under the terms of the GNU General Public License as published by |
|
| 14 |
# the Free Software Foundation; either version 2 of the License, or |
|
| 15 |
# (at your option) any later version. |
|
| 16 |
# |
|
| 17 |
# This program is distributed in the hope that it will be useful, |
|
| 18 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 19 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 20 |
# GNU General Public License for more details. |
|
| 21 |
# |
|
| 22 |
# You should have received a copy of the GNU General Public License |
|
| 23 |
# along with this program; if not, write to the Free Software |
|
| 24 |
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
| 25 |
# |
|
| 26 |
#--------------------------------------------------------------------------- |
|
| 27 |
# |
|
| 28 |
|
|
| 29 |
|
|
| 30 |
|
|
| 31 |
|
|
| 32 |
module Net |
|
| 33 |
class LDAP |
|
| 34 |
|
|
| 35 |
|
|
| 36 |
# Objects of this class represent individual entries in an LDAP |
|
| 37 |
# directory. User code generally does not instantiate this class. |
|
| 38 |
# Net::LDAP#search provides objects of this class to user code, |
|
| 39 |
# either as block parameters or as return values. |
|
| 40 |
# |
|
| 41 |
# In LDAP-land, an "entry" is a collection of attributes that are |
|
| 42 |
# uniquely and globally identified by a DN ("Distinguished Name").
|
|
| 43 |
# Attributes are identified by short, descriptive words or phrases. |
|
| 44 |
# Although a directory is |
|
| 45 |
# free to implement any attribute name, most of them follow rigorous |
|
| 46 |
# standards so that the range of commonly-encountered attribute |
|
| 47 |
# names is not large. |
|
| 48 |
# |
|
| 49 |
# An attribute name is case-insensitive. Most directories also |
|
| 50 |
# restrict the range of characters allowed in attribute names. |
|
| 51 |
# To simplify handling attribute names, Net::LDAP::Entry |
|
| 52 |
# internally converts them to a standard format. Therefore, the |
|
| 53 |
# methods which take attribute names can take Strings or Symbols, |
|
| 54 |
# and work correctly regardless of case or capitalization. |
|
| 55 |
# |
|
| 56 |
# An attribute consists of zero or more data items called |
|
| 57 |
# <i>values.</i> An entry is the combination of a unique DN, a set of attribute |
|
| 58 |
# names, and a (possibly-empty) array of values for each attribute. |
|
| 59 |
# |
|
| 60 |
# Class Net::LDAP::Entry provides convenience methods for dealing |
|
| 61 |
# with LDAP entries. |
|
| 62 |
# In addition to the methods documented below, you may access individual |
|
| 63 |
# attributes of an entry simply by giving the attribute name as |
|
| 64 |
# the name of a method call. For example: |
|
| 65 |
# ldap.search( ... ) do |entry| |
|
| 66 |
# puts "Common name: #{entry.cn}"
|
|
| 67 |
# puts "Email addresses:" |
|
| 68 |
# entry.mail.each {|ma| puts ma}
|
|
| 69 |
# end |
|
| 70 |
# If you use this technique to access an attribute that is not present |
|
| 71 |
# in a particular Entry object, a NoMethodError exception will be raised. |
|
| 72 |
# |
|
| 73 |
#-- |
|
| 74 |
# Ugly problem to fix someday: We key off the internal hash with |
|
| 75 |
# a canonical form of the attribute name: convert to a string, |
|
| 76 |
# downcase, then take the symbol. Unfortunately we do this in |
|
| 77 |
# at least three places. Should do it in ONE place. |
|
| 78 |
class Entry |
|
| 79 |
|
|
| 80 |
# This constructor is not generally called by user code. |
|
| 81 |
def initialize dn = nil # :nodoc: |
|
| 82 |
@myhash = Hash.new {|k,v| k[v] = [] }
|
|
| 83 |
@myhash[:dn] = [dn] |
|
| 84 |
end |
|
| 85 |
|
|
| 86 |
|
|
| 87 |
def []= name, value # :nodoc: |
|
| 88 |
sym = name.to_s.downcase.intern |
|
| 89 |
@myhash[sym] = value |
|
| 90 |
end |
|
| 91 |
|
|
| 92 |
|
|
| 93 |
#-- |
|
| 94 |
# We have to deal with this one as we do with []= |
|
| 95 |
# because this one and not the other one gets called |
|
| 96 |
# in formulations like entry["CN"] << cn. |
|
| 97 |
# |
|
| 98 |
def [] name # :nodoc: |
|
| 99 |
name = name.to_s.downcase.intern unless name.is_a?(Symbol) |
|
| 100 |
@myhash[name] |
|
| 101 |
end |
|
| 102 |
|
|
| 103 |
# Returns the dn of the Entry as a String. |
|
| 104 |
def dn |
|
| 105 |
self[:dn][0] |
|
| 106 |
end |
|
| 107 |
|
|
| 108 |
# Returns an array of the attribute names present in the Entry. |
|
| 109 |
def attribute_names |
|
| 110 |
@myhash.keys |
|
| 111 |
end |
|
| 112 |
|
|
| 113 |
# Accesses each of the attributes present in the Entry. |
|
| 114 |
# Calls a user-supplied block with each attribute in turn, |
|
| 115 |
# passing two arguments to the block: a Symbol giving |
|
| 116 |
# the name of the attribute, and a (possibly empty) |
|
| 117 |
# Array of data values. |
|
| 118 |
# |
|
| 119 |
def each |
|
| 120 |
if block_given? |
|
| 121 |
attribute_names.each {|a|
|
|
| 122 |
attr_name,values = a,self[a] |
|
| 123 |
yield attr_name, values |
|
| 124 |
} |
|
| 125 |
end |
|
| 126 |
end |
|
| 127 |
|
|
| 128 |
alias_method :each_attribute, :each |
|
| 129 |
|
|
| 130 |
|
|
| 131 |
#-- |
|
| 132 |
# Convenience method to convert unknown method names |
|
| 133 |
# to attribute references. Of course the method name |
|
| 134 |
# comes to us as a symbol, so let's save a little time |
|
| 135 |
# and not bother with the to_s.downcase two-step. |
|
| 136 |
# Of course that means that a method name like mAIL |
|
| 137 |
# won't work, but we shouldn't be encouraging that |
|
| 138 |
# kind of bad behavior in the first place. |
|
| 139 |
# Maybe we should thow something if the caller sends |
|
| 140 |
# arguments or a block... |
|
| 141 |
# |
|
| 142 |
def method_missing *args, &block # :nodoc: |
|
| 143 |
s = args[0].to_s.downcase.intern |
|
| 144 |
if attribute_names.include?(s) |
|
| 145 |
self[s] |
|
| 146 |
elsif s.to_s[-1] == 61 and s.to_s.length > 1 |
|
| 147 |
value = args[1] or raise RuntimeError.new( "unable to set value" ) |
|
| 148 |
value = [value] unless value.is_a?(Array) |
|
| 149 |
name = s.to_s[0..-2].intern |
|
| 150 |
self[name] = value |
|
| 151 |
else |
|
| 152 |
raise NoMethodError.new( "undefined method '#{s}'" )
|
|
| 153 |
end |
|
| 154 |
end |
|
| 155 |
|
|
| 156 |
def write |
|
| 157 |
end |
|
| 158 |
|
|
| 159 |
end # class Entry |
|
| 160 |
|
|
| 161 |
|
|
| 162 |
end # class LDAP |
|
| 163 |
end # module Net |
|
| 164 |
|
|
| 165 |
|
|
Also available in: Unified diff