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 13 end
14 14  
15 15 def new
16   - @user = User.new.with_defaults
  16 + @user = User.build_user
17 17 end
18 18  
19 19 def edit
... ... @@ -44,7 +44,7 @@ class Admin::UsersController < Admin::ApplicationController
44 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 48 @user.admin = (admin && admin.to_i > 0)
49 49 @user.created_by_id = current_user.id
50 50  
... ...
app/models/user.rb
... ... @@ -198,6 +198,21 @@ class User < ActiveRecord::Base
198 198 User.find_by_username(name_or_id)
199 199 end
200 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 216 end
202 217  
203 218 #
... ... @@ -208,14 +223,6 @@ class User < ActiveRecord::Base
208 223 username
209 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 226 def notification
220 227 @notification ||= Notification.new(self)
221 228 end
... ... @@ -375,4 +382,10 @@ class User < ActiveRecord::Base
375 382 group.owners == [self]
376 383 end
377 384 end
  385 +
  386 + def with_defaults
  387 + User.defaults.each do |k,v|
  388 + self.send("#{k}=",v)
  389 + end
  390 + end
378 391 end
... ...
lib/api/users.rb
... ... @@ -45,9 +45,8 @@ module API
45 45 post do
46 46 authenticated_as_admin!
47 47 required_attributes! [:email, :password, :name, :username]
48   -
49 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 50 if user.save
52 51 present user, with: Entities::User
53 52 else
... ...
lib/gitlab/auth.rb
... ... @@ -13,6 +13,72 @@ module Gitlab
13 13 end
14 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 82 def log
17 83 Gitlab::AppLogger
18 84 end
... ...
lib/gitlab/oauth/user.rb
... ... @@ -27,7 +27,7 @@ module Gitlab
27 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 31 user.save!
32 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 196 it { User.not_in_project(@project).should include(@user, @project.owner) }
197 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 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 256 end
223 257 end
224 258  
... ...
spec/requests/api/users_spec.rb
... ... @@ -57,6 +57,19 @@ describe API::API do
57 57 response.status.should == 201
58 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 73 it "should not create user with invalid email" do
61 74 post api("/users", admin), { email: "invalid email", password: 'password' }
62 75 response.status.should == 400
... ...