diff --git a/app/assets/stylesheets/specific/user_feedback.css.scss b/app/assets/stylesheets/specific/user_feedback.css.scss
index abf100c9f..3495f1023 100644
--- a/app/assets/stylesheets/specific/user_feedback.css.scss
+++ b/app/assets/stylesheets/specific/user_feedback.css.scss
@@ -1,9 +1,9 @@
div#c-user-feedbacks {
- tr.feedback-category-positive {
+ .feedback-category-positive {
background: #DDFFDD !important;
}
- tr.feedback-category-negative {
+ .feedback-category-negative {
background: #FFDDDD !important;
}
}
\ No newline at end of file
diff --git a/app/assets/stylesheets/specific/user_name_change_requests.css.scss b/app/assets/stylesheets/specific/user_name_change_requests.css.scss
new file mode 100644
index 000000000..bfacee695
--- /dev/null
+++ b/app/assets/stylesheets/specific/user_name_change_requests.css.scss
@@ -0,0 +1,31 @@
+#c-user-name-change-requests {
+ .feedback-category-positive {
+ background: #DDFFDD !important;
+ }
+
+ .feedback-category-negative {
+ background: #FFDDDD !important;
+ }
+
+ li {
+ margin-bottom: 1em;
+ }
+
+ form {
+ margin-bottom: 2em;
+ }
+
+ p {
+ margin: 0;
+ }
+
+ p.author {
+ font-size: 80%;
+ font-style: italic;
+ color: #AAA;
+ }
+
+ section {
+ margin-bottom: 1em;
+ }
+}
\ No newline at end of file
diff --git a/app/controllers/user_name_change_requests_controller.rb b/app/controllers/user_name_change_requests_controller.rb
new file mode 100644
index 000000000..334112c88
--- /dev/null
+++ b/app/controllers/user_name_change_requests_controller.rb
@@ -0,0 +1,38 @@
+class UserNameChangeRequestsController < ApplicationController
+ before_filter :member_only, :only => [:new, :create, :show]
+ before_filter :admin_only, :only => [:index, :approve, :reject]
+
+ def new
+ end
+
+ def create
+ @change_request = UserNameChangeRequest.create(
+ :user_id => CurrentUser.user.id,
+ :original_name => CurrentUser.user.name,
+ :status => "pending",
+ :change_reason => params[:reason],
+ :desired_name => params[:desired_name]
+ )
+ redirect_to user_name_change_request_path(@change_request), :notice => "Your request has been submitted and is pending admin review"
+ end
+
+ def show
+ @change_request = UserNameChangeRequest.find(params[:id])
+ end
+
+ def index
+ @change_requests = UserNameChangeRequest.order("id desc").paginate(params[:page])
+ end
+
+ def approve
+ @change_request = UserNameChangeRequest.find(params[:id])
+ @change_request.approve!
+ redirect_to user_name_change_request_path(@change_request), :notice => "Name change request approved"
+ end
+
+ def reject
+ @change_request = UserNameChangeRequest.find(params[:id])
+ @change_request.reject!(params[:reason])
+ redirect_to user_name_change_request_path(@change_request), :notice => "Name change request rejected"
+ end
+end
diff --git a/app/models/tag_alias.rb b/app/models/tag_alias.rb
index bef397702..c185c3b5f 100644
--- a/app/models/tag_alias.rb
+++ b/app/models/tag_alias.rb
@@ -3,6 +3,7 @@ class TagAlias < ActiveRecord::Base
after_save :clear_all_cache
after_destroy :clear_all_cache
before_validation :initialize_creator, :on => :create
+ before_validation :normalize_names
validates_presence_of :creator_id, :antecedent_name, :consequent_name
validates_uniqueness_of :antecedent_name
validate :absence_of_transitive_relation
@@ -88,6 +89,11 @@ class TagAlias < ActiveRecord::Base
def is_active?
status == "active"
end
+
+ def normalize_names
+ self.antecedent_name = antecedent_name.mb_chars.downcase.tr(" ", "_").strip
+ self.consequent_name = consequent_name.downcase.tr(" ", "_").strip
+ end
def initialize_creator
self.creator_id = CurrentUser.user.id
diff --git a/app/models/tag_implication.rb b/app/models/tag_implication.rb
index 3384386b2..fb2948bcf 100644
--- a/app/models/tag_implication.rb
+++ b/app/models/tag_implication.rb
@@ -3,6 +3,7 @@ class TagImplication < ActiveRecord::Base
after_save :update_descendant_names_for_parent
belongs_to :creator, :class_name => "User"
before_validation :initialize_creator, :on => :create
+ before_validation :normalize_names
validates_presence_of :creator_id, :antecedent_name, :consequent_name
validates_uniqueness_of :antecedent_name, :scope => :consequent_name
validate :absence_of_circular_relation
@@ -129,6 +130,11 @@ class TagImplication < ActiveRecord::Base
end
end
end
+
+ def normalize_names
+ self.antecedent_name = antecedent_name.downcase.tr(" ", "_").strip
+ self.consequent_name = consequent_name.downcase.tr(" ", "_").strip
+ end
def is_pending?
status == "pending"
diff --git a/app/models/user.rb b/app/models/user.rb
index c86cb3300..ddc8627de 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -531,7 +531,7 @@ class User < ActiveRecord::Base
end
def admins
- where("is_admin = TRUE")
+ where("level = ?", Levels::ADMIN)
end
def with_email(email)
diff --git a/app/models/user_name_change_request.rb b/app/models/user_name_change_request.rb
new file mode 100644
index 000000000..6fd271077
--- /dev/null
+++ b/app/models/user_name_change_request.rb
@@ -0,0 +1,48 @@
+class UserNameChangeRequest < ActiveRecord::Base
+ validates_presence_of :user_id, :original_name, :desired_name
+ validates_inclusion_of :status, :in => %w(pending approved rejected)
+ belongs_to :user
+ belongs_to :approver, :class_name => "User"
+ validate :uniqueness_of_desired_name
+ validates_length_of :desired_name, :within => 2..100, :on => :create
+ validates_format_of :desired_name, :with => /\A[^\s:]+\Z/, :on => :create, :message => "cannot have whitespace or colons"
+ after_create :notify_admins
+
+ def self.pending
+ where(:status => "pending")
+ end
+
+ def feedback
+ UserFeedback.for_user(user_id).order("id desc").all
+ end
+
+ def notify_admins
+ title = "#{original_name} is requesting a name change to #{desired_name}"
+ body = title + "\n\n\"See request\":/user_name_change_requests/#{id}"
+ User.admins.find_each do |user|
+ Dmail.create_split(:title => title, :body => body, :to_id => user.id)
+ end
+ end
+
+ def approve!
+ update_attribute(:status, "approved")
+ user.update_attribute(:name, desired_name)
+ body = "Your name change request has been approved. Be sure to log in with your new user name."
+ Dmail.create_split(:title => "Name change request approved", :body => body, :to_id => user_id)
+ end
+
+ def reject!(reason)
+ update_attributes(:status => "rejected", :rejection_reason => reason)
+ body = "Your name change request has been rejected for the following reason: #{rejection_reason}"
+ Dmail.create_split(:title => "Name change request rejected", :body => body, :to_id => user_id)
+ end
+
+ def uniqueness_of_desired_name
+ if User.find_by_name(desired_name)
+ errors.add(:desired_name, "already exists")
+ return false
+ else
+ return true
+ end
+ end
+end
diff --git a/app/views/user_name_change_requests/new.html.erb b/app/views/user_name_change_requests/new.html.erb
new file mode 100644
index 000000000..c112e827e
--- /dev/null
+++ b/app/views/user_name_change_requests/new.html.erb
@@ -0,0 +1,21 @@
+
Name Change Request
+
+
You can request a name change but it must be approved. Factors that go into consideration include your upload and update history, and your user feedback.
+<% end %>
\ No newline at end of file
diff --git a/app/views/user_name_change_requests/show.html.erb b/app/views/user_name_change_requests/show.html.erb
new file mode 100644
index 000000000..9f1d9cd78
--- /dev/null
+++ b/app/views/user_name_change_requests/show.html.erb
@@ -0,0 +1,56 @@
+
+
Name Change Request
+
+
+
<%= @change_request.original_name %> is requesting to change their name to <%= @change_request.desired_name %>.
+
+
+
+
Reason
+
<%= @change_request.change_reason %>
+
+
+
+
Feedback
+
+ <% @change_request.feedback.each do |feedback| %>
+
+
<%= feedback.body %>
+
Submitted by <%= feedback.creator.name %> <%= time_ago_in_words_tagged feedback.created_at %>