PageRenderTime 29ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/spec/requests/api/api_helpers_spec.rb

https://gitlab.com/sacuiu.andy/gitlab-ce
Ruby | 264 lines | 241 code | 23 blank | 0 comment | 4 complexity | 4fe5f26976a17de6beb32a4b646b132d MD5 | raw file
  1. require 'spec_helper'
  2. describe API::Helpers, api: true do
  3. include API::Helpers
  4. include ApiHelpers
  5. include SentryHelper
  6. let(:user) { create(:user) }
  7. let(:admin) { create(:admin) }
  8. let(:key) { create(:key, user: user) }
  9. let(:params) { {} }
  10. let(:env) { {} }
  11. def set_env(token_usr, identifier)
  12. clear_env
  13. clear_param
  14. env[API::Helpers::PRIVATE_TOKEN_HEADER] = token_usr.private_token
  15. env[API::Helpers::SUDO_HEADER] = identifier
  16. end
  17. def set_param(token_usr, identifier)
  18. clear_env
  19. clear_param
  20. params[API::Helpers::PRIVATE_TOKEN_PARAM] = token_usr.private_token
  21. params[API::Helpers::SUDO_PARAM] = identifier
  22. end
  23. def clear_env
  24. env.delete(API::Helpers::PRIVATE_TOKEN_HEADER)
  25. env.delete(API::Helpers::SUDO_HEADER)
  26. end
  27. def clear_param
  28. params.delete(API::Helpers::PRIVATE_TOKEN_PARAM)
  29. params.delete(API::Helpers::SUDO_PARAM)
  30. end
  31. def error!(message, status)
  32. raise Exception
  33. end
  34. describe ".current_user" do
  35. describe "when authenticating using a user's private token" do
  36. it "returns nil for an invalid token" do
  37. env[API::Helpers::PRIVATE_TOKEN_HEADER] = 'invalid token'
  38. allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false }
  39. expect(current_user).to be_nil
  40. end
  41. it "returns nil for a user without access" do
  42. env[API::Helpers::PRIVATE_TOKEN_HEADER] = user.private_token
  43. allow_any_instance_of(Gitlab::UserAccess).to receive(:allowed?).and_return(false)
  44. expect(current_user).to be_nil
  45. end
  46. it "leaves user as is when sudo not specified" do
  47. env[API::Helpers::PRIVATE_TOKEN_HEADER] = user.private_token
  48. expect(current_user).to eq(user)
  49. clear_env
  50. params[API::Helpers::PRIVATE_TOKEN_PARAM] = user.private_token
  51. expect(current_user).to eq(user)
  52. end
  53. end
  54. describe "when authenticating using a user's personal access tokens" do
  55. let(:personal_access_token) { create(:personal_access_token, user: user) }
  56. it "returns nil for an invalid token" do
  57. env[API::Helpers::PRIVATE_TOKEN_HEADER] = 'invalid token'
  58. allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false }
  59. expect(current_user).to be_nil
  60. end
  61. it "returns nil for a user without access" do
  62. env[API::Helpers::PRIVATE_TOKEN_HEADER] = personal_access_token.token
  63. allow_any_instance_of(Gitlab::UserAccess).to receive(:allowed?).and_return(false)
  64. expect(current_user).to be_nil
  65. end
  66. it "leaves user as is when sudo not specified" do
  67. env[API::Helpers::PRIVATE_TOKEN_HEADER] = personal_access_token.token
  68. expect(current_user).to eq(user)
  69. clear_env
  70. params[API::Helpers::PRIVATE_TOKEN_PARAM] = personal_access_token.token
  71. expect(current_user).to eq(user)
  72. end
  73. it 'does not allow revoked tokens' do
  74. personal_access_token.revoke!
  75. env[API::Helpers::PRIVATE_TOKEN_HEADER] = personal_access_token.token
  76. allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false }
  77. expect(current_user).to be_nil
  78. end
  79. it 'does not allow expired tokens' do
  80. personal_access_token.update_attributes!(expires_at: 1.day.ago)
  81. env[API::Helpers::PRIVATE_TOKEN_HEADER] = personal_access_token.token
  82. allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false }
  83. expect(current_user).to be_nil
  84. end
  85. end
  86. it "changes current user to sudo when admin" do
  87. set_env(admin, user.id)
  88. expect(current_user).to eq(user)
  89. set_param(admin, user.id)
  90. expect(current_user).to eq(user)
  91. set_env(admin, user.username)
  92. expect(current_user).to eq(user)
  93. set_param(admin, user.username)
  94. expect(current_user).to eq(user)
  95. end
  96. it "throws an error when the current user is not an admin and attempting to sudo" do
  97. set_env(user, admin.id)
  98. expect { current_user }.to raise_error(Exception)
  99. set_param(user, admin.id)
  100. expect { current_user }.to raise_error(Exception)
  101. set_env(user, admin.username)
  102. expect { current_user }.to raise_error(Exception)
  103. set_param(user, admin.username)
  104. expect { current_user }.to raise_error(Exception)
  105. end
  106. it "throws an error when the user cannot be found for a given id" do
  107. id = user.id + admin.id
  108. expect(user.id).not_to eq(id)
  109. expect(admin.id).not_to eq(id)
  110. set_env(admin, id)
  111. expect { current_user }.to raise_error(Exception)
  112. set_param(admin, id)
  113. expect { current_user }.to raise_error(Exception)
  114. end
  115. it "throws an error when the user cannot be found for a given username" do
  116. username = "#{user.username}#{admin.username}"
  117. expect(user.username).not_to eq(username)
  118. expect(admin.username).not_to eq(username)
  119. set_env(admin, username)
  120. expect { current_user }.to raise_error(Exception)
  121. set_param(admin, username)
  122. expect { current_user }.to raise_error(Exception)
  123. end
  124. it "handles sudo's to oneself" do
  125. set_env(admin, admin.id)
  126. expect(current_user).to eq(admin)
  127. set_param(admin, admin.id)
  128. expect(current_user).to eq(admin)
  129. set_env(admin, admin.username)
  130. expect(current_user).to eq(admin)
  131. set_param(admin, admin.username)
  132. expect(current_user).to eq(admin)
  133. end
  134. it "handles multiple sudo's to oneself" do
  135. set_env(admin, user.id)
  136. expect(current_user).to eq(user)
  137. expect(current_user).to eq(user)
  138. set_env(admin, user.username)
  139. expect(current_user).to eq(user)
  140. expect(current_user).to eq(user)
  141. set_param(admin, user.id)
  142. expect(current_user).to eq(user)
  143. expect(current_user).to eq(user)
  144. set_param(admin, user.username)
  145. expect(current_user).to eq(user)
  146. expect(current_user).to eq(user)
  147. end
  148. it "handles multiple sudo's to oneself using string ids" do
  149. set_env(admin, user.id.to_s)
  150. expect(current_user).to eq(user)
  151. expect(current_user).to eq(user)
  152. set_param(admin, user.id.to_s)
  153. expect(current_user).to eq(user)
  154. expect(current_user).to eq(user)
  155. end
  156. end
  157. describe '.sudo_identifier' do
  158. it "returns integers when input is an int" do
  159. set_env(admin, '123')
  160. expect(sudo_identifier).to eq(123)
  161. set_env(admin, '0001234567890')
  162. expect(sudo_identifier).to eq(1234567890)
  163. set_param(admin, '123')
  164. expect(sudo_identifier).to eq(123)
  165. set_param(admin, '0001234567890')
  166. expect(sudo_identifier).to eq(1234567890)
  167. end
  168. it "returns string when input is an is not an int" do
  169. set_env(admin, '12.30')
  170. expect(sudo_identifier).to eq("12.30")
  171. set_env(admin, 'hello')
  172. expect(sudo_identifier).to eq('hello')
  173. set_env(admin, ' 123')
  174. expect(sudo_identifier).to eq(' 123')
  175. set_param(admin, '12.30')
  176. expect(sudo_identifier).to eq("12.30")
  177. set_param(admin, 'hello')
  178. expect(sudo_identifier).to eq('hello')
  179. set_param(admin, ' 123')
  180. expect(sudo_identifier).to eq(' 123')
  181. end
  182. end
  183. describe '.to_boolean' do
  184. it 'converts a valid string to a boolean' do
  185. expect(to_boolean('true')).to be_truthy
  186. expect(to_boolean('YeS')).to be_truthy
  187. expect(to_boolean('t')).to be_truthy
  188. expect(to_boolean('1')).to be_truthy
  189. expect(to_boolean('ON')).to be_truthy
  190. expect(to_boolean('FaLse')).to be_falsy
  191. expect(to_boolean('F')).to be_falsy
  192. expect(to_boolean('NO')).to be_falsy
  193. expect(to_boolean('n')).to be_falsy
  194. expect(to_boolean('0')).to be_falsy
  195. expect(to_boolean('oFF')).to be_falsy
  196. end
  197. it 'converts an invalid string to nil' do
  198. expect(to_boolean('fals')).to be_nil
  199. expect(to_boolean('yeah')).to be_nil
  200. expect(to_boolean('')).to be_nil
  201. expect(to_boolean(nil)).to be_nil
  202. end
  203. end
  204. describe '.handle_api_exception' do
  205. before do
  206. allow_any_instance_of(self.class).to receive(:sentry_enabled?).and_return(true)
  207. allow_any_instance_of(self.class).to receive(:rack_response)
  208. end
  209. it 'does not report a MethodNotAllowed exception to Sentry' do
  210. exception = Grape::Exceptions::MethodNotAllowed.new({ 'X-GitLab-Test' => '1' })
  211. allow(exception).to receive(:backtrace).and_return(caller)
  212. expect(Raven).not_to receive(:capture_exception).with(exception)
  213. handle_api_exception(exception)
  214. end
  215. it 'does report RuntimeError to Sentry' do
  216. exception = RuntimeError.new('test error')
  217. allow(exception).to receive(:backtrace).and_return(caller)
  218. expect_any_instance_of(self.class).to receive(:sentry_context)
  219. expect(Raven).to receive(:capture_exception).with(exception)
  220. handle_api_exception(exception)
  221. end
  222. end
  223. end