Commit c9f741bb07bac1722dcbfeb909acd4ed49d1d1ae

Authored by Dmitriy Zaporozhets
2 parents fc6ed495 88d4559e

Merge pull request #4743 from karlhungus/feature-users-api-respect-defaults

Update User api to respect default settings
app/controllers/admin/users_controller.rb
@@ -13,7 +13,7 @@ class Admin::UsersController < Admin::ApplicationController @@ -13,7 +13,7 @@ class Admin::UsersController < Admin::ApplicationController
13 end 13 end
14 14
15 def new 15 def new
16 - @user = User.new.with_defaults 16 + @user = User.build_user
17 end 17 end
18 18
19 def edit 19 def edit
@@ -44,7 +44,7 @@ class Admin::UsersController < Admin::ApplicationController @@ -44,7 +44,7 @@ class Admin::UsersController < Admin::ApplicationController
44 password_expires_at: Time.now 44 password_expires_at: Time.now
45 } 45 }
46 46
47 - @user = User.new(params[:user].merge(opts), as: :admin) 47 + @user = User.build_user(params[:user].merge(opts), as: :admin)
48 @user.admin = (admin && admin.to_i > 0) 48 @user.admin = (admin && admin.to_i > 0)
49 @user.created_by_id = current_user.id 49 @user.created_by_id = current_user.id
50 50
app/models/user.rb
@@ -198,6 +198,21 @@ class User < ActiveRecord::Base @@ -198,6 +198,21 @@ class User < ActiveRecord::Base
198 User.find_by_username(name_or_id) 198 User.find_by_username(name_or_id)
199 end 199 end
200 end 200 end
  201 +
  202 + def build_user(attrs = {}, options= {})
  203 + user = User.new(defaults.merge(attrs), options)
  204 + # if not as: :admin force default settings
  205 + user.with_defaults unless options[:as] == :admin
  206 + user
  207 + end
  208 +
  209 + def defaults
  210 + {
  211 + projects_limit: Gitlab.config.gitlab.default_projects_limit,
  212 + can_create_group: Gitlab.config.gitlab.default_can_create_group,
  213 + theme_id: Gitlab::Theme::BASIC
  214 + }
  215 + end
201 end 216 end
202 217
203 # 218 #
@@ -208,14 +223,6 @@ class User < ActiveRecord::Base @@ -208,14 +223,6 @@ class User < ActiveRecord::Base
208 username 223 username
209 end 224 end
210 225
211 - def with_defaults  
212 - tap do |u|  
213 - u.projects_limit = Gitlab.config.gitlab.default_projects_limit  
214 - u.can_create_group = Gitlab.config.gitlab.default_can_create_group  
215 - u.theme_id = Gitlab::Theme::MARS  
216 - end  
217 - end  
218 -  
219 def notification 226 def notification
220 @notification ||= Notification.new(self) 227 @notification ||= Notification.new(self)
221 end 228 end
@@ -375,4 +382,10 @@ class User < ActiveRecord::Base @@ -375,4 +382,10 @@ class User < ActiveRecord::Base
375 group.owners == [self] 382 group.owners == [self]
376 end 383 end
377 end 384 end
  385 +
  386 + def with_defaults
  387 + User.defaults.each do |k,v|
  388 + self.send("#{k}=",v)
  389 + end
  390 + end
