Commit 86a8eee1 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@13-6-stable-ee

parent 1b517a5a
import { joinPaths } from '~/lib/utils/url_utility';
export const pathGenerator = (imageDetails, ending = '?format=json') => {
// this method is a temporary workaround, to be removed with graphql implementation
// https://gitlab.com/gitlab-org/gitlab/-/issues/276432
......@@ -12,5 +14,12 @@ export const pathGenerator = (imageDetails, ending = '?format=json') => {
return acc;
}, [])
.join('/');
return `/${basePath}/registry/repository/${imageDetails.id}/tags${ending}`;
return joinPaths(
window.gon.relative_url_root,
`/${basePath}`,
'/registry/repository/',
`${imageDetails.id}`,
`tags${ending}`,
);
};
......@@ -202,6 +202,9 @@ export default {
shouldShowAccessibilityReport() {
return this.mr.accessibilityReportPath;
},
formattedHumanAccess() {
return (this.mr.humanAccess || '').toLowerCase();
},
},
watch: {
state(newVal, oldVal) {
......@@ -439,7 +442,7 @@ export default {
class="mr-widget-workflow"
:pipeline-path="mr.mergeRequestAddCiConfigPath"
:pipeline-svg-path="mr.pipelinesEmptySvgPath"
:human-access="mr.humanAccess.toLowerCase()"
:human-access="formattedHumanAccess"
:user-callouts-path="mr.userCalloutsPath"
:user-callout-feature-id="mr.suggestPipelineFeatureId"
@dismiss="dismissSuggestPipelines"
......
......@@ -6,14 +6,14 @@ module MembersHelper
text = 'Are you sure you want to'
action =
if member.request?
if member.invite?
"revoke the invitation for #{member.invite_email} to join"
elsif member.request?
if member.user == user
'withdraw your access request for'
else
"deny #{member.user.name}'s request to join"
end
elsif member.invite?
"revoke the invitation for #{member.invite_email} to join"
else
if member.user
"remove #{member.user.name} from"
......
......@@ -20,8 +20,8 @@ module Members
emails.each do |email|
next if existing_member?(source, email)
next if existing_invite?(source, email)
next if existing_request?(source, email)
if existing_user?(email)
add_existing_user_as_member(current_user, source, params, email)
......@@ -44,8 +44,7 @@ module Members
access_level: params[:access_level],
invite_email: email,
created_by_id: current_user.id,
expires_at: params[:expires_at],
requested_at: Time.current.utc)
expires_at: params[:expires_at])
unless new_member.valid? && new_member.persisted?
errors[params[:email]] = new_member.errors.full_messages.to_sentence
......@@ -92,6 +91,17 @@ module Members
false
end
def existing_request?(source, email)
existing_request = source.requesters.with_user_by_email(email).exists?
if existing_request
errors[email] = "Member cannot be invited because they already requested to join #{source.name}"
return true
end
false
end
def existing_user(email)
User.find_by_email(email)
end
......
......@@ -67,7 +67,7 @@ module Projects
@project
rescue ActiveRecord::RecordInvalid => e
message = "Unable to save #{e.record.type}: #{e.record.errors.full_messages.join(", ")} "
message = "Unable to save #{e.inspect}: #{e.record.errors.full_messages.join(", ")}"
fail(error: message)
rescue => e
@project.errors.add(:base, e.message) if @project
......@@ -122,8 +122,9 @@ module Projects
only_concrete_membership: true)
if group_access_level > GroupMember::NO_ACCESS
current_user.project_authorizations.create!(project: @project,
access_level: group_access_level)
current_user.project_authorizations.safe_find_or_create_by!(
project: @project,
access_level: group_access_level)
end
if Feature.enabled?(:specialized_project_authorization_workers)
......
---
title: Add different string encoding method in rack middleware
merge_request: 49044
author:
type: fixed
---
title: Fix container_registry url for relative urls
merge_request: 48661
author:
type: fixed
---
title: Resolve Members page 500 error after Invitation sent via API
merge_request: 48937
author:
type: fixed
---
title: Fix MR rendering issue when user is tool admin and not project member
merge_request: 49258
author:
type: fixed
---
title: Fix error 500s creating projects concurrently
merge_request: 48571
author:
type: fixed
---
title: Update Rake check and docs to require Ruby 2.7
merge_request: 48552
author:
type: changed
......@@ -121,6 +121,7 @@ class ObjectStoreSettings
if section['enabled'] && target_config['bucket'].blank?
missing_bucket_for(store_type)
next
end
# Map bucket (external name) -> remote_directory (internal representation)
......
......@@ -97,7 +97,7 @@ Example response:
{
"id": 1,
"invite_email": "member@example.org",
"invited_at": "2020-10-22T14:13:35Z",
"created_at": "2020-10-22T14:13:35Z",
"access_level": 30,
"expires_at": "2020-11-22T14:13:35Z",
"user_name": "Raymond Smith",
......
......@@ -224,12 +224,6 @@ make
sudo make install
```
Then install the Bundler gem (a version below 2.x):
```shell
sudo gem install bundler --no-document --version '< 2'
```
## 3. Go
In GitLab 8.0 and later, GitLab has several daemons written in Go. To install
......
......@@ -45,7 +45,13 @@ Please consider using a virtual machine to run GitLab.
### Ruby versions
GitLab requires Ruby (MRI) 2.6. Beginning in GitLab 12.2, we no longer support Ruby 2.5 and lower.
From GitLab 13.6:
- Ruby 2.7 and later is required.
From GitLab 12.2:
- Ruby 2.6 and later is required.
You must use the standard MRI implementation of Ruby.
We love [JRuby](https://www.jruby.org/) and [Rubinius](https://github.com/rubinius/rubinius#the-rubinius-language-platform), but GitLab
......
......@@ -312,6 +312,8 @@ installation-specific upgrade instructions, based on how you installed GitLab:
### 13.6.0
Ruby 2.7.2 is required. GitLab will not start with Ruby 2.6.6 or older versions.
The required Git version is Git v2.29 or higher.
### 13.3.0
......
......@@ -61,8 +61,8 @@ sudo service gitlab stop
### 3. Update Ruby
NOTE: Beginning in GitLab 12.2, we only support Ruby 2.6 or higher, and dropped
support for Ruby 2.5. Be sure to upgrade if necessary.
NOTE: Beginning in GitLab 13.6, we only support Ruby 2.7 or higher, and dropped
support for Ruby 2.6. Be sure to upgrade if necessary.
You can check which version you are running with `ruby -v`.
......@@ -70,21 +70,15 @@ Download Ruby and compile it:
```shell
mkdir /tmp/ruby && cd /tmp/ruby
curl --remote-name --progress https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.6.tar.gz
echo '2d78048e293817f38d4ede4ebc7873013e97bb0b ruby-2.6.6.tar.gz' | shasum -c - && tar xzf ruby-2.6.6.tar.gz
cd ruby-2.6.6
curl --remote-name --progress https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.2.tar.gz
echo 'cb9731a17487e0ad84037490a6baf8bfa31a09e8 ruby-2.7.2.tar.gz' | shasum -c - && tar xzf ruby-2.7.2.tar.gz
cd ruby-2.7.2
./configure --disable-install-rdoc
make
sudo make install
```
Install Bundler:
```shell
sudo gem install bundler --no-document --version '< 2'
```
### 4. Update Node.js
NOTE: To check the minimum required Node.js version, see [Node.js versions](../install/requirements.md#nodejs-versions).
......
......@@ -188,15 +188,12 @@ To set your current status:
1. Set the desired emoji and/or status message.
1. Click **Set status**. Alternatively, you can click **Remove status** to remove your user status entirely.
![Busy status indicator](img/busy_status_indicator_v13_6.png)
or
1. Click your avatar.
1. Select **Profile**.
1. Click **Edit profile** (pencil icon).
1. Enter your status message in the **Your status** text field.
1. Alternatively, select the **Busy** checkbox ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/259649) in GitLab 13.6}.
1. Click **Add status emoji** (smiley face), and select the desired emoji.
1. Click **Update profile settings**.
......@@ -204,6 +201,44 @@ You can also set your current status [using the API](../../api/users.md#user-sta
If you previously selected the "Busy" checkbox, remember to deselect it when you become available again.
## Busy status indicator
> - Introduced in GitLab 13.6.
> - It's [deployed behind a feature flag](../feature_flags.md), disabled by default.
> - It's disabled on GitLab.com.
> - It's not recommended for production use.
> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-busy-status-feature).
To indicate to others that you are busy, you can set an indicator
![Busy status indicator](img/busy_status_indicator_v13_6.png)
To set the busy status indicator, either:
- Set it directly:
1. Click your avatar.
1. Click **Set status**, or **Edit status** if you have already set a status.
1. Select the **Busy** checkbox
- Set it on your profile:
1. Click your avatar.
1. Select **Profile**.
1. Click **Edit profile** (**{pencil}**).
1. Select the **Busy** checkbox
### Enable busy status feature
The busy status feature is deployed behind a feature flag and is **disabled by default**.
[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md) can enable it for your instance from the [rails console](../../administration/feature_flags.md#start-the-gitlab-rails-console).
To enable it:
```ruby
Feature.enable(:set_user_availability_status)
```
## Commit email
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/21598) in GitLab 11.4.
......
......@@ -4,7 +4,7 @@ module API
module Entities
class Invitation < Grape::Entity
expose :access_level
expose :requested_at
expose :created_at
expose :expires_at
expose :invite_email
expose :invite_token
......
......@@ -93,7 +93,8 @@ module Gitlab
# We try to encode the string from ASCII-8BIT to UTF8. If we failed to do
# so for certain characters in the string, those chars are probably incomplete
# multibyte characters.
string.encode(Encoding::UTF_8).match?(NULL_BYTE_REGEX)
string.dup.force_encoding(Encoding::UTF_8).match?(NULL_BYTE_REGEX)
rescue ArgumentError, Encoding::UndefinedConversionError
# If we're here, we caught a malformed string. Return true
true
......
......@@ -7,7 +7,7 @@ module SystemCheck
set_check_pass -> { "yes (#{self.current_version})" }
def self.required_version
@required_version ||= Gitlab::VersionInfo.new(2, 5, 3)
@required_version ||= Gitlab::VersionInfo.new(2, 7, 2)
end
def self.current_version
......
......@@ -88,6 +88,7 @@ RSpec.describe ObjectStoreSettings do
config['object_store']['objects']['pages'].delete('bucket')
expect { subject }.not_to raise_error
expect(settings.pages['object_store']).to eq(nil)
end
context 'with legacy config' do
......
......@@ -8,6 +8,10 @@ describe('Utils', () => {
id: 1,
};
beforeEach(() => {
window.gon.relative_url_root = null;
});
it('returns the fetch url when no ending is passed', () => {
expect(pathGenerator(imageDetails)).toBe('/foo/bar/registry/repository/1/tags?format=json');
});
......@@ -16,7 +20,7 @@ describe('Utils', () => {
expect(pathGenerator(imageDetails, '/foo')).toBe('/foo/bar/registry/repository/1/tags/foo');
});
it.each`
describe.each`
path | name | result
${'foo/foo'} | ${''} | ${'/foo/foo/registry/repository/1/tags?format=json'}
${'foo/foo/foo'} | ${'foo'} | ${'/foo/foo/registry/repository/1/tags?format=json'}
......@@ -26,8 +30,15 @@ describe('Utils', () => {
${'foo/foo/baz/foo/bar'} | ${'foo/bar'} | ${'/foo/foo/baz/registry/repository/1/tags?format=json'}
${'baz/foo/foo'} | ${'foo'} | ${'/baz/foo/registry/repository/1/tags?format=json'}
${'baz/foo/bar'} | ${'foo'} | ${'/baz/foo/bar/registry/repository/1/tags?format=json'}
`('returns the correct path when path is $path and name is $name', ({ name, path, result }) => {
expect(pathGenerator({ id: 1, name, path })).toBe(result);
`('when path is $path and name is $name', ({ name, path, result }) => {
it('returns the correct value', () => {
expect(pathGenerator({ id: 1, name, path })).toBe(result);
});
it('produces a correct relative url', () => {
window.gon.relative_url_root = '/gitlab';
expect(pathGenerator({ id: 1, name, path })).toBe(`/gitlab${result}`);
});
});
it('returns the url unchanged when imageDetails have no name', () => {
......
......@@ -260,6 +260,20 @@ describe('mrWidgetOptions', () => {
});
});
});
describe('formattedHumanAccess', () => {
it('when user is a tool admin but not a member of project', () => {
vm.mr.humanAccess = null;
expect(vm.formattedHumanAccess).toEqual('');
});
it('when user a member of the project', () => {
vm.mr.humanAccess = 'Owner';
expect(vm.formattedHumanAccess).toEqual('owner');
});
});
});
describe('methods', () => {
......
......@@ -33,6 +33,16 @@ RSpec.describe MembersHelper do
expect(remove_member_message(group_member_invite)).to eq "Are you sure you want to remove this orphaned member from the #{group.name} group and any subresources?"
end
end
context 'a pending member invitation with no user associated' do
before do
project_member_invite.update_columns(invite_email: "#{SecureRandom.hex}@example.com", invite_token: 'some-token', user_id: nil)
end
it 'does not error when there is an invitation for the requestor' do
expect(remove_member_message(project_member_invite)).to eq "Are you sure you want to revoke the invitation for #{project_member_invite.invite_email} to join the #{project.full_name} project?"
end
end
end
describe '#remove_member_title' do
......
# frozen_string_literal: true
require 'spec_helper'
require "rack/test"
......@@ -104,6 +103,12 @@ RSpec.describe Gitlab::Middleware::HandleMalformedStrings do
expect(subject.call(env)).not_to eq error_400
end
it 'does not reject correct encoded password with special characters' do
env = env_for.merge(auth_env("username", "RçKszEwéC5kFnû∆f243fycGu§Gh9ftDj!U", nil))
expect(subject.call(env)).not_to eq error_400
end
end
context 'in params' do
......
......@@ -58,7 +58,7 @@ RSpec.describe API::Invitations do
it 'does not transform the requester into a proper member' do
expect do
post api("/#{source_type.pluralize}/#{source.id}/invitations", maintainer),
params: { email: email, access_level: Member::MAINTAINER }
params: { email: access_requester.email, access_level: Member::MAINTAINER }
expect(response).to have_gitlab_http_status(:created)
end.not_to change { source.members.count }
......@@ -71,7 +71,7 @@ RSpec.describe API::Invitations do
params: { email: email, access_level: Member::DEVELOPER }
expect(response).to have_gitlab_http_status(:created)
end.to change { source.requesters.count }.by(1)
end.to change { source.members.invite.count }.by(1)
end
it 'invites a list of new email addresses' do
......@@ -82,7 +82,7 @@ RSpec.describe API::Invitations do
params: { email: email_list, access_level: Member::DEVELOPER }
expect(response).to have_gitlab_http_status(:created)
end.to change { source.requesters.count }.by(2)
end.to change { source.members.invite.count }.by(2)
end
end
......@@ -140,7 +140,7 @@ RSpec.describe API::Invitations do
it 'invites a member' do
expect do
subject
end.to change { source.requesters.count }.by(1)
end.to change { source.members.invite.count }.by(1)
expect(response).to have_gitlab_http_status(:created)
end
......
......@@ -280,6 +280,20 @@ RSpec.describe 'Git HTTP requests' do
project.add_developer(user)
end
context 'when user is using credentials with special characters' do
context 'with password with special characters' do
before do
user.update!(password: 'RKszEwéC5kFnû∆f243fycGu§Gh9ftDj!U')
end
it 'allows clones' do
download(path, user: user.username, password: user.password) do |response|
expect(response).to have_gitlab_http_status(:ok)
end
end
end
end
context 'but the repo is disabled' do
let(:project) { create(:project, :wiki_repo, :private, :repository_disabled, :wiki_enabled) }
......
......@@ -63,4 +63,15 @@ RSpec.describe Members::InviteService do
expect(result[:status]).to eq(:error)
expect(result[:message][invited_member.invite_email]).to eq("Member already invited to #{project.name}")
end
it 'does not add a member with an access_request' do
requested_member = create(:project_member, :access_request, project: project)
params = { email: requested_member.user.email,
access_level: Gitlab::Access::GUEST }
result = described_class.new(user, params).execute(project)
expect(result[:status]).to eq(:error)
expect(result[:message][requested_member.user.email]).to eq("Member cannot be invited because they already requested to join #{project.name}")
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment