summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2013-06-13 18:09:26 +0000
committerDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>2013-06-13 18:09:26 +0000
commit313ac55539ab93110d070e17811480092d55d8ce (patch)
tree924ebbb3a13ebf107fda9c310573de1716c24217
parentcfd15eb480973e5206c83dc4f2ed18781d78f7e0 (diff)
parent6838304a85cd3b5dfdac076c600cb15f5643c674 (diff)
downloadgitlab-ce-313ac55539ab93110d070e17811480092d55d8ce.tar.gz
Merge branch 'feature/password_expire' of /home/git/repositories/gitlab/gitlabhq
-rw-r--r--app/controllers/admin/users_controller.rb8
-rw-r--r--app/controllers/application_controller.rb7
-rw-r--r--app/controllers/passwords_controller.rb38
-rw-r--r--app/models/user.rb11
-rw-r--r--app/views/admin/users/_form.html.haml30
-rw-r--r--app/views/admin/users/show.html.haml112
-rw-r--r--app/views/notify/new_user_email.html.haml9
-rw-r--r--app/views/notify/new_user_email.text.erb5
-rw-r--r--app/views/passwords/new.html.haml22
-rw-r--r--config/routes.rb1
-rw-r--r--db/fixtures/production/001_admin.rb3
-rw-r--r--db/migrate/20130613165816_add_password_expires_at_to_users.rb5
-rw-r--r--db/migrate/20130613173246_add_created_by_id_to_user.rb5
-rw-r--r--db/schema.rb4
-rw-r--r--spec/features/admin/admin_users_spec.rb18
15 files changed, 199 insertions, 79 deletions
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 185ad181b2a..ec3209fdfe2 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -55,8 +55,14 @@ class Admin::UsersController < Admin::ApplicationController
def create
admin = params[:user].delete("admin")
- @admin_user = User.new(params[:user], as: :admin)
+ opts = {
+ force_random_password: true,
+ password_expires_at: Time.now
+ }
+
+ @admin_user = User.new(params[:user].merge(opts), as: :admin)
@admin_user.admin = (admin && admin.to_i > 0)
+ @admin_user.created_by_id = current_user.id
respond_to do |format|
if @admin_user.save
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 09af5b94164..fda05feefc0 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -1,6 +1,7 @@
class ApplicationController < ActionController::Base
before_filter :authenticate_user!
before_filter :reject_blocked!
+ before_filter :check_password_expiration
before_filter :set_current_user_for_thread
before_filter :add_abilities
before_filter :dev_tools if Rails.env == 'development'
@@ -156,4 +157,10 @@ class ApplicationController < ActionController::Base
gon.gravatar_url = request.ssl? || Gitlab.config.gitlab.https ? Gitlab.config.gravatar.ssl_url : Gitlab.config.gravatar.plain_url
gon.relative_url_root = Gitlab.config.gitlab.relative_url_root
end
+
+ def check_password_expiration
+ if current_user && current_user.password_expires_at && current_user.password_expires_at < Time.now
+ redirect_to new_profile_password_path and return
+ end
+ end
end
diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb
new file mode 100644
index 00000000000..0e5b42178a7
--- /dev/null
+++ b/app/controllers/passwords_controller.rb
@@ -0,0 +1,38 @@
+class PasswordsController < ApplicationController
+ layout 'navless'
+
+ skip_before_filter :check_password_expiration
+
+ before_filter :set_user
+ before_filter :set_title
+
+ def new
+ end
+
+ def create
+ new_password = params[:user][:password]
+ new_password_confirmation = params[:user][:password_confirmation]
+
+ result = @user.update_attributes(
+ password: new_password,
+ password_confirmation: new_password_confirmation
+ )
+
+ if result
+ @user.update_attributes(password_expires_at: nil)
+ redirect_to root_path, notice: 'Password successfully changed'
+ else
+ render :new
+ end
+ end
+
+ private
+
+ def set_user
+ @user = current_user
+ end
+
+ def set_title
+ @title = "New password"
+ end
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index 0a3a40b994c..6de8d2d4c39 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -42,8 +42,11 @@ class User < ActiveRecord::Base
attr_accessible :email, :password, :password_confirmation, :remember_me, :bio, :name, :username,
:skype, :linkedin, :twitter, :color_scheme_id, :theme_id, :force_random_password,
- :extern_uid, :provider, as: [:default, :admin]
- attr_accessible :projects_limit, :can_create_team, :can_create_group, as: :admin
+ :extern_uid, :provider, :password_expires_at,
+ as: [:default, :admin]
+
+ attr_accessible :projects_limit, :can_create_team, :can_create_group,
+ as: :admin
attr_accessor :force_random_password
@@ -364,4 +367,8 @@ class User < ActiveRecord::Base
def accessible_deploy_keys
DeployKey.in_projects(self.master_projects).uniq
end
+
+ def created_by
+ User.find_by_id(created_by_id) if created_by_id
+ end
end
diff --git a/app/views/admin/users/_form.html.haml b/app/views/admin/users/_form.html.haml
index 9bde50f8947..fdf37965091 100644
--- a/app/views/admin/users/_form.html.haml
+++ b/app/views/admin/users/_form.html.haml
@@ -24,19 +24,25 @@
= f.text_field :email, required: true, autocomplete: "off"
%span.help-inline * required
- %fieldset
- %legend Password
- .clearfix
- = f.label :password
- .input= f.password_field :password, disabled: f.object.force_random_password
- .clearfix
- = f.label :password_confirmation
- .input= f.password_field :password_confirmation, disabled: f.object.force_random_password
- -if f.object.new_record?
+ - if @admin_user.new_record?
+ %fieldset
+ %legend Password
+ .clearfix
+ = f.label :password
+ .input
+ %strong
+ A temporary password will be generated and sent to user.
+ %br
+ User will be forced to change it after first sign in
+ - else
+ %fieldset
+ %legend Password
+ .clearfix
+ = f.label :password
+ .input= f.password_field :password, disabled: f.object.force_random_password
.clearfix
- = f.label :force_random_password do
- %span Generate random password
- .input= f.check_box :force_random_password, {}, true, nil
+ = f.label :password_confirmation
+ .input= f.password_field :password_confirmation, disabled: f.object.force_random_password
%fieldset
%legend Access
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index 6709b8f8a6b..1b5340d687d 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -1,32 +1,65 @@
+%h3.page_title
+ User:
+ = @admin_user.name
+ - if @admin_user.blocked?
+ %span.cred (Blocked)
+ - if @admin_user.admin
+ %span.cred (Admin)
+
+ .pull-right
+ = link_to edit_admin_user_path(@admin_user), class: "btn grouped btn-small" do
+ %i.icon-edit
+ Edit
+ - unless @admin_user == current_user
+ - if @admin_user.blocked?
+ = link_to 'Unblock', unblock_admin_user_path(@admin_user), method: :put, class: "btn grouped btn-small success"
+ - else
+ = link_to 'Block', block_admin_user_path(@admin_user), confirm: 'USER WILL BE BLOCKED! Are you sure?', method: :put, class: "btn grouped btn-small btn-remove"
+ = link_to 'Destroy', [:admin, @admin_user], confirm: "USER #{@admin_user.name} WILL BE REMOVED! Are you sure?", method: :delete, class: "btn grouped btn-small btn-remove"
+%hr
+
.row
.span6
- %h3.page_title
- = image_tag gravatar_icon(@admin_user.email, 90), class: "avatar s90"
- = @admin_user.name
- - if @admin_user.blocked?
- %span.cred (Blocked)
- - if @admin_user.admin
- %span.cred (Admin)
- .pull-right
- = link_to edit_admin_user_path(@admin_user), class: "btn pull-right" do
- %i.icon-edit
- Edit
- %br
- %small @#{@admin_user.username}
- %br
- %small member since #{@admin_user.created_at.stamp("Nov 12, 2031")}
- .clearfix
- %hr
- %p
- %span.btn.btn-small
- %i.icon-envelope
- = mail_to @admin_user.email
- - unless @admin_user == current_user
- - if @admin_user.blocked?
- = link_to 'Unblock', unblock_admin_user_path(@admin_user), method: :put, class: "btn btn-small success"
- - else
- = link_to 'Block', block_admin_user_path(@admin_user), confirm: 'USER WILL BE BLOCKED! Are you sure?', method: :put, class: "btn btn-small btn-remove"
- = link_to 'Destroy', [:admin, @admin_user], confirm: "USER #{@admin_user.name} WILL BE REMOVED! Are you sure?", method: :delete, class: "btn btn-small btn-remove"
+ .ui-box
+ %h5.title
+ Account:
+ .pull-right
+ = image_tag gravatar_icon(@admin_user.email, 32), class: "avatar s32"
+ %ul.well-list
+ %li
+ %span.light Name:
+ %strong= @admin_user.name
+ %li
+ %span.light Username:
+ %strong
+ = @admin_user.username
+ %li
+ %span.light Email:
+ %strong
+ = mail_to @admin_user.email
+
+ %li
+ %span.light Member since:
+ %strong
+ = @admin_user.created_at.stamp("Nov 12, 2031")
+
+ %li
+ %span.light Last sign-in at:
+ %strong
+ = @admin_user.last_sign_in_at.stamp("Nov 12, 2031")
+
+ - if @admin_user.ldap_user?
+ %li
+ %span.light LDAP uid:
+ %strong
+ = @admin_user.extern_uid
+
+ - if @admin_user.created_by
+ %li
+ %span.light Created by:
+ %strong
+ = link_to @admin_user.created_by.name, [:admin, @admin_user.created_by]
+
%hr
%h5
Add User to Projects
@@ -67,11 +100,11 @@
.span6
- = render 'users/profile', user: @admin_user
.ui-box
%h5.title Projects (#{@projects.count})
%ul.well-list
- @projects.sort_by(&:name_with_namespace).each do |project|
+ - tm = project.team.get_tm(@admin_user.id)
%li
= link_to admin_project_path(project), class: dom_class(project) do
- if project.namespace
@@ -79,16 +112,17 @@
\/
%strong.well-title
= truncate(project.name, length: 45)
- %span.pull-right.light
- - if project.owner == @admin_user
- %i.icon-wrench
- - tm = project.team.get_tm(@admin_user.id)
- - if tm
- = tm.project_access_human
- = link_to edit_admin_project_member_path(project, tm.user), class: "btn btn-small" do
+
+ - if project.owner == @admin_user
+ %span.label.label-info owner
+
+ - if tm
+ .pull-right
+ = link_to edit_admin_project_member_path(project, tm.user), class: "btn grouped btn-small" do
%i.icon-edit
- = link_to admin_project_member_path(project, tm.user), confirm: remove_from_project_team_message(project, @admin_user), method: :delete, class: "btn btn-small btn-remove" do
+ = link_to admin_project_member_path(project, tm.user), confirm: remove_from_project_team_message(project, @admin_user), method: :delete, class: "btn grouped btn-small btn-remove" do
%i.icon-remove
- %p.light
- %i.icon-wrench
- &ndash; user is a project owner
+
+ .pull-right.light
+ = tm.project_access_human
+ &nbsp;
diff --git a/app/views/notify/new_user_email.html.haml b/app/views/notify/new_user_email.html.haml
index 9804fbdd51e..fc2c02ef827 100644
--- a/app/views/notify/new_user_email.html.haml
+++ b/app/views/notify/new_user_email.html.haml
@@ -8,13 +8,14 @@
%p
login..........................................
%code= @user['email']
-%p
- - unless Gitlab.config.gitlab.signup_enabled
+
+- if @user.created_by_id
+ %p
password..................................
%code= @password
-%p
- Please change your password immediately after login.
+ %p
+ You will be forced to change this password immediately after login.
%p
= link_to "Click here to login", root_url
diff --git a/app/views/notify/new_user_email.text.erb b/app/views/notify/new_user_email.text.erb
index 777930a2803..70fe0e0736a 100644
--- a/app/views/notify/new_user_email.text.erb
+++ b/app/views/notify/new_user_email.text.erb
@@ -3,10 +3,11 @@ Hi <%= @user.name %>!
The Administrator created an account for you. Now you are a member of company GitLab application.
login.................. <%= @user.email %>
-<% unless Gitlab.config.gitlab.signup_enabled %>
+<% if @user.created_by_id %>
password............... <%= @password %>
+
+ You will be forced to change this password immediately after login.
<% end %>
-Please change your password immediately after login.
Click here to login: <%= url_for(root_url) %>
diff --git a/app/views/passwords/new.html.haml b/app/views/passwords/new.html.haml
new file mode 100644
index 00000000000..c92424160b3
--- /dev/null
+++ b/app/views/passwords/new.html.haml
@@ -0,0 +1,22 @@
+= form_for @user, url: profile_password_path, method: :post do |f|
+ .light-well.padded
+ %p.slead
+ Please set new password before proceed.
+ %br
+ After successful password update you will be redirected to login screen
+ -if @user.errors.any?
+ .alert.alert-error
+ %ul
+ - @user.errors.full_messages.each do |msg|
+ %li= msg
+
+ .clearfix
+ = f.label :password
+ .input= f.password_field :password, required: true
+ .clearfix
+ = f.label :password_confirmation
+ .input
+ = f.password_field :password_confirmation, required: true
+ .clearfix
+ .input
+ = f.submit 'Set new password', class: "btn btn-create"
diff --git a/config/routes.rb b/config/routes.rb
index 6f72e2cb186..39c79635c40 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -123,6 +123,7 @@ Gitlab::Application.routes.draw do
end
resource :notifications
+ resource :password
end
resources :keys
diff --git a/db/fixtures/production/001_admin.rb b/db/fixtures/production/001_admin.rb
index f119694d11d..632f6107b33 100644
--- a/db/fixtures/production/001_admin.rb
+++ b/db/fixtures/production/001_admin.rb
@@ -3,7 +3,8 @@ admin = User.create(
name: "Administrator",
username: 'root',
password: "5iveL!fe",
- password_confirmation: "5iveL!fe"
+ password_confirmation: "5iveL!fe",
+ password_expires_at: Time.now
)
admin.projects_limit = 10000
diff --git a/db/migrate/20130613165816_add_password_expires_at_to_users.rb b/db/migrate/20130613165816_add_password_expires_at_to_users.rb
new file mode 100644
index 00000000000..3479c8e64d0
--- /dev/null
+++ b/db/migrate/20130613165816_add_password_expires_at_to_users.rb
@@ -0,0 +1,5 @@
+class AddPasswordExpiresAtToUsers < ActiveRecord::Migration
+ def change
+ add_column :users, :password_expires_at, :datetime
+ end
+end
diff --git a/db/migrate/20130613173246_add_created_by_id_to_user.rb b/db/migrate/20130613173246_add_created_by_id_to_user.rb
new file mode 100644
index 00000000000..615e96eb156
--- /dev/null
+++ b/db/migrate/20130613173246_add_created_by_id_to_user.rb
@@ -0,0 +1,5 @@
+class AddCreatedByIdToUser < ActiveRecord::Migration
+ def change
+ add_column :users, :created_by_id, :integer
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 21e553dd612..bec32c1d52a 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20130522141856) do
+ActiveRecord::Schema.define(:version => 20130613173246) do
create_table "deploy_keys_projects", :force => true do |t|
t.integer "deploy_key_id", :null => false
@@ -292,6 +292,8 @@ ActiveRecord::Schema.define(:version => 20130522141856) do
t.string "state"
t.integer "color_scheme_id", :default => 1, :null => false
t.integer "notification_level", :default => 1, :null => false
+ t.datetime "password_expires_at"
+ t.integer "created_by_id"
end
add_index "users", ["admin"], :name => "index_users_on_admin"
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
index bec43e5029c..15de101a17a 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/admin_users_spec.rb
@@ -20,13 +20,10 @@ describe "Admin::Users" do
describe "GET /admin/users/new" do
before do
- @password = "123ABC"
visit new_admin_user_path
fill_in "user_name", with: "Big Bang"
fill_in "user_username", with: "bang"
fill_in "user_email", with: "bigbang@mail.com"
- fill_in "user_password", with: @password
- fill_in "user_password_confirmation", with: @password
end
it "should create new user" do
@@ -57,26 +54,13 @@ describe "Admin::Users" do
end
it "should send valid email to user with email & password" do
- Gitlab.config.gitlab.stub(:signup_enabled).and_return(false)
User.observers.enable :user_observer do
click_button "Create user"
user = User.last
email = ActionMailer::Base.deliveries.last
email.subject.should have_content("Account was created")
email.text_part.body.should have_content(user.email)
- email.text_part.body.should have_content(@password)
- end
- end
-
- it "should send valid email to user with email without password when signup is enabled" do
- Gitlab.config.gitlab.stub(:signup_enabled).and_return(true)
- User.observers.enable :user_observer do
- click_button "Create user"
- user = User.last
- email = ActionMailer::Base.deliveries.last
- email.subject.should have_content("Account was created")
- email.text_part.body.should have_content(user.email)
- email.text_part.body.should_not have_content(@password)
+ email.text_part.body.should have_content('password')
end
end
end