378 end 391 end
lib/api/users.rb
@@ -45,9 +45,8 @@ module API @@ -45,9 +45,8 @@ module API
45 post do 45 post do
46 authenticated_as_admin! 46 authenticated_as_admin!
47 required_attributes! [:email, :password, :name, :username] 47 required_attributes! [:email, :password, :name, :username]
48 -  
49 attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit, :username, :extern_uid, :provider, :bio] 48 attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit, :username, :extern_uid, :provider, :bio]
50 - user = User.new attrs, as: :admin 49 + user = User.build_user(attrs, as: :admin)
51 if user.save 50 if user.save
52 present user, with: Entities::User 51 present user, with: Entities::User
53 else 52 else
lib/gitlab/auth.rb
@@ -13,6 +13,72 @@ module Gitlab @@ -13,6 +13,72 @@ module Gitlab
13 end 13 end
14 end 14 end
15 15
  16 + def find_for_ldap_auth(auth, signed_in_resource = nil)
  17 + uid = auth.info.uid
  18 + provider = auth.provider
  19 + email = auth.info.email.downcase unless auth.info.email.nil?
  20 + raise OmniAuth::Error, "LDAP accounts must provide an uid and email address" if uid.nil? or email.nil?
  21 +
  22 + if @user = User.find_by_extern_uid_and_provider(uid, provider)
  23 + @user
  24 + elsif @user = User.find_by_email(email)
  25 + log.info "Updating legacy LDAP user #{email} with extern_uid => #{uid}"
  26 + @user.update_attributes(extern_uid: uid, provider: provider)
  27 + @user
  28 + else
  29 + create_from_omniauth(auth, true)
  30 + end
  31 + end
  32 +
  33 + def create_from_omniauth(auth, ldap = false)
  34 + provider = auth.provider
  35 + uid = auth.info.uid || auth.uid
  36 + uid = uid.to_s.force_encoding("utf-8")
  37 + name = auth.info.name.to_s.force_encoding("utf-8")
  38 + email = auth.info.email.to_s.downcase unless auth.info.email.nil?
  39 +
  40 + ldap_prefix = ldap ? '(LDAP) ' : ''
  41 + raise OmniAuth::Error, "#{ldap_prefix}#{provider} does not provide an email"\
  42 + " address" if auth.info.email.blank?
  43 +
  44 + log.info "#{ldap_prefix}Creating user from #{provider} login"\
  45 + " {uid => #{uid}, name => #{name}, email => #{email}}"
  46 + password = Devise.friendly_token[0, 8].downcase
  47 + @user = User.build_user({
  48 + extern_uid: uid,
  49 + provider: provider,
  50 + name: name,
  51 + username: email.match(/^[^@]*/)[0],
  52 + email: email,
  53 + password: password,
  54 + password_confirmation: password,
  55 + }, as: :admin)
  56 + @user.save!
  57 +
  58 + if Gitlab.config.omniauth['block_auto_created_users'] && !ldap
  59 + @user.block
  60 + end
  61 +
  62 + @user
  63 + end
  64 +
  65 + def find_or_new_for_omniauth(auth)
  66 + provider, uid = auth.provider, auth.uid
  67 + email = auth.info.email.downcase unless auth.info.email.nil?
  68 +
  69 + if @user = User.find_by_provider_and_extern_uid(provider, uid)
  70 + @user
  71 + elsif @user = User.find_by_email(email)
  72 + @user.update_attributes(extern_uid: uid, provider: provider)
  73 + @user
  74 + else
  75 + if Gitlab.config.omniauth['allow_single_sign_on']
  76 + @user = create_from_omniauth(auth)
  77 + @user
  78 + end
  79 + end
  80 + end
  81 +
16 def log 82 def log
17 Gitlab::AppLogger 83 Gitlab::AppLogger
18 end 84 end
lib/gitlab/oauth/user.rb
@@ -27,7 +27,7 @@ module Gitlab @@ -27,7 +27,7 @@ module Gitlab
27 password_confirmation: password, 27 password_confirmation: password,
28 } 28 }
29 29
30 - user = model.new(opts, as: :admin).with_defaults 30 + user = model.build_user(opts, as: :admin)
31 user.save! 31 user.save!
32 log.info "(OAuth) Creating user #{email} from login with extern_uid => #{uid}" 32 log.info "(OAuth) Creating user #{email} from login with extern_uid => #{uid}"
33 33
spec/models/user_spec.rb
@@ -196,29 +196,63 @@ describe User do @@ -196,29 +196,63 @@ describe User do
196 it { User.not_in_project(@project).should include(@user, @project.owner) } 196 it { User.not_in_project(@project).should include(@user, @project.owner) }
197 end 197 end
198 198
199 - describe 'normal user' do  
200 - let(:user) { create(:user, name: 'John Smith') } 199 + describe 'user creation' do
  200 + describe 'normal user' do
  201 + let(:user) { create(:user, name: 'John Smith') }
