PageRenderTime 31ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/spec/lib/gitlab/auth_spec.rb

https://gitlab.com/jacobvosmaer-gitlab/gitlab-ce
Ruby | 243 lines | 189 code | 54 blank | 0 comment | 1 complexity | 7011c1a3f41a0ef8415f5ef77e2ad2ac MD5 | raw file
  1. require 'spec_helper'
  2. describe Gitlab::Auth, lib: true do
  3. let(:gl_auth) { described_class }
  4. describe 'find_for_git_client' do
  5. context 'build token' do
  6. subject { gl_auth.find_for_git_client('gitlab-ci-token', build.token, project: project, ip: 'ip') }
  7. context 'for running build' do
  8. let!(:build) { create(:ci_build, :running) }
  9. let(:project) { build.project }
  10. before do
  11. expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: 'gitlab-ci-token')
  12. end
  13. it 'recognises user-less build' do
  14. expect(subject).to eq(Gitlab::Auth::Result.new(nil, build.project, :ci, build_authentication_abilities))
  15. end
  16. it 'recognises user token' do
  17. build.update(user: create(:user))
  18. expect(subject).to eq(Gitlab::Auth::Result.new(build.user, build.project, :build, build_authentication_abilities))
  19. end
  20. end
  21. (HasStatus::AVAILABLE_STATUSES - ['running']).each do |build_status|
  22. context "for #{build_status} build" do
  23. let!(:build) { create(:ci_build, status: build_status) }
  24. let(:project) { build.project }
  25. before do
  26. expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: 'gitlab-ci-token')
  27. end
  28. it 'denies authentication' do
  29. expect(subject).to eq(Gitlab::Auth::Result.new)
  30. end
  31. end
  32. end
  33. end
  34. it 'recognizes other ci services' do
  35. project = create(:empty_project)
  36. project.create_drone_ci_service(active: true)
  37. project.drone_ci_service.update(token: 'token')
  38. expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: 'drone-ci-token')
  39. expect(gl_auth.find_for_git_client('drone-ci-token', 'token', project: project, ip: 'ip')).to eq(Gitlab::Auth::Result.new(nil, project, :ci, build_authentication_abilities))
  40. end
  41. it 'recognizes master passwords' do
  42. user = create(:user, password: 'password')
  43. expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: user.username)
  44. expect(gl_auth.find_for_git_client(user.username, 'password', project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities))
  45. end
  46. context 'while using LFS authenticate' do
  47. it 'recognizes user lfs tokens' do
  48. user = create(:user)
  49. token = Gitlab::LfsToken.new(user).token
  50. expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: user.username)
  51. expect(gl_auth.find_for_git_client(user.username, token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(user, nil, :lfs_token, full_authentication_abilities))
  52. end
  53. it 'recognizes deploy key lfs tokens' do
  54. key = create(:deploy_key)
  55. token = Gitlab::LfsToken.new(key).token
  56. expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: "lfs+deploy-key-#{key.id}")
  57. expect(gl_auth.find_for_git_client("lfs+deploy-key-#{key.id}", token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(key, nil, :lfs_deploy_token, read_authentication_abilities))
  58. end
  59. it 'does not try password auth before oauth' do
  60. user = create(:user)
  61. token = Gitlab::LfsToken.new(user).token
  62. expect(gl_auth).not_to receive(:find_with_user_password)
  63. gl_auth.find_for_git_client(user.username, token, project: nil, ip: 'ip')
  64. end
  65. end
  66. context 'while using OAuth tokens as passwords' do
  67. let(:user) { create(:user) }
  68. let(:token_w_api_scope) { Doorkeeper::AccessToken.create!(application_id: application.id, resource_owner_id: user.id, scopes: 'api') }
  69. let(:application) { Doorkeeper::Application.create!(name: 'MyApp', redirect_uri: 'https://app.com', owner: user) }
  70. it 'succeeds for OAuth tokens with the `api` scope' do
  71. expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: 'oauth2')
  72. expect(gl_auth.find_for_git_client("oauth2", token_w_api_scope.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(user, nil, :oauth, read_authentication_abilities))
  73. end
  74. it 'fails for OAuth tokens with other scopes' do
  75. token = Doorkeeper::AccessToken.create!(application_id: application.id, resource_owner_id: user.id, scopes: 'read_user')
  76. expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: 'oauth2')
  77. expect(gl_auth.find_for_git_client("oauth2", token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(nil, nil))
  78. end
  79. it 'does not try password auth before oauth' do
  80. expect(gl_auth).not_to receive(:find_with_user_password)
  81. gl_auth.find_for_git_client("oauth2", token_w_api_scope.token, project: nil, ip: 'ip')
  82. end
  83. end
  84. context 'while using personal access tokens as passwords' do
  85. let(:user) { create(:user) }
  86. let(:token_w_api_scope) { create(:personal_access_token, user: user, scopes: ['api']) }
  87. it 'succeeds for personal access tokens with the `api` scope' do
  88. expect(gl_auth).to receive(:rate_limit!).with('ip', success: true, login: user.email)
  89. expect(gl_auth.find_for_git_client(user.email, token_w_api_scope.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(user, nil, :personal_token, full_authentication_abilities))
  90. end
  91. it 'fails for personal access tokens with other scopes' do
  92. personal_access_token = create(:personal_access_token, user: user, scopes: ['read_user'])
  93. expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: user.email)
  94. expect(gl_auth.find_for_git_client(user.email, personal_access_token.token, project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new(nil, nil))
  95. end
  96. it 'does not try password auth before personal access tokens' do
  97. expect(gl_auth).not_to receive(:find_with_user_password)
  98. gl_auth.find_for_git_client(user.email, token_w_api_scope.token, project: nil, ip: 'ip')
  99. end
  100. end
  101. context 'while using regular user and password' do
  102. it 'falls through lfs authentication' do
  103. user = create(
  104. :user,
  105. username: 'normal_user',
  106. password: 'my-secret',
  107. )
  108. expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip'))
  109. .to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities))
  110. end
  111. it 'falls through oauth authentication when the username is oauth2' do
  112. user = create(
  113. :user,
  114. username: 'oauth2',
  115. password: 'my-secret',
  116. )
  117. expect(gl_auth.find_for_git_client(user.username, user.password, project: nil, ip: 'ip'))
  118. .to eq(Gitlab::Auth::Result.new(user, nil, :gitlab_or_ldap, full_authentication_abilities))
  119. end
  120. end
  121. it 'returns double nil for invalid credentials' do
  122. login = 'foo'
  123. expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: login)
  124. expect(gl_auth.find_for_git_client(login, 'bar', project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new)
  125. end
  126. end
  127. describe 'find_with_user_password' do
  128. let!(:user) do
  129. create(:user,
  130. username: username,
  131. password: password,
  132. password_confirmation: password)
  133. end
  134. let(:username) { 'John' } # username isn't lowercase, test this
  135. let(:password) { 'my-secret' }
  136. it "finds user by valid login/password" do
  137. expect( gl_auth.find_with_user_password(username, password) ).to eql user
  138. end
  139. it 'finds user by valid email/password with case-insensitive email' do
  140. expect(gl_auth.find_with_user_password(user.email.upcase, password)).to eql user
  141. end
  142. it 'finds user by valid username/password with case-insensitive username' do
  143. expect(gl_auth.find_with_user_password(username.upcase, password)).to eql user
  144. end
  145. it "does not find user with invalid password" do
  146. password = 'wrong'
  147. expect( gl_auth.find_with_user_password(username, password) ).not_to eql user
  148. end
  149. it "does not find user with invalid login" do
  150. user = 'wrong'
  151. expect( gl_auth.find_with_user_password(username, password) ).not_to eql user
  152. end
  153. context "with ldap enabled" do
  154. before do
  155. allow(Gitlab::LDAP::Config).to receive(:enabled?).and_return(true)
  156. end
  157. it "tries to autheticate with db before ldap" do
  158. expect(Gitlab::LDAP::Authentication).not_to receive(:login)
  159. gl_auth.find_with_user_password(username, password)
  160. end
  161. it "uses ldap as fallback to for authentication" do
  162. expect(Gitlab::LDAP::Authentication).to receive(:login)
  163. gl_auth.find_with_user_password('ldap_user', 'password')
  164. end
  165. end
  166. end
  167. private
  168. def build_authentication_abilities
  169. [
  170. :read_project,
  171. :build_download_code,
  172. :build_read_container_image,
  173. :build_create_container_image
  174. ]
  175. end
  176. def read_authentication_abilities
  177. [
  178. :read_project,
  179. :download_code,
  180. :read_container_image
  181. ]
  182. end
  183. def full_authentication_abilities
  184. read_authentication_abilities + [
  185. :push_code,
  186. :create_container_image
  187. ]
  188. end
  189. end