/spec/controllers/application_controller_spec.rb

https://gitlab.com/certik/gitlab-ce · Ruby · 422 lines · 335 code · 87 blank · 0 comment · 0 complexity · 14ae3c596495458057316527ff147976 MD5 · raw file

  1. require 'spec_helper'
  2. describe ApplicationController do
  3. let(:user) { create(:user) }
  4. describe '#check_password_expiration' do
  5. let(:controller) { described_class.new }
  6. it 'redirects if the user is over their password expiry' do
  7. user.password_expires_at = Time.new(2002)
  8. expect(user.ldap_user?).to be_falsey
  9. allow(controller).to receive(:current_user).and_return(user)
  10. expect(controller).to receive(:redirect_to)
  11. expect(controller).to receive(:new_profile_password_path)
  12. controller.send(:check_password_expiration)
  13. end
  14. it 'does not redirect if the user is under their password expiry' do
  15. user.password_expires_at = Time.now + 20010101
  16. expect(user.ldap_user?).to be_falsey
  17. allow(controller).to receive(:current_user).and_return(user)
  18. expect(controller).not_to receive(:redirect_to)
  19. controller.send(:check_password_expiration)
  20. end
  21. it 'does not redirect if the user is over their password expiry but they are an ldap user' do
  22. user.password_expires_at = Time.new(2002)
  23. allow(user).to receive(:ldap_user?).and_return(true)
  24. allow(controller).to receive(:current_user).and_return(user)
  25. expect(controller).not_to receive(:redirect_to)
  26. controller.send(:check_password_expiration)
  27. end
  28. it 'redirects if the user is over their password expiry and sign-in is disabled' do
  29. stub_application_setting(password_authentication_enabled: false)
  30. user.password_expires_at = Time.new(2002)
  31. expect(user.ldap_user?).to be_falsey
  32. allow(controller).to receive(:current_user).and_return(user)
  33. expect(controller).to receive(:redirect_to)
  34. expect(controller).to receive(:new_profile_password_path)
  35. controller.send(:check_password_expiration)
  36. end
  37. end
  38. describe "#authenticate_user_from_token!" do
  39. describe "authenticating a user from a private token" do
  40. controller(described_class) do
  41. def index
  42. render text: "authenticated"
  43. end
  44. end
  45. context "when the 'private_token' param is populated with the private token" do
  46. it "logs the user in" do
  47. get :index, private_token: user.private_token
  48. expect(response).to have_http_status(200)
  49. expect(response.body).to eq("authenticated")
  50. end
  51. end
  52. context "when the 'PRIVATE-TOKEN' header is populated with the private token" do
  53. it "logs the user in" do
  54. @request.headers['PRIVATE-TOKEN'] = user.private_token
  55. get :index
  56. expect(response).to have_http_status(200)
  57. expect(response.body).to eq("authenticated")
  58. end
  59. end
  60. it "doesn't log the user in otherwise" do
  61. @request.headers['PRIVATE-TOKEN'] = "token"
  62. get :index, private_token: "token", authenticity_token: "token"
  63. expect(response.status).not_to eq(200)
  64. expect(response.body).not_to eq("authenticated")
  65. end
  66. end
  67. describe "authenticating a user from a personal access token" do
  68. controller(described_class) do
  69. def index
  70. render text: 'authenticated'
  71. end
  72. end
  73. let(:personal_access_token) { create(:personal_access_token, user: user) }
  74. context "when the 'personal_access_token' param is populated with the personal access token" do
  75. it "logs the user in" do
  76. get :index, private_token: personal_access_token.token
  77. expect(response).to have_http_status(200)
  78. expect(response.body).to eq('authenticated')
  79. end
  80. end
  81. context "when the 'PERSONAL_ACCESS_TOKEN' header is populated with the personal access token" do
  82. it "logs the user in" do
  83. @request.headers["PRIVATE-TOKEN"] = personal_access_token.token
  84. get :index
  85. expect(response).to have_http_status(200)
  86. expect(response.body).to eq('authenticated')
  87. end
  88. end
  89. it "doesn't log the user in otherwise" do
  90. get :index, private_token: "token"
  91. expect(response.status).not_to eq(200)
  92. expect(response.body).not_to eq('authenticated')
  93. end
  94. end
  95. end
  96. describe 'rescue from Gitlab::Git::Storage::Inaccessible' do
  97. controller(described_class) do
  98. def index
  99. raise Gitlab::Git::Storage::Inaccessible.new('broken', 100)
  100. end
  101. end
  102. it 'renders a 503 when storage is not available' do
  103. sign_in(create(:user))
  104. get :index
  105. expect(response.status).to eq(503)
  106. end
  107. it 'renders includes a Retry-After header' do
  108. sign_in(create(:user))
  109. get :index
  110. expect(response.headers['Retry-After']).to eq(100)
  111. end
  112. end
  113. describe 'response format' do
  114. controller(described_class) do
  115. def index
  116. respond_to do |format|
  117. format.json do
  118. head :ok
  119. end
  120. end
  121. end
  122. end
  123. context 'when format is handled' do
  124. let(:requested_format) { :json }
  125. it 'returns 200 response' do
  126. get :index, private_token: user.private_token, format: requested_format
  127. expect(response).to have_http_status 200
  128. end
  129. end
  130. context 'when format is not handled' do
  131. it 'returns 404 response' do
  132. get :index, private_token: user.private_token
  133. expect(response).to have_http_status 404
  134. end
  135. end
  136. end
  137. describe '#authenticate_user_from_rss_token' do
  138. describe "authenticating a user from an RSS token" do
  139. controller(described_class) do
  140. def index
  141. render text: 'authenticated'
  142. end
  143. end
  144. context "when the 'rss_token' param is populated with the RSS token" do
  145. context 'when the request format is atom' do
  146. it "logs the user in" do
  147. get :index, rss_token: user.rss_token, format: :atom
  148. expect(response).to have_http_status 200
  149. expect(response.body).to eq 'authenticated'
  150. end
  151. end
  152. context 'when the request format is not atom' do
  153. it "doesn't log the user in" do
  154. get :index, rss_token: user.rss_token
  155. expect(response.status).not_to have_http_status 200
  156. expect(response.body).not_to eq 'authenticated'
  157. end
  158. end
  159. end
  160. context "when the 'rss_token' param is populated with an invalid RSS token" do
  161. it "doesn't log the user" do
  162. get :index, rss_token: "token"
  163. expect(response.status).not_to eq 200
  164. expect(response.body).not_to eq 'authenticated'
  165. end
  166. end
  167. end
  168. end
  169. describe '#route_not_found' do
  170. it 'renders 404 if authenticated' do
  171. allow(controller).to receive(:current_user).and_return(user)
  172. expect(controller).to receive(:not_found)
  173. controller.send(:route_not_found)
  174. end
  175. it 'does redirect to login page via authenticate_user! if not authenticated' do
  176. allow(controller).to receive(:current_user).and_return(nil)
  177. expect(controller).to receive(:authenticate_user!)
  178. controller.send(:route_not_found)
  179. end
  180. end
  181. context 'two-factor authentication' do
  182. let(:controller) { described_class.new }
  183. describe '#check_two_factor_requirement' do
  184. subject { controller.send :check_two_factor_requirement }
  185. it 'does not redirect if 2FA is not required' do
  186. allow(controller).to receive(:two_factor_authentication_required?).and_return(false)
  187. expect(controller).not_to receive(:redirect_to)
  188. subject
  189. end
  190. it 'does not redirect if user is not logged in' do
  191. allow(controller).to receive(:two_factor_authentication_required?).and_return(true)
  192. allow(controller).to receive(:current_user).and_return(nil)
  193. expect(controller).not_to receive(:redirect_to)
  194. subject
  195. end
  196. it 'does not redirect if user has 2FA enabled' do
  197. allow(controller).to receive(:two_factor_authentication_required?).and_return(true)
  198. allow(controller).to receive(:current_user).twice.and_return(user)
  199. allow(user).to receive(:two_factor_enabled?).and_return(true)
  200. expect(controller).not_to receive(:redirect_to)
  201. subject
  202. end
  203. it 'does not redirect if 2FA setup can be skipped' do
  204. allow(controller).to receive(:two_factor_authentication_required?).and_return(true)
  205. allow(controller).to receive(:current_user).twice.and_return(user)
  206. allow(user).to receive(:two_factor_enabled?).and_return(false)
  207. allow(controller).to receive(:skip_two_factor?).and_return(true)
  208. expect(controller).not_to receive(:redirect_to)
  209. subject
  210. end
  211. it 'redirects to 2FA setup otherwise' do
  212. allow(controller).to receive(:two_factor_authentication_required?).and_return(true)
  213. allow(controller).to receive(:current_user).twice.and_return(user)
  214. allow(user).to receive(:two_factor_enabled?).and_return(false)
  215. allow(controller).to receive(:skip_two_factor?).and_return(false)
  216. allow(controller).to receive(:profile_two_factor_auth_path)
  217. expect(controller).to receive(:redirect_to)
  218. subject
  219. end
  220. end
  221. describe '#two_factor_authentication_required?' do
  222. subject { controller.send :two_factor_authentication_required? }
  223. it 'returns false if no 2FA requirement is present' do
  224. allow(controller).to receive(:current_user).and_return(nil)
  225. expect(subject).to be_falsey
  226. end
  227. it 'returns true if a 2FA requirement is set in the application settings' do
  228. stub_application_setting require_two_factor_authentication: true
  229. allow(controller).to receive(:current_user).and_return(nil)
  230. expect(subject).to be_truthy
  231. end
  232. it 'returns true if a 2FA requirement is set on the user' do
  233. user.require_two_factor_authentication_from_group = true
  234. allow(controller).to receive(:current_user).and_return(user)
  235. expect(subject).to be_truthy
  236. end
  237. end
  238. describe '#two_factor_grace_period' do
  239. subject { controller.send :two_factor_grace_period }
  240. it 'returns the grace period from the application settings' do
  241. stub_application_setting two_factor_grace_period: 23
  242. allow(controller).to receive(:current_user).and_return(nil)
  243. expect(subject).to eq 23
  244. end
  245. context 'with a 2FA requirement set on the user' do
  246. let(:user) { create :user, require_two_factor_authentication_from_group: true, two_factor_grace_period: 23 }
  247. it 'returns the user grace period if lower than the application grace period' do
  248. stub_application_setting two_factor_grace_period: 24
  249. allow(controller).to receive(:current_user).and_return(user)
  250. expect(subject).to eq 23
  251. end
  252. it 'returns the application grace period if lower than the user grace period' do
  253. stub_application_setting two_factor_grace_period: 22
  254. allow(controller).to receive(:current_user).and_return(user)
  255. expect(subject).to eq 22
  256. end
  257. end
  258. end
  259. describe '#two_factor_grace_period_expired?' do
  260. subject { controller.send :two_factor_grace_period_expired? }
  261. before do
  262. allow(controller).to receive(:current_user).and_return(user)
  263. end
  264. it 'returns false if the user has not started their grace period yet' do
  265. expect(subject).to be_falsey
  266. end
  267. context 'with grace period started' do
  268. let(:user) { create :user, otp_grace_period_started_at: 2.hours.ago }
  269. it 'returns true if the grace period has expired' do
  270. allow(controller).to receive(:two_factor_grace_period).and_return(1)
  271. expect(subject).to be_truthy
  272. end
  273. it 'returns false if the grace period is still active' do
  274. allow(controller).to receive(:two_factor_grace_period).and_return(3)
  275. expect(subject).to be_falsey
  276. end
  277. end
  278. end
  279. describe '#two_factor_skippable' do
  280. subject { controller.send :two_factor_skippable? }
  281. before do
  282. allow(controller).to receive(:current_user).and_return(user)
  283. end
  284. it 'returns false if 2FA is not required' do
  285. allow(controller).to receive(:two_factor_authentication_required?).and_return(false)
  286. expect(subject).to be_falsey
  287. end
  288. it 'returns false if the user has already enabled 2FA' do
  289. allow(controller).to receive(:two_factor_authentication_required?).and_return(true)
  290. allow(user).to receive(:two_factor_enabled?).and_return(true)
  291. expect(subject).to be_falsey
  292. end
  293. it 'returns false if the 2FA grace period has expired' do
  294. allow(controller).to receive(:two_factor_authentication_required?).and_return(true)
  295. allow(user).to receive(:two_factor_enabled?).and_return(false)
  296. allow(controller).to receive(:two_factor_grace_period_expired?).and_return(true)
  297. expect(subject).to be_falsey
  298. end
  299. it 'returns true otherwise' do
  300. allow(controller).to receive(:two_factor_authentication_required?).and_return(true)
  301. allow(user).to receive(:two_factor_enabled?).and_return(false)
  302. allow(controller).to receive(:two_factor_grace_period_expired?).and_return(false)
  303. expect(subject).to be_truthy
  304. end
  305. end
  306. describe '#skip_two_factor?' do
  307. subject { controller.send :skip_two_factor? }
  308. it 'returns false if 2FA setup was not skipped' do
  309. allow(controller).to receive(:session).and_return({})
  310. expect(subject).to be_falsey
  311. end
  312. context 'with 2FA setup skipped' do
  313. before do
  314. allow(controller).to receive(:session).and_return({ skip_two_factor: 2.hours.from_now })
  315. end
  316. it 'returns false if the grace period has expired' do
  317. Timecop.freeze(3.hours.from_now) do
  318. expect(subject).to be_falsey
  319. end
  320. end
  321. it 'returns true if the grace period is still active' do
  322. Timecop.freeze(1.hour.from_now) do
  323. expect(subject).to be_truthy
  324. end
  325. end
  326. end
  327. end
  328. end
  329. end