From d625f4e9fe78a69be0d481c20cba33b6dd88ef1a Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 27 Jul 2022 19:03:35 +0000 Subject: Add latest changes from gitlab-org/security/gitlab@15-2-stable-ee --- spec/requests/api/invitations_spec.rb | 41 ++++++++ spec/requests/api/oauth_tokens_spec.rb | 34 +++++++ spec/requests/api/users_spec.rb | 167 +++++++++++++++++++++++++++++++++ 3 files changed, 242 insertions(+) (limited to 'spec/requests/api') diff --git a/spec/requests/api/invitations_spec.rb b/spec/requests/api/invitations_spec.rb index 53154aef21e..cb351635081 100644 --- a/spec/requests/api/invitations_spec.rb +++ b/spec/requests/api/invitations_spec.rb @@ -7,6 +7,7 @@ RSpec.describe API::Invitations do let_it_be(:developer) { create(:user) } let_it_be(:access_requester) { create(:user) } let_it_be(:stranger) { create(:user) } + let_it_be(:unconfirmed_stranger) { create(:user, :unconfirmed) } let(:email) { 'email1@example.com' } let(:email2) { 'email2@example.com' } @@ -92,6 +93,46 @@ RSpec.describe API::Invitations do end.to change { source.members.invite.count }.by(1) end + it 'adds a new member by confirmed primary email' do + expect do + post invitations_url(source, maintainer), + params: { email: stranger.email, access_level: Member::DEVELOPER } + + expect(response).to have_gitlab_http_status(:created) + end.to change { source.members.non_invite.count }.by(1) + end + + it 'adds a new member by unconfirmed primary email' do + expect do + post invitations_url(source, maintainer), + params: { email: unconfirmed_stranger.email, access_level: Member::DEVELOPER } + + expect(response).to have_gitlab_http_status(:created) + end.to change { source.members.non_invite.count }.by(1) + end + + it 'adds a new member by confirmed secondary email' do + secondary_email = create(:email, :confirmed, email: 'secondary@example.com', user: stranger) + + expect do + post invitations_url(source, maintainer), + params: { email: secondary_email.email, access_level: Member::DEVELOPER } + + expect(response).to have_gitlab_http_status(:created) + end.to change { source.members.non_invite.count }.by(1) + end + + it 'adds a new member as an invite for unconfirmed secondary email' do + secondary_email = create(:email, email: 'secondary@example.com', user: stranger) + + expect do + post invitations_url(source, maintainer), + params: { email: secondary_email.email, access_level: Member::DEVELOPER } + + expect(response).to have_gitlab_http_status(:created) + end.to change { source.members.invite.count }.by(1).and change { source.members.non_invite.count }.by(0) + end + it 'adds a new member by user_id' do expect do post invitations_url(source, maintainer), diff --git a/spec/requests/api/oauth_tokens_spec.rb b/spec/requests/api/oauth_tokens_spec.rb index edadfbc3d0c..f07dcfcccd6 100644 --- a/spec/requests/api/oauth_tokens_spec.rb +++ b/spec/requests/api/oauth_tokens_spec.rb @@ -25,6 +25,40 @@ RSpec.describe 'OAuth tokens' do end end + context 'when 2FA enforced' do + let_it_be(:user) { create(:user, otp_grace_period_started_at: 1.day.ago) } + + before do + stub_application_setting(require_two_factor_authentication: true) + end + + context 'when grace period expired' do + before do + stub_application_setting(two_factor_grace_period: 0) + end + + it 'does not create an access token' do + request_oauth_token(user, client_basic_auth_header(client)) + + expect(response).to have_gitlab_http_status(:bad_request) + expect(json_response['error']).to eq('invalid_grant') + end + end + + context 'when grace period is not expired' do + before do + stub_application_setting(two_factor_grace_period: 72) + end + + it 'creates an access token' do + request_oauth_token(user, client_basic_auth_header(client)) + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response['access_token']).not_to be_nil + end + end + end + context 'when user does not have 2FA enabled' do context 'when no client credentials provided' do it 'creates an access token' do diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index 68d5fad8ff4..81ca2548995 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -1307,6 +1307,81 @@ RSpec.describe API::Users do end end + context 'when user with a primary email exists' do + context 'when the primary email is confirmed' do + let!(:confirmed_user) { create(:user, email: 'foo@example.com') } + + it 'returns 409 conflict error' do + expect do + post api('/users', admin), + params: { + name: 'foo', + email: confirmed_user.email, + password: 'password', + username: 'TEST' + } + end.to change { User.count }.by(0) + expect(response).to have_gitlab_http_status(:conflict) + expect(json_response['message']).to eq('Email has already been taken') + end + end + + context 'when the primary email is unconfirmed' do + let!(:unconfirmed_user) { create(:user, :unconfirmed, email: 'foo@example.com') } + + it 'returns 409 conflict error' do + expect do + post api('/users', admin), + params: { + name: 'foo', + email: unconfirmed_user.email, + password: 'password', + username: 'TEST' + } + end.to change { User.count }.by(0) + expect(response).to have_gitlab_http_status(:conflict) + expect(json_response['message']).to eq('Email has already been taken') + end + end + end + + context 'when user with a secondary email exists' do + context 'when the secondary email is confirmed' do + let!(:email) { create(:email, :confirmed, email: 'foo@example.com') } + + it 'returns 409 conflict error' do + expect do + post api('/users', admin), + params: { + name: 'foo', + email: email.email, + password: 'password', + username: 'TEST' + } + end.to change { User.count }.by(0) + expect(response).to have_gitlab_http_status(:conflict) + expect(json_response['message']).to eq('Email has already been taken') + end + end + + context 'when the secondary email is unconfirmed' do + let!(:email) { create(:email, email: 'foo@example.com') } + + it 'does not create user' do + expect do + post api('/users', admin), + params: { + name: 'foo', + email: email.email, + password: 'password', + username: 'TEST' + } + end.to change { User.count }.by(0) + expect(response).to have_gitlab_http_status(:bad_request) + end + end + end + context "scopes" do let(:user) { admin } let(:path) { '/users' } @@ -1663,6 +1738,54 @@ RSpec.describe API::Users do expect(@user.reload.username).to eq(@user.username) end end + + context 'when user with a primary email exists' do + context 'when the primary email is confirmed' do + let!(:confirmed_user) { create(:user, email: 'foo@example.com') } + + it 'returns 409 conflict error' do + put api("/users/#{user.id}", admin), params: { email: confirmed_user.email } + + expect(response).to have_gitlab_http_status(:conflict) + expect(user.reload.email).not_to eq(confirmed_user.email) + end + end + + context 'when the primary email is unconfirmed' do + let!(:unconfirmed_user) { create(:user, :unconfirmed, email: 'foo@example.com') } + + it 'returns 409 conflict error' do + put api("/users/#{user.id}", admin), params: { email: unconfirmed_user.email } + + expect(response).to have_gitlab_http_status(:conflict) + expect(user.reload.email).not_to eq(unconfirmed_user.email) + end + end + end + + context 'when user with a secondary email exists' do + context 'when the secondary email is confirmed' do + let!(:email) { create(:email, :confirmed, email: 'foo@example.com') } + + it 'returns 409 conflict error' do + put api("/users/#{user.id}", admin), params: { email: email.email } + + expect(response).to have_gitlab_http_status(:conflict) + expect(user.reload.email).not_to eq(email.email) + end + end + + context 'when the secondary email is unconfirmed' do + let!(:email) { create(:email, email: 'foo@example.com') } + + it 'does not update email' do + put api("/users/#{user.id}", admin), params: { email: email.email } + + expect(response).to have_gitlab_http_status(:bad_request) + expect(user.reload.email).not_to eq(email.email) + end + end + end end describe "PUT /user/:id/credit_card_validation" do @@ -2227,6 +2350,50 @@ RSpec.describe API::Users do expect(json_response['confirmed_at']).not_to be_nil end + + context 'when user with a primary email exists' do + context 'when the primary email is confirmed' do + let!(:confirmed_user) { create(:user, email: 'foo@example.com') } + + it 'returns 400 error' do + post api("/users/#{user.id}/emails", admin), params: { email: confirmed_user.email } + + expect(response).to have_gitlab_http_status(:bad_request) + end + end + + context 'when the primary email is unconfirmed' do + let!(:unconfirmed_user) { create(:user, :unconfirmed, email: 'foo@example.com') } + + it 'returns 400 error' do + post api("/users/#{user.id}/emails", admin), params: { email: unconfirmed_user.email } + + expect(response).to have_gitlab_http_status(:bad_request) + end + end + end + + context 'when user with a secondary email exists' do + context 'when the secondary email is confirmed' do + let!(:email) { create(:email, :confirmed, email: 'foo@example.com') } + + it 'returns 400 error' do + post api("/users/#{user.id}/emails", admin), params: { email: email.email } + + expect(response).to have_gitlab_http_status(:bad_request) + end + end + + context 'when the secondary email is unconfirmed' do + let!(:email) { create(:email, email: 'foo@example.com') } + + it 'returns 400 error' do + post api("/users/#{user.id}/emails", admin), params: { email: email.email } + + expect(response).to have_gitlab_http_status(:bad_request) + end + end + end end describe 'GET /user/:id/emails' do -- cgit v1.2.3