201 202
202 - it { user.is_admin?.should be_false }  
203 - it { user.require_ssh_key?.should be_true }  
204 - it { user.can_create_group?.should be_true }  
205 - it { user.can_create_project?.should be_true }  
206 - it { user.first_name.should == 'John' }  
207 - end 203 + it { user.is_admin?.should be_false }
  204 + it { user.require_ssh_key?.should be_true }
  205 + it { user.can_create_group?.should be_true }
  206 + it { user.can_create_project?.should be_true }
  207 + it { user.first_name.should == 'John' }
  208 + end
208 209
209 - describe 'without defaults' do  
210 - let(:user) { User.new }  
211 - it "should not apply defaults to user" do  
212 - user.projects_limit.should == 10  
213 - user.can_create_group.should == true 210 + describe 'without defaults' do
  211 + let(:user) { User.new }
  212 + it "should not apply defaults to user" do
  213 + user.projects_limit.should == 10
  214 + user.can_create_group.should be_true
  215 + user.theme_id.should == Gitlab::Theme::BASIC
  216 + end
214 end 217 end
215 - end 218 + context 'as admin' do
  219 + describe 'with defaults' do
  220 + let(:user) { User.build_user({}, as: :admin) }
  221 + it "should apply defaults to user" do
  222 + user.projects_limit.should == 42
  223 + user.can_create_group.should be_false
  224 + user.theme_id.should == Gitlab::Theme::BASIC
  225 + end
  226 + end
  227 +
  228 + describe 'with default overrides' do
  229 + let(:user) { User.build_user({projects_limit: 123, can_create_group: true, can_create_team: true, theme_id: Gitlab::Theme::MARS}, as: :admin) }
  230 + it "should apply defaults to user" do
  231 + user.projects_limit.should == 123
  232 + user.can_create_group.should be_true
  233 + user.theme_id.should == Gitlab::Theme::MARS
  234 + end
  235 + end
  236 + end
  237 +
  238 + context 'as user' do
  239 + describe 'with defaults' do
  240 + let(:user) { User.build_user }
  241 + it "should apply defaults to user" do
  242 + user.projects_limit.should == 42
  243 + user.can_create_group.should be_false
  244 + user.theme_id.should == Gitlab::Theme::BASIC
  245 + end
  246 + end
216 247
217 - describe 'with defaults' do  
218 - let(:user) { User.new.with_defaults }  
219 - it "should apply defaults to user" do  
220 - user.projects_limit.should == 42  
221 - user.can_create_group.should == false 248 + describe 'with default overrides' do
  249 + let(:user) { User.build_user(projects_limit: 123, can_create_group: true, theme_id: Gitlab::Theme::MARS) }
  250 + it "should apply defaults to user" do
  251 + user.projects_limit.should == 42
  252 + user.can_create_group.should be_false
  253 + user.theme_id.should == Gitlab::Theme::BASIC
  254 + end
  255 + end
222 end 256 end
223 end 257 end
224 258
spec/requests/api/users_spec.rb
@@ -57,6 +57,19 @@ describe API::API do @@ -57,6 +57,19 @@ describe API::API do
57 response.status.should == 201 57 response.status.should == 201
58 end 58 end
59 59
  60 + it "creating a user should respect default project limit" do
  61 + limit = 123456
  62 + Gitlab.config.gitlab.stub(:default_projects_limit).and_return(limit)
  63 + attr = attributes_for(:user )
  64 + expect {
  65 + post api("/users", admin), attr
  66 + }.to change { User.count }.by(1)
  67 + user = User.find_by_username(attr[:username])
  68 + user.projects_limit.should == limit
  69 + user.theme_id.should == Gitlab::Theme::BASIC
  70 + Gitlab.config.gitlab.unstub(:default_projects_limit)
  71 + end
  72 +
60 it "should not create user with invalid email" do 73 it "should not create user with invalid email" do
61 post api("/users", admin), { email: "invalid email", password: 'password' } 74 post api("/users", admin), { email: "invalid email", password: 'password' }
62 response.status.should == 400 75 response.status.should == 400