Commit c8c88bcd authored by GitLab Bot's avatar GitLab Bot

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2018-08-22

# Conflicts:
#	CHANGELOG.md
#	app/assets/javascripts/api.js
#	app/assets/stylesheets/framework/variables.scss

[ci skip]
parents 4f277d3c f3d9e19b
......@@ -4,6 +4,7 @@ entry.
## 11.2.0 (2018-08-22)
<<<<<<< HEAD
### Security (7 changes)
- Bump Gitaly to 0.117.1 for Rouge update. !21277
......@@ -13,6 +14,15 @@ entry.
- Bump rugged to 0.27.4 for security fixes.
- Don't expose project names in various counters.
- Fixed XSS in branch name in Web IDE.
=======
### Security (5 changes)
- Bump Gitaly to 0.117.1 for Rouge update. !21277
- Fix symlink vulnerability in project import.
- Bump rugged to 0.27.4 for security fixes.
- Fixed XSS in branch name in Web IDE.
- Adding CSRF protection to Hooks test action.
>>>>>>> upstream/master
### Removed (1 change)
......@@ -72,9 +82,15 @@ entry.
- Fix bug setting http headers in Files API. !20938
- Rails5: fix flaky spec. !20953 (Jasper Maes)
- Fixed list of projects not loading in group boards. !20955
<<<<<<< HEAD
- Fix rendering of the context lines in MR diffs page. !20968
- Fix navigation to First and Next discussion on MR Changes tab. !20968
- Fix autosave and ESC confirmation issues for MR discussions. !20968
=======
- Fix autosave and ESC confirmation issues for MR discussions. !20968
- Fix navigation to First and Next discussion on MR Changes tab. !20968
- Fix rendering of the context lines in MR diffs page. !20968
>>>>>>> upstream/master
- fix error caused when using the search bar while unauthenticated. !20970
- Fix GPG status badge loading regressions. !20987
- Ensure links in notifications footer are not escaped. !21000
......@@ -88,6 +104,7 @@ entry.
- Fix issue stopping Instance Statistics javascript to be executed. !21211
- Fix broken JavaScript in IE11. !21214
- Improve JUnit test reports in merge request widgets. !49966
<<<<<<< HEAD
- Fix handling of annotated tags when Gitaly is not in use.
- Properly handle colons in URL passwords.
- Renders test reports for resolved failures and resets error state.
......@@ -100,6 +117,20 @@ entry.
- Add missing predefined variable and fix docs.
- Allow updating a project's avatar without other params. (Jamie Schembri)
- Fix the UI for listing system-level labels.
=======
- Properly handle colons in URL passwords.
- Renders test reports for resolved failures and resets error state.
- Fix handling of annotated tags when Gitaly is not in use.
- Fix serialization of LegacyDiffNote.
- Escapes milestone and label's names on flash notice when promoting them.
- Allow to toggle notifications for issues due soon.
- Sanitize git URL in import errors. (Jamie Schembri)
- Add missing predefined variable and fix docs.
- Allow updating a project's avatar without other params. (Jamie Schembri)
- Fix the UI for listing system-level labels.
- Update hamlit to fix ruby 2.5 incompatibilities, fixes #42045. (Matthew Dawson)
- Fix updated_at if created_at is set for Note API.
>>>>>>> upstream/master
- Fix search bar text input alignment.
### Changed (32 changes, 7 of them are from the community)
......@@ -133,9 +164,15 @@ entry.
- Update to Rouge 3.2.0, including Terraform and Crystal lexer and bug fixes. !20991
- Update design of project templates. !21012
- Update to Rouge 3.2.1, which includes a critical fix to the Perl Lexer. !21263
<<<<<<< HEAD
- Redesign GCP offer banner.
- Add a 10 ms bucket for SQL timings.
- Show one digit after dot in commit_per_day value in charts page. (msdundar)
=======
- Add a 10 ms bucket for SQL timings.
- Show one digit after dot in commit_per_day value in charts page. (msdundar)
- Redesign GCP offer banner.
>>>>>>> upstream/master
### Performance (30 changes, 10 of them are from the community)
......@@ -206,6 +243,7 @@ entry.
- Clean orphaned files in object storage. !20918
- Adds frontend support to render test reports on the MR widget. !20936
- Trigger system hooks when project is archived/unarchived. !20995
<<<<<<< HEAD
- Emails on push recipients now accepts formats like John Doe <johndoe@example.com>. (George Thomas)
- Added button to regenerate 2FA codes. (Luke Picciau)
- Improve danger confirmation modals by focusing input field. (Jamie Schembri)
......@@ -213,6 +251,15 @@ entry.
- Custom Wiki Sidebar Support Issue 14995. (Josh Sooter)
- Clicking CI icon in Web IDE now opens up pipelines panel.
- Enabled deletion of files in the Web IDE.
=======
- Custom Wiki Sidebar Support Issue 14995. (Josh Sooter)
- Emails on push recipients now accepts formats like John Doe <johndoe@example.com>. (George Thomas)
- Add new model for tracking label events.
- Improve danger confirmation modals by focusing input field. (Jamie Schembri)
- Clicking CI icon in Web IDE now opens up pipelines panel.
- Enabled deletion of files in the Web IDE.
- Added button to regenerate 2FA codes. (Luke Picciau)
>>>>>>> upstream/master
### Other (26 changes, 7 of them are from the community)
......@@ -238,9 +285,15 @@ entry.
- Update git rerere link in docs. !21060 (gfyoung)
- Add 'tabindex' attribute support on Icon component to show BS4 popover on trigger type 'focus'. !21066
- Add a Gitlab::Profiler.print_by_total_time convenience method for profiling from a Rails console.
<<<<<<< HEAD
- Disables toggle comments button if diff has no discussions.
- Automatically expand runner's settings block when linking to the runner's settings page.
- Increases title column on modal for reports.
=======
- Automatically expand runner's settings block when linking to the runner's settings page.
- Increases title column on modal for reports.
- Disables toggle comments button if diff has no discussions.
>>>>>>> upstream/master
- Moves help_popover component to a common location.
......
......@@ -119,14 +119,14 @@ gem 'dropzonejs-rails', '~> 0.7.1'
# for backups
gem 'fog-aws', '~> 2.0.1'
gem 'fog-core', '~> 1.44'
gem 'fog-google', '~> 1.3.3'
gem 'fog-google', '~> 1.7.1'
gem 'fog-local', '~> 0.3'
gem 'fog-openstack', '~> 0.1'
gem 'fog-rackspace', '~> 0.1.1'
gem 'fog-aliyun', '~> 0.2.0'
# for Google storage
gem 'google-api-client', '~> 0.19.8'
gem 'google-api-client', '~> 0.23'
# for aws storage
gem 'unf', '~> 0.1.4'
......
......@@ -263,11 +263,11 @@ GEM
builder
excon (~> 0.58)
formatador (~> 0.2)
fog-google (1.3.3)
fog-google (1.7.1)
fog-core
fog-json
fog-xml
google-api-client (~> 0.19.1)
google-api-client (~> 0.23.0)
fog-json (1.0.2)
fog-core (~> 1.0)
multi_json (~> 1.10)
......@@ -354,7 +354,7 @@ GEM
actionpack (>= 3.0)
multi_json
request_store (>= 1.0)
google-api-client (0.19.8)
google-api-client (0.23.4)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.5, < 0.7.0)
httpclient (>= 2.8.1, < 3.0)
......@@ -767,7 +767,7 @@ GEM
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
retriable (3.1.1)
retriable (3.1.2)
rinku (2.0.0)
rotp (2.1.2)
rouge (3.2.1)
......@@ -1065,7 +1065,7 @@ DEPENDENCIES
fog-aliyun (~> 0.2.0)
fog-aws (~> 2.0.1)
fog-core (~> 1.44)
fog-google (~> 1.3.3)
fog-google (~> 1.7.1)
fog-local (~> 0.3)
fog-openstack (~> 0.1)
fog-rackspace (~> 0.1.1)
......@@ -1086,7 +1086,7 @@ DEPENDENCIES
gitlab-styles (~> 2.4)
gitlab_omniauth-ldap (~> 2.0.4)
gon (~> 6.2)
google-api-client (~> 0.19.8)
google-api-client (~> 0.23)
google-protobuf (= 3.5.1)
gpgme
grape (~> 1.0)
......
......@@ -266,11 +266,11 @@ GEM
builder
excon (~> 0.58)
formatador (~> 0.2)
fog-google (1.3.3)
fog-google (1.7.1)
fog-core
fog-json
fog-xml
google-api-client (~> 0.19.1)
google-api-client (~> 0.23.0)
fog-json (1.0.2)
fog-core (~> 1.0)
multi_json (~> 1.10)
......@@ -357,7 +357,7 @@ GEM
actionpack (>= 3.0)
multi_json
request_store (>= 1.0)
google-api-client (0.19.8)
google-api-client (0.23.4)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.5, < 0.7.0)
httpclient (>= 2.8.1, < 3.0)
......@@ -777,7 +777,7 @@ GEM
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
retriable (3.1.1)
retriable (3.1.2)
rinku (2.0.0)
rotp (2.1.2)
rouge (3.2.0)
......@@ -1077,7 +1077,7 @@ DEPENDENCIES
fog-aliyun (~> 0.2.0)
fog-aws (~> 2.0.1)
fog-core (~> 1.44)
fog-google (~> 1.3.3)
fog-google (~> 1.7.1)
fog-local (~> 0.3)
fog-openstack (~> 0.1)
fog-rackspace (~> 0.1.1)
......@@ -1098,7 +1098,7 @@ DEPENDENCIES
gitlab-styles (~> 2.4)
gitlab_omniauth-ldap (~> 2.0.4)
gon (~> 6.2)
google-api-client (~> 0.19.8)
google-api-client (~> 0.23)
google-protobuf (= 3.5.1)
gpgme
grape (~> 1.0)
......
11.2.0-pre
11.3.0-pre
......@@ -274,6 +274,7 @@ const Api = {
return axios.get(url, { params });
},
<<<<<<< HEAD
approverUsers(search, options, callback = $.noop) {
const url = Api.buildUrl('/autocomplete/users.json');
return axios
......@@ -310,6 +311,8 @@ const Api = {
});
},
=======
>>>>>>> upstream/master
buildUrl(url) {
let urlRoot = '';
if (gon.relative_url_root != null) {
......
......@@ -4,11 +4,11 @@
$text-color: $gl-text-color;
$brand-primary: $gl-primary;
$brand-success: $gl-success;
$brand-info: $gl-info;
$brand-warning: $gl-warning;
$brand-danger: $gl-danger;
$brand-primary: $blue-500;
$brand-success: $green-500;
$brand-info: $blue-500;
$brand-warning: $orange-500;
$brand-danger: $red-500;
$border-radius-base: 3px !default;
......
......@@ -8,7 +8,7 @@
float: left;
margin-right: 15px;
border-radius: $avatar-radius;
border: 1px solid $avatar-border;
border: 1px solid $gray-normal;
&.s16 { @include avatar-size(16px, 6px); }
&.s18 { @include avatar-size(18px, 6px); }
&.s19 { @include avatar-size(19px, 6px); }
......@@ -36,7 +36,7 @@
width: 40px;
height: 40px;
padding: 0;
background: $avatar-background;
background: $gray-lightest;
overflow: hidden;
&.avatar-inline {
......@@ -66,7 +66,7 @@
}
&:not([href]):hover {
border-color: darken($avatar-border, 10%);
border-color: darken($gray-normal, 10%);
}
}
......@@ -74,7 +74,7 @@
text-align: center;
vertical-align: top;
color: $identicon-fg-color;
background-color: $identicon-gray;
background-color: $gray-darker;
// Sizes
&.s16 { font-size: 12px; line-height: 1.33; }
......@@ -98,7 +98,7 @@
&.bg4 { background-color: $identicon-blue; }
&.bg5 { background-color: $identicon-teal; }
&.bg6 { background-color: $identicon-orange; }
&.bg7 { background-color: $identicon-gray; }
&.bg7 { background-color: $gray-darker; }
}
.avatar-container {
......@@ -126,7 +126,7 @@
.avatar-counter {
background-color: $gray-darkest;
color: $white-light;
border: 1px solid $avatar-border;
border: 1px solid $gray-normal;
border-radius: 1em;
font-family: $regular-font;
font-size: 9px;
......
.badge.badge-pill {
font-weight: $gl-font-weight-normal;
background-color: $badge-bg;
color: $badge-color;
color: $gl-text-color-secondary;
vertical-align: baseline;
}
......@@ -452,14 +452,14 @@
}
.btn-missing {
color: $notes-light-color;
color: $gl-text-color-secondary;
border: 1px dashed $border-gray-normal-dashed;
border-radius: $border-radius-default;
&:hover,
&:active,
&:focus {
color: $notes-light-color;
color: $gl-text-color-secondary;
background-color: $white-normal;
}
}
......
......@@ -352,7 +352,7 @@ img.emoji {
border-color: $border-color !important;
.dz-upload {
background: $gl-success !important;
background: $green-500 !important;
}
}
......
......@@ -206,7 +206,7 @@
&.focus,
&.focus:hover {
border-color: $blue-300;
box-shadow: 0 0 4px $search-input-focus-shadow-color;
box-shadow: 0 0 4px $dropdown-input-focus-shadow;
}
gl-emoji {
......
......@@ -554,7 +554,7 @@
float: left;
margin-right: 5px;
border-radius: 50%;
border: 1px solid $avatar-border;
border: 1px solid $gray-normal;
}
.with-performance-bar .navbar-gitlab {
......
......@@ -11,7 +11,7 @@
.ci-status-icon-failed {
svg {
fill: $gl-danger;
fill: $red-500;
}
&.add-border {
......
......@@ -26,12 +26,12 @@
&.status-box-closed,
&.status-box-mr-closed {
background-color: $gl-danger;
background-color: $red-500;
}
&.status-box-issue-closed,
&.status-box-mr-merged {
background-color: $gl-primary;
background-color: $blue-500;
}
&.status-box-open {
......
......@@ -308,19 +308,9 @@ $tanuki-yellow: #fca326;
/*
* State colors:
*/
$gl-primary: $blue-500;
$gl-success: $green-500;
$gl-success-focus: rgba($gl-success, 0.4);
$gl-info: $blue-500;
$gl-warning: $orange-500;
$gl-danger: $red-500;
$green-500-focus: rgba($green-500, 0.4);
$gl-btn-active-background: rgba(0, 0, 0, 0.16);
$gl-btn-active-gradient: inset 0 2px 3px $gl-btn-active-background;
// Bootstrap override states
$success: $gl-success;
$info: $gl-info;
$warning: $gl-warning;
$danger: $gl-danger;
/*
* Commit Diff Colors
......@@ -341,10 +331,14 @@ $dark-diff-match-bg: rgba(255, 255, 255, 0.3);
$dark-diff-match-color: rgba(255, 255, 255, 0.1);
$file-mode-changed: #777;
$file-mode-changed: #777;
<<<<<<< HEAD
$diff-image-bg: #ddd;
$diff-image-info-color: grey;
=======
$diff-image-info-color: gray;
>>>>>>> upstream/master
$diff-swipe-border: #999;
$diff-view-modes-color: grey;
$diff-view-modes-color: gray;
$diff-view-modes-border: #c1c1c1;
$diff-jagged-border-gradient-color: darken($white-normal, 8%);
......@@ -384,7 +378,6 @@ $dropdown-member-form-control-width: 163px;
* Filtered Search
*/
$filtered-search-term-shadow-color: rgba(0, 0, 0, 0.09);
$dropdown-hover-color: $blue-400;
/*
* Contextual Sidebar
......@@ -399,7 +392,7 @@ $sidebar-milestone-toggle-bottom-margin: 10px;
* Buttons
*/
$btn-active-gray: #ececec;
$btn-active-gray-light: e4e7ed;
$btn-active-gray-light: #e4e7ed;
$btn-white-active: #848484;
$gl-btn-padding: 10px;
$gl-btn-line-height: 16px;
......@@ -410,7 +403,6 @@ $gl-btn-horz-padding: 12px;
* Badges
*/
$badge-bg: rgba(0, 0, 0, 0.07);
$badge-color: $gl-text-color-secondary;
/*
* Pagination
......@@ -418,21 +410,12 @@ $badge-color: $gl-text-color-secondary;
$pagination-padding-y: 6px;
$pagination-padding-x: 16px;
$pagination-line-height: 20px;
$pagination-border-color: $border-color;
$pagination-active-bg: $blue-600;
$pagination-active-border-color: $blue-600;
$pagination-hover-bg: $blue-50;
$pagination-hover-border-color: $border-color;
$pagination-hover-color: $gl-text-color;
$pagination-disabled-color: #cdcdcd;
$pagination-disabled-bg: $gray-light;
$pagination-disabled-border-color: $border-color;
/*
* Status icons
*/
$status-icon-size: 22px;
$status-icon-margin: $gl-btn-padding;
/*
* Award emoji
......@@ -445,16 +428,13 @@ $award-emoji-positive-add-lines: #bb9c13;
* Search Box
*/
$search-input-border-color: rgba($blue-400, 0.8);
$search-input-focus-shadow-color: $dropdown-input-focus-shadow;
$search-input-width: 240px;
$search-input-active-width: 320px;
$location-badge-active-bg: $blue-500;
$location-icon-color: #e7e9ed;
/*
* Notes
*/
$notes-light-color: $gl-text-color-secondary;
$note-disabled-comment-color: #b2b2b2;
$note-targe3-outside: #fffff0;
$note-targe3-inside: #ffffd3;
......@@ -475,7 +455,6 @@ $identicon-indigo: #e8eaf6;
$identicon-blue: #e3f2fd;
$identicon-teal: #e0f2f1;
$identicon-orange: #fbe9e7;
$identicon-gray: $gray-darker;
$identicon-fg-color: #555555;
/*
......@@ -491,7 +470,6 @@ $calendar-user-contrib-text: #959494;
$cycle-analytics-box-padding: 30px;
$cycle-analytics-box-text-color: #8c8c8c;
$cycle-analytics-big-font: 19px;
$cycle-analytics-dark-text: $gl-text-color;
$cycle-analytics-light-gray: #bfbfbf;
$cycle-analytics-dismiss-icon-color: #b2b2b2;
......@@ -519,9 +497,6 @@ $issue-board-list-difference-md: $issue-board-list-difference-sm + $issue-boards
* Avatar
*/
$avatar-radius: 50%;
$avatar-border: $gray-normal;
$avatar-border-hover: $gray-darker;
$avatar-background: $gray-lightest;
$gl-avatar-size: 40px;
/*
......
......@@ -14,3 +14,7 @@ $btn-line-height: 20px;
$table-accent-bg: $gray-light;
$card-border-color: $border-color;
$card-cap-bg: $gray-light;
$success: $green-500;
$info: $blue-500;
$warning: $orange-500;
$danger: $red-500;
......@@ -285,7 +285,7 @@
.total-time {
font-size: $cycle-analytics-big-font;
color: $cycle-analytics-dark-text;
color: $gl-text-color;
span {
color: $gl-text-color;
......
......@@ -144,7 +144,7 @@
color: $blue-800;
.avatar {
border-color: rgba($avatar-border, .2);
border-color: rgba($gray-normal, .2);
}
}
......@@ -240,7 +240,7 @@
}
a.edit-link:not([href]):hover {
color: rgba($avatar-border, .2);
color: rgba($gray-normal, .2);
}
.lock-edit, // uses same style, different js behaviour
......
......@@ -67,7 +67,7 @@
.dropdown-labels-error {
padding: 5px 10px;
margin-bottom: 10px;
background-color: $gl-danger;
background-color: $red-500;
color: $white-light;
}
......@@ -117,7 +117,7 @@
color: $blue-600;
&.remove-row {
color: $gl-danger;
color: $red-500;
}
}
}
......
......@@ -200,7 +200,7 @@
.mr-widget-icon {
font-size: 22px;
margin-right: $status-icon-margin;
margin-right: $gl-btn-padding;
}
.ci-status-icon svg {
......@@ -281,7 +281,7 @@
margin-bottom: 0;
&.has-conflicts .fa-exclamation-triangle {
color: $gl-warning;
color: $orange-500;
}
time {
......@@ -313,7 +313,7 @@
}
.danger {
color: $gl-danger;
color: $red-500;
}
.spacing,
......@@ -514,7 +514,7 @@
}
.mr-links {
padding-left: $status-icon-size + $status-icon-margin;
padding-left: $status-icon-size + $gl-btn-padding;
}
.mr-info-list {
......
......@@ -74,13 +74,13 @@
}
&.is-dropzone-hover {
border-color: $gl-success;
border-color: $green-500;
box-shadow: 0 0 2px $black-transparent,
0 0 4px $gl-success-focus;
0 0 4px $green-500-focus;
.comment-toolbar,
.nav-links {
border-color: $gl-success;
border-color: $green-500;
}
}
}
......
......@@ -443,7 +443,7 @@ ul.notes {
.note-headline-light,
.discussion-headline-light {
color: $notes-light-color;
color: $gl-text-color-secondary;
}
.discussion-headline-light {
......
......@@ -394,23 +394,23 @@
}
.vs-public {
color: $gl-primary;
color: $blue-500;
}
.vs-internal {
color: $gl-warning;
color: $orange-500;
}
.vs-private {
color: $gl-success;
color: $green-500;
}
.lfs-enabled {
color: $gl-success;
color: $green-500;
}
.lfs-disabled {
color: $gl-warning;
color: $orange-500;
}
.breadcrumb.repo-breadcrumb {
......@@ -732,7 +732,7 @@
background-color: transparent;
font-size: $gl-font-size;
line-height: $gl-btn-line-height;
color: $notes-light-color;
color: $gl-text-color-secondary;
}
.stat-link {
......
......@@ -24,12 +24,12 @@ $search-avatar-size: 16px;
.form-control:hover,
:not[readonly] {
border-color: lighten($blue-300, 20%);
box-shadow: 0 0 4px lighten($search-input-focus-shadow-color, 20%);
box-shadow: 0 0 4px lighten($dropdown-input-focus-shadow, 20%);
}
input[type='checkbox']:hover {
box-shadow: 0 0 2px 2px lighten($search-input-focus-shadow-color, 20%),
0 0 0 1px lighten($search-input-focus-shadow-color, 20%);
box-shadow: 0 0 2px 2px lighten($dropdown-input-focus-shadow, 20%),
0 0 0 1px lighten($dropdown-input-focus-shadow, 20%);
}
.search {
......@@ -181,7 +181,7 @@ input[type='checkbox']:hover {
width: $search-avatar-size;
height: $search-avatar-size;
border-radius: 50%;
border: 1px solid $avatar-border;
border: 1px solid $gray-normal;
}
}
......
......@@ -120,11 +120,11 @@
}
.warning-title {
color: $gl-warning;
color: $orange-500;
}
.danger-title {
color: $gl-danger;
color: $red-500;
}
.integration-settings-form {
......
......@@ -101,7 +101,7 @@ class Projects::CommitController < Projects::ApplicationController
@branch_name = create_new_branch? ? @commit.cherry_pick_branch_name : @start_branch
create_commit(Commits::CherryPickService, success_notice: "The #{@commit.change_type_title(current_user)} has been successfully cherry-picked.",
create_commit(Commits::CherryPickService, success_notice: "The #{@commit.change_type_title(current_user)} has been successfully cherry-picked into #{@branch_name}.",
success_path: -> { successful_change_path }, failure_path: failed_change_path)
end
......
......@@ -193,6 +193,7 @@ class Commit
# otherwise returns commit message without first line
def description
return safe_message if full_title.length >= 100
return no_commit_message if safe_message.blank?
safe_message.split("\n", 2)[1].try(:chomp)
end
......
......@@ -104,7 +104,7 @@ class Member < ActiveRecord::Base
def filter_by_2fa(value)
case value
when 'enabled'
left_join_users.merge(User.with_two_factor_indistinct)
left_join_users.merge(User.with_two_factor)
when 'disabled'
left_join_users.merge(User.without_two_factor)
else
......
......@@ -298,13 +298,16 @@ class User < ActiveRecord::Base
end
end
def self.with_two_factor_indistinct
joins("LEFT OUTER JOIN u2f_registrations AS u2f ON u2f.user_id = users.id")
.where("u2f.id IS NOT NULL OR users.otp_required_for_login = ?", true)
end
def self.with_two_factor
with_two_factor_indistinct.distinct(arel_table[:id])
with_u2f_registrations = <<-SQL
EXISTS (
SELECT *
FROM u2f_registrations AS u2f
WHERE u2f.user_id = users.id
) OR users.otp_required_for_login = ?
SQL
where(with_u2f_registrations, true)
end
def self.without_two_factor
......
......@@ -146,7 +146,6 @@ class GitPushService < BaseService
EventCreateService.new.push(project, current_user, build_push_data)
Ci::CreatePipelineService.new(project, current_user, build_push_data).execute(:push, mirror_update: mirror_update)
SystemHookPushWorker.perform_async(build_push_data.dup, :push_hooks)
project.execute_hooks(build_push_data.dup, :push_hooks)
project.execute_services(build_push_data.dup, :push_hooks)
......
---
title: "Avoid nil safe message"
merge_request: 21326
author: Yi Siliang
type: fixed
---
title: Add target branch name to cherrypick confirmation message
merge_request: 20846
author: George Andrinopoulos
type: other
---
title: 'API: Catch empty commit messages'
merge_request: 21322
author: Robert Schilling
type: fixed
---
title: 'API: Catch empty code content for project snippets'
merge_request: 21325
author: Robert Schilling
type: fixed
---
title: 'API: Add expiration date for shared projects to the project entity'
merge_request: 21104
author: Robert Schilling
type: added
---
title: Fix SQL error when sorting 2FA-enabled users by name in admin area
merge_request: 21324
author:
type: fixed
---
title: Bump fog-google to 1.7.0 and google-api-client to 0.23.0
merge_request: 21295
author:
type: fixed
---
title: Eliminate unnecessary and duplicate system hook fires
merge_request: 21337
author:
type: performance
......@@ -7,7 +7,7 @@ module Fog
class GoogleXML
class File < Fog::Model
module MonkeyPatch
def url(expires)
def url(expires, options = {})
requires :key
collection.get_https_url(key, expires)
end
......
......@@ -352,12 +352,14 @@ Example response:
{
"group_id": 4,
"group_name": "Twitter",
"group_access_level": 30
"group_access_level": 30,
"expires_at": null
},
{
"group_id": 3,
"group_name": "Gitlab Org",
"group_access_level": 10
"group_access_level": 10,
"expires_at": "2018-08-14"
}
]
}
......
......@@ -91,6 +91,7 @@ module API
group_link.group.name
end
expose :group_access, as: :group_access_level
expose :expires_at
end
class ProjectIdentity < Grape::Entity
......
......@@ -59,7 +59,7 @@ module API
params :simple_file_params do
requires :file_path, type: String, desc: 'The url encoded path to the file. Ex. lib%2Fclass%2Erb'
requires :branch, type: String, desc: 'Name of the branch to commit into. To create a new branch, also provide `start_branch`.'
requires :commit_message, type: String, desc: 'Commit message'
requires :commit_message, type: String, allow_blank: false, desc: 'Commit message'
optional :start_branch, type: String, desc: 'Name of the branch to start the new commit from'
optional :author_email, type: String, desc: 'The email of the author'
optional :author_name, type: String, desc: 'The name of the author'
......
......@@ -49,7 +49,7 @@ module API
params do
requires :title, type: String, desc: 'The title of the snippet'
requires :file_name, type: String, desc: 'The file name of the snippet'
requires :code, type: String, desc: 'The content of the snippet'
requires :code, type: String, allow_blank: false, desc: 'The content of the snippet'
optional :description, type: String, desc: 'The description of a snippet'
requires :visibility, type: String,
values: Gitlab::VisibilityLevel.string_values,
......@@ -78,7 +78,7 @@ module API
requires :snippet_id, type: Integer, desc: 'The ID of a project snippet'
optional :title, type: String, desc: 'The title of the snippet'
optional :file_name, type: String, desc: 'The file name of the snippet'
optional :code, type: String, desc: 'The content of the snippet'
optional :code, type: String, allow_blank: false, desc: 'The content of the snippet'
optional :description, type: String, desc: 'The description of a snippet'
optional :visibility, type: String,
values: Gitlab::VisibilityLevel.string_values,
......
......@@ -2,7 +2,7 @@ module QA
module Scenario
module Test
module Integration
class Github < Test::Instance
class Github < Test::Instance::All
tags :github
def perform(address, *rspec_options)
......
......@@ -2,7 +2,7 @@ module QA
module Scenario
module Test
module Integration
class Kubernetes < Test::Instance
class Kubernetes < Test::Instance::All
tags :kubernetes
end
end
......
......@@ -2,7 +2,7 @@ module QA
module Scenario
module Test
module Integration
class LDAP < Test::Instance
class LDAP < Test::Instance::All
tags :ldap
end
end
......
......@@ -6,7 +6,7 @@ module QA
# Run test suite against any GitLab instance where mattermost is enabled,
# including staging and on-premises installation.
#
class Mattermost < Test::Instance
class Mattermost < Test::Instance::All
tags :core, :mattermost
def perform(address, mattermost, *rspec_options)
......
......@@ -230,7 +230,7 @@ describe Projects::CommitController do
id: master_pickable_commit.id)
expect(response).to redirect_to project_commits_path(project, 'master')
expect(flash[:notice]).to eq('The commit has been successfully cherry-picked.')
expect(flash[:notice]).to eq('The commit has been successfully cherry-picked into master.')
end
end
......
......@@ -2,5 +2,6 @@ FactoryBot.define do
factory :project_group_link do
project
group
expires_at nil
end
end
......@@ -21,7 +21,7 @@ describe 'Cherry-pick Commits' do
uncheck 'create_merge_request'
click_button 'Cherry-pick'
end
expect(page).to have_content('The commit has been successfully cherry-picked.')
expect(page).to have_content('The commit has been successfully cherry-picked into master.')
end
end
......@@ -32,7 +32,7 @@ describe 'Cherry-pick Commits' do
uncheck 'create_merge_request'
click_button 'Cherry-pick'
end
expect(page).to have_content('The commit has been successfully cherry-picked.')
expect(page).to have_content('The commit has been successfully cherry-picked into master.')
end
end
......@@ -59,7 +59,7 @@ describe 'Cherry-pick Commits' do
page.within('#modal-cherry-pick-commit') do
click_button 'Cherry-pick'
end
expect(page).to have_content('The commit has been successfully cherry-picked. You can now submit a merge request to get this change into the original branch.')
expect(page).to have_content("The commit has been successfully cherry-picked into cherry-pick-#{master_pickable_commit.short_id}. You can now submit a merge request to get this change into the original branch.")
expect(page).to have_content("From cherry-pick-#{master_pickable_commit.short_id} into master")
end
end
......@@ -86,7 +86,7 @@ describe 'Cherry-pick Commits' do
click_button 'Cherry-pick'
end
expect(page).to have_content('The commit has been successfully cherry-picked.')
expect(page).to have_content('The commit has been successfully cherry-picked into feature.')
end
end
......
......@@ -225,6 +225,12 @@ eos
end
describe 'description' do
it 'returns no_commit_message when safe_message is blank' do
allow(commit).to receive(:safe_message).and_return(nil)
expect(commit.description).to eq('--no commit message')
end
it 'returns description of commit message if title less than 100 characters' do
message = <<eos
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec sodales id felis id blandit.
......
......@@ -343,6 +343,14 @@ describe User do
expect(users_with_two_factor).to eq([user_with_2fa.id])
expect(users_with_two_factor).not_to include(user_without_2fa.id)
end
it 'works with ORDER BY' do
user_with_2fa = create(:user, :two_factor_via_otp, :two_factor_via_u2f)
expect(described_class
.with_two_factor
.reorder_by_name).to eq([user_with_2fa])
end
end
describe ".without_two_factor" do
......
......@@ -313,7 +313,7 @@ describe API::Files do
describe "POST /projects/:id/repository/files/:file_path" do
let!(:file_path) { "new_subfolder%2Fnewfile%2Erb" }
let(:valid_params) do
let(:params) do
{
branch: "master",
content: "puts 8",
......@@ -322,7 +322,7 @@ describe API::Files do
end
it "creates a new file in project repo" do
post api(route(file_path), user), valid_params
post api(route(file_path), user), params
expect(response).to have_gitlab_http_status(201)
expect(json_response["file_path"]).to eq(CGI.unescape(file_path))
......@@ -337,20 +337,28 @@ describe API::Files do
expect(response).to have_gitlab_http_status(400)
end
it 'returns a 400 bad request if the commit message is empty' do
params[:commit_message] = ''
post api(route(file_path), user), params
expect(response).to have_gitlab_http_status(400)
end
it "returns a 400 if editor fails to create file" do
allow_any_instance_of(Repository).to receive(:create_file)
.and_raise(Gitlab::Git::CommitError, 'Cannot create file')
post api(route("any%2Etxt"), user), valid_params
post api(route("any%2Etxt"), user), params
expect(response).to have_gitlab_http_status(400)
end
context "when specifying an author" do
it "creates a new file with the specified author" do
valid_params.merge!(author_email: author_email, author_name: author_name)
params.merge!(author_email: author_email, author_name: author_name)
post api(route("new_file_with_author%2Etxt"), user), valid_params
post api(route("new_file_with_author%2Etxt"), user), params
expect(response).to have_gitlab_http_status(201)
expect(response.content_type).to eq('application/json')
......@@ -364,7 +372,7 @@ describe API::Files do
let!(:project) { create(:project_empty_repo, namespace: user.namespace ) }
it "creates a new file in project repo" do
post api(route("newfile%2Erb"), user), valid_params
post api(route("newfile%2Erb"), user), params
expect(response).to have_gitlab_http_status(201)
expect(json_response['file_path']).to eq('newfile.rb')
......@@ -376,7 +384,7 @@ describe API::Files do
end
describe "PUT /projects/:id/repository/files" do
let(:valid_params) do
let(:params) do
{
branch: 'master',
content: 'puts 8',
......@@ -385,7 +393,7 @@ describe API::Files do
end
it "updates existing file in project repo" do
put api(route(file_path), user), valid_params
put api(route(file_path), user), params
expect(response).to have_gitlab_http_status(200)
expect(json_response['file_path']).to eq(CGI.unescape(file_path))
......@@ -394,8 +402,16 @@ describe API::Files do
expect(last_commit.author_name).to eq(user.name)
end
it 'returns a 400 bad request if the commit message is empty' do
params[:commit_message] = ''
put api(route(file_path), user), params
expect(response).to have_gitlab_http_status(400)
end
it "returns a 400 bad request if update existing file with stale last commit id" do
params_with_stale_id = valid_params.merge(last_commit_id: 'stale')
params_with_stale_id = params.merge(last_commit_id: 'stale')
put api(route(file_path), user), params_with_stale_id
......@@ -406,7 +422,7 @@ describe API::Files do
it "updates existing file in project repo with accepts correct last commit id" do
last_commit = Gitlab::Git::Commit
.last_for_path(project.repository, 'master', URI.unescape(file_path))
params_with_correct_id = valid_params.merge(last_commit_id: last_commit.id)
params_with_correct_id = params.merge(last_commit_id: last_commit.id)
put api(route(file_path), user), params_with_correct_id
......@@ -421,9 +437,9 @@ describe API::Files do
context "when specifying an author" do
it "updates a file with the specified author" do
valid_params.merge!(author_email: author_email, author_name: author_name, content: "New content")
params.merge!(author_email: author_email, author_name: author_name, content: "New content")
put api(route(file_path), user), valid_params
put api(route(file_path), user), params
expect(response).to have_gitlab_http_status(200)
last_commit = project.repository.commit.raw
......@@ -434,7 +450,7 @@ describe API::Files do
end
describe "DELETE /projects/:id/repository/files" do
let(:valid_params) do
let(:params) do
{
branch: 'master',
commit_message: 'Changed file'
......@@ -442,7 +458,7 @@ describe API::Files do
end
it "deletes existing file in project repo" do
delete api(route(file_path), user), valid_params
delete api(route(file_path), user), params
expect(response).to have_gitlab_http_status(204)
end
......@@ -453,19 +469,27 @@ describe API::Files do
expect(response).to have_gitlab_http_status(400)
end
it 'returns a 400 bad request if the commit message is empty' do
params[:commit_message] = ''
delete api(route(file_path), user), params
expect(response).to have_gitlab_http_status(400)
end
it "returns a 400 if fails to delete file" do
allow_any_instance_of(Repository).to receive(:delete_file).and_raise(Gitlab::Git::CommitError, 'Cannot delete file')
delete api(route(file_path), user), valid_params
delete api(route(file_path), user), params
expect(response).to have_gitlab_http_status(400)
end
context "when specifying an author" do
it "removes a file with the specified author" do
valid_params.merge!(author_email: author_email, author_name: author_name)
params.merge!(author_email: author_email, author_name: author_name)
delete api(route(file_path), user), valid_params
delete api(route(file_path), user), params
expect(response).to have_gitlab_http_status(204)
end
......
......@@ -116,6 +116,14 @@ describe API::ProjectSnippets do
expect(response).to have_gitlab_http_status(400)
end
it 'returns 400 for empty code field' do
params[:code] = ''
post api("/projects/#{project.id}/snippets/", admin), params
expect(response).to have_gitlab_http_status(400)
end
context 'when the snippet is spam' do
def create_snippet(project, snippet_params = {})
project.add_developer(user)
......@@ -180,6 +188,14 @@ describe API::ProjectSnippets do
expect(response).to have_gitlab_http_status(400)
end
it 'returns 400 for empty code field' do
new_content = ''
put api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/", admin), code: new_content
expect(response).to have_gitlab_http_status(400)
end
context 'when the snippet is spam' do
def update_snippet(snippet_params = {})
put api("/projects/#{snippet.project.id}/snippets/#{snippet.id}", admin), snippet_params
......
......@@ -962,6 +962,7 @@ describe API::Projects do
expect(json_response['shared_with_groups'][0]['group_id']).to eq(group.id)
expect(json_response['shared_with_groups'][0]['group_name']).to eq(group.name)
expect(json_response['shared_with_groups'][0]['group_access_level']).to eq(link.group_access)
expect(json_response['shared_with_groups'][0]['expires_at']).to be_nil
expect(json_response['only_allow_merge_if_pipeline_succeeds']).to eq(project.only_allow_merge_if_pipeline_succeeds)
expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to eq(project.only_allow_merge_if_all_discussions_are_resolved)
expect(json_response['merge_method']).to eq(project.merge_method.to_s)
......@@ -969,6 +970,21 @@ describe API::Projects do
expect(json_response).not_to have_key('repository_storage')
end
it 'returns a group link with expiration date' do
group = create(:group)
expires_at = 5.days.from_now.to_date
link = create(:project_group_link, project: project, group: group, expires_at: expires_at)
get api("/projects/#{project.id}", user)
expect(json_response['shared_with_groups']).to be_an Array
expect(json_response['shared_with_groups'].length).to eq(1)
expect(json_response['shared_with_groups'][0]['group_id']).to eq(group.id)
expect(json_response['shared_with_groups'][0]['group_name']).to eq(group.name)
expect(json_response['shared_with_groups'][0]['group_access_level']).to eq(link.group_access)
expect(json_response['shared_with_groups'][0]['expires_at']).to eq(expires_at.to_s)
end
it 'returns a project by path name' do
get api("/projects/#{project.id}", user)
expect(response).to have_gitlab_http_status(200)
......
......@@ -245,9 +245,13 @@ describe GitPushService do
end
end
context "Sends System Push data" do
it "when pushing on a branch" do
expect(SystemHookPushWorker).to receive(:perform_async).with(push_data, :push_hooks)
describe 'system hooks' do
let(:system_hook_service) { double() }
it "sends a system hook after pushing a branch" do
expect(SystemHooksService).to receive(:new).and_return(system_hook_service)
expect(system_hook_service).to receive(:execute_hooks).with(push_data, :push_hooks)
execute_service(project, user, oldrev, newrev, ref)
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