Commit 41d446ba authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 386e5740
/* eslint-disable func-names, no-var, no-underscore-dangle, no-param-reassign, consistent-return, one-var, no-else-return */ /* eslint-disable func-names, no-underscore-dangle, no-param-reassign, consistent-return, no-else-return */
import $ from 'jquery'; import $ from 'jquery';
...@@ -82,13 +82,13 @@ LineHighlighter.prototype.highlightHash = function(newHash) { ...@@ -82,13 +82,13 @@ LineHighlighter.prototype.highlightHash = function(newHash) {
}; };
LineHighlighter.prototype.clickHandler = function(event) { LineHighlighter.prototype.clickHandler = function(event) {
var current, lineNumber, range; let range;
event.preventDefault(); event.preventDefault();
this.clearHighlight(); this.clearHighlight();
lineNumber = $(event.target) const lineNumber = $(event.target)
.closest('a') .closest('a')
.data('lineNumber'); .data('lineNumber');
current = this.hashToRange(this._hash); const current = this.hashToRange(this._hash);
if (!(current[0] && event.shiftKey)) { if (!(current[0] && event.shiftKey)) {
// If there's no current selection, or there is but Shift wasn't held, // If there's no current selection, or there is but Shift wasn't held,
// treat this like a single-line selection. // treat this like a single-line selection.
...@@ -121,12 +121,11 @@ LineHighlighter.prototype.clearHighlight = function() { ...@@ -121,12 +121,11 @@ LineHighlighter.prototype.clearHighlight = function() {
// //
// Returns an Array // Returns an Array
LineHighlighter.prototype.hashToRange = function(hash) { LineHighlighter.prototype.hashToRange = function(hash) {
var first, last, matches;
// ?L(\d+)(?:-(\d+))?$/) // ?L(\d+)(?:-(\d+))?$/)
matches = hash.match(/^#?L(\d+)(?:-(\d+))?$/); const matches = hash.match(/^#?L(\d+)(?:-(\d+))?$/);
if (matches && matches.length) { if (matches && matches.length) {
first = parseInt(matches[1], 10); const first = parseInt(matches[1], 10);
last = matches[2] ? parseInt(matches[2], 10) : null; const last = matches[2] ? parseInt(matches[2], 10) : null;
return [first, last]; return [first, last];
} else { } else {
return [null, null]; return [null, null];
...@@ -160,7 +159,7 @@ LineHighlighter.prototype.highlightRange = function(range) { ...@@ -160,7 +159,7 @@ LineHighlighter.prototype.highlightRange = function(range) {
// Set the URL hash string // Set the URL hash string
LineHighlighter.prototype.setHash = function(firstLineNumber, lastLineNumber) { LineHighlighter.prototype.setHash = function(firstLineNumber, lastLineNumber) {
var hash; let hash;
if (lastLineNumber) { if (lastLineNumber) {
hash = `#L${firstLineNumber}-${lastLineNumber}`; hash = `#L${firstLineNumber}-${lastLineNumber}`;
} else { } else {
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
= f.label :expires_at, _('Expires at'), class: 'label-bold' = f.label :expires_at, _('Expires at'), class: 'label-bold'
.input-icon-wrapper .input-icon-wrapper
= f.text_field :expires_at, class: "datepicker form-control", placeholder: 'YYYY-MM-DD' = f.text_field :expires_at, class: "datepicker form-control", placeholder: 'YYYY-MM-DD'
= icon('calendar', { class: 'input-icon-right' })
.form-group .form-group
= f.label :scopes, _('Scopes'), class: 'label-bold' = f.label :scopes, _('Scopes'), class: 'label-bold'
......
---
title: Remove calendar icon from personal access tokens
merge_request: 20183
author:
type: other
---
title: Add Group Audit Events API
merge_request: 19868
author:
type: added
---
title: Remove var from line_highlighter.js
merge_request: 20108
author: Lee Tickett
type: other
...@@ -59,6 +59,8 @@ From there, you can see the following actions: ...@@ -59,6 +59,8 @@ From there, you can see the following actions:
- 2FA enforcement/grace period changed - 2FA enforcement/grace period changed
- Roles allowed to create project changed - Roles allowed to create project changed
Group events can also be accessed via the [Group Audit Events API](../api/audit_events.md#group-audit-events-starter)
### Project events **(STARTER)** ### Project events **(STARTER)**
NOTE: **Note:** NOTE: **Note:**
...@@ -107,6 +109,8 @@ the filter drop-down. You can further filter by specific group, project or user ...@@ -107,6 +109,8 @@ the filter drop-down. You can further filter by specific group, project or user
![audit log](img/audit_log.png) ![audit log](img/audit_log.png)
Instance events can also be accessed via the [Instance Audit Events API](../api/audit_events.md#instance-audit-events-premium-only)
### Missing events ### Missing events
Some events are not being tracked in Audit Events. Please see the following Some events are not being tracked in Audit Events. Please see the following
......
# Audit Events API **(PREMIUM ONLY)** # Audit Events API
## Instance Audit Events **(PREMIUM ONLY)**
The Audit Events API allows you to retrieve [instance audit events](../administration/audit_events.md#instance-events-premium-only). The Audit Events API allows you to retrieve [instance audit events](../administration/audit_events.md#instance-events-premium-only).
To retrieve audit events using the API, you must [authenticate yourself](README.html#authentication) as an Administrator. To retrieve audit events using the API, you must [authenticate yourself](README.html#authentication) as an Administrator.
## Retrieve all instance audit events ### Retrieve all instance audit events
``` ```
GET /audit_events GET /audit_events
...@@ -83,7 +85,7 @@ Example response: ...@@ -83,7 +85,7 @@ Example response:
] ]
``` ```
## Retrieve single instance audit event ### Retrieve single instance audit event
``` ```
GET /audit_events/:id GET /audit_events/:id
...@@ -113,3 +115,109 @@ Example response: ...@@ -113,3 +115,109 @@ Example response:
"created_at": "2019-08-30T07:00:41.885Z" "created_at": "2019-08-30T07:00:41.885Z"
} }
``` ```
## Group Audit Events **(STARTER)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/34078) in GitLab 12.5.
The Group Audit Events API allows you to retrieve [group audit events](../administration/audit_events.html#group-events-starter).
To retrieve group audit events using the API, you must [authenticate yourself](README.html#authentication) as an Administrator or an owner of the group.
### Retrieve all group audit events
```
GET /groups/:id/audit_events
```
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
| `created_after` | string | no | Return group audit events created on or after the given time. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ |
| `created_before` | string | no | Return group audit events created on or before the given time. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ |
By default, `GET` requests return 20 results at a time because the API results
are paginated.
Read more on [pagination](README.md#pagination).
```bash
curl --header "PRIVATE-TOKEN: <your_access_token>" https://primary.example.com/api/v4/groups/60/audit_events
```
Example response:
```json
[
{
"id": 2,
"author_id": 1,
"entity_id": 60,
"entity_type": "Group",
"details": {
"custom_message": "Group marked for deletion",
"author_name": "Administrator",
"target_id": "flightjs",
"target_type": "Group",
"target_details": "flightjs",
"ip_address": "127.0.0.1",
"entity_path": "flightjs"
},
"created_at": "2019-08-28T19:36:44.162Z"
},
{
"id": 1,
"author_id": 1,
"entity_id": 60,
"entity_type": "Group",
"details": {
"add": "group",
"author_name": "Administrator",
"target_id": "flightjs",
"target_type": "Group",
"target_details": "flightjs",
"ip_address": "127.0.0.1",
"entity_path": "flightjs"
},
"created_at": "2019-08-27T18:36:44.162Z"
}
]
```
### Retrieve a specific group audit event
Only available to group owners and administrators.
```
GET /groups/:id/audit_events/:audit_event_id
```
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
| `audit_event_id` | integer | yes | ID of the audit event |
```bash
curl --header "PRIVATE-TOKEN: <your_access_token>" https://primary.example.com/api/v4/groups/60/audit_events/2
```
Example response:
```json
{
"id": 2,
"author_id": 1,
"entity_id": 60,
"entity_type": "Group",
"details": {
"custom_message": "Group marked for deletion",
"author_name": "Administrator",
"target_id": "flightjs",
"target_type": "Group",
"target_details": "flightjs",
"ip_address": "127.0.0.1",
"entity_path": "flightjs"
},
"created_at": "2019-08-28T19:36:44.162Z"
}
```
...@@ -611,6 +611,10 @@ GET /groups?search=foobar ...@@ -611,6 +611,10 @@ GET /groups?search=foobar
] ]
``` ```
## Group Audit Events **(STARTER)**
Group audit events can be accessed via the [Group Audit Events API](audit_events.md#group-audit-events-starter)
## Sync group with LDAP **(CORE ONLY)** ## Sync group with LDAP **(CORE ONLY)**
Syncs the group with its linked LDAP group. Only available to group owners and administrators. Syncs the group with its linked LDAP group. Only available to group owners and administrators.
......
...@@ -49,11 +49,12 @@ module Gitlab ...@@ -49,11 +49,12 @@ module Gitlab
].compact ].compact
end end
# Returns Arel clause `"{table_name}"."project_id" = {project.id}` # Returns Arel clause `"{table_name}"."project_id" = {project.id}` if project is present
# For example: merge_request has :target_project_id, and we are searching by :iid
# or, if group is present: # or, if group is present:
# `"{table_name}"."project_id" = {project.id} OR "{table_name}"."group_id" = {group.id}` # `"{table_name}"."project_id" = {project.id} OR "{table_name}"."group_id" = {group.id}`
def where_clause_base def where_clause_base
clause = table[:project_id].eq(project.id) clause = table[:project_id].eq(project.id) if project
clause = clause.or(table[:group_id].eq(group.id)) if group clause = clause.or(table[:group_id].eq(group.id)) if group
clause clause
...@@ -103,6 +104,10 @@ module Gitlab ...@@ -103,6 +104,10 @@ module Gitlab
klass == Milestone klass == Milestone
end end
def merge_request?
klass == MergeRequest
end
# If an existing group milestone used the IID # If an existing group milestone used the IID
# claim the IID back and set the group milestone to use one available # claim the IID back and set the group milestone to use one available
# This is necessary to fix situations like the following: # This is necessary to fix situations like the following:
...@@ -124,7 +129,7 @@ module Gitlab ...@@ -124,7 +129,7 @@ module Gitlab
# Returns Arel clause for a particular model or `nil`. # Returns Arel clause for a particular model or `nil`.
def where_clause_for_klass def where_clause_for_klass
# no-op return attrs_to_arel(attributes.slice('iid')) if merge_request?
end end
end end
end end
......
...@@ -329,8 +329,6 @@ module Gitlab ...@@ -329,8 +329,6 @@ module Gitlab
def find_or_create_object! def find_or_create_object!
return relation_class.find_or_create_by(project_id: @project.id) if UNIQUE_RELATIONS.include?(@relation_name) return relation_class.find_or_create_by(project_id: @project.id) if UNIQUE_RELATIONS.include?(@relation_name)
return find_or_create_merge_request! if @relation_name == :merge_request
# Can't use IDs as validation exists calling `group` or `project` attributes # Can't use IDs as validation exists calling `group` or `project` attributes
finder_hash = parsed_relation_hash.tap do |hash| finder_hash = parsed_relation_hash.tap do |hash|
hash['group'] = @project.group if relation_class.attribute_method?('group_id') hash['group'] = @project.group if relation_class.attribute_method?('group_id')
...@@ -340,11 +338,6 @@ module Gitlab ...@@ -340,11 +338,6 @@ module Gitlab
GroupProjectObjectBuilder.build(relation_class, finder_hash) GroupProjectObjectBuilder.build(relation_class, finder_hash)
end end
def find_or_create_merge_request!
@project.merge_requests.find_by(iid: parsed_relation_hash['iid']) ||
relation_class.new(parsed_relation_hash)
end
end end
end end
end end
...@@ -2,7 +2,7 @@ require 'spec_helper' ...@@ -2,7 +2,7 @@ require 'spec_helper'
describe Gitlab::ImportExport::GroupProjectObjectBuilder do describe Gitlab::ImportExport::GroupProjectObjectBuilder do
let(:project) do let(:project) do
create(:project, create(:project, :repository,
:builds_disabled, :builds_disabled,
:issues_disabled, :issues_disabled,
name: 'project', name: 'project',
...@@ -11,8 +11,8 @@ describe Gitlab::ImportExport::GroupProjectObjectBuilder do ...@@ -11,8 +11,8 @@ describe Gitlab::ImportExport::GroupProjectObjectBuilder do
end end
context 'labels' do context 'labels' do
it 'finds the right group label' do it 'finds the existing group label' do
group_label = create(:group_label, 'name': 'group label', 'group': project.group) group_label = create(:group_label, name: 'group label', group: project.group)
expect(described_class.build(Label, expect(described_class.build(Label,
'title' => 'group label', 'title' => 'group label',
...@@ -31,8 +31,8 @@ describe Gitlab::ImportExport::GroupProjectObjectBuilder do ...@@ -31,8 +31,8 @@ describe Gitlab::ImportExport::GroupProjectObjectBuilder do
end end
context 'milestones' do context 'milestones' do
it 'finds the right group milestone' do it 'finds the existing group milestone' do
milestone = create(:milestone, 'name' => 'group milestone', 'group' => project.group) milestone = create(:milestone, name: 'group milestone', group: project.group)
expect(described_class.build(Milestone, expect(described_class.build(Milestone,
'title' => 'group milestone', 'title' => 'group milestone',
...@@ -49,4 +49,30 @@ describe Gitlab::ImportExport::GroupProjectObjectBuilder do ...@@ -49,4 +49,30 @@ describe Gitlab::ImportExport::GroupProjectObjectBuilder do
expect(milestone.persisted?).to be true expect(milestone.persisted?).to be true
end end
end end
context 'merge_request' do
it 'finds the existing merge_request' do
merge_request = create(:merge_request, title: 'MergeRequest', iid: 7, target_project: project, source_project: project)
expect(described_class.build(MergeRequest,
'title' => 'MergeRequest',
'source_project_id' => project.id,
'target_project_id' => project.id,
'source_branch' => 'SourceBranch',
'iid' => 7,
'target_branch' => 'TargetBranch',
'author_id' => project.creator.id)).to eq(merge_request)
end
it 'creates a new merge_request' do
merge_request = described_class.build(MergeRequest,
'title' => 'MergeRequest',
'iid' => 8,
'source_project_id' => project.id,
'target_project_id' => project.id,
'source_branch' => 'SourceBranch',
'target_branch' => 'TargetBranch',
'author_id' => project.creator.id)
expect(merge_request.persisted?).to be true
end
end
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