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';
......@@ -82,13 +82,13 @@ LineHighlighter.prototype.highlightHash = function(newHash) {
};
LineHighlighter.prototype.clickHandler = function(event) {
var current, lineNumber, range;
let range;
event.preventDefault();
this.clearHighlight();
lineNumber = $(event.target)
const lineNumber = $(event.target)
.closest('a')
.data('lineNumber');
current = this.hashToRange(this._hash);
const current = this.hashToRange(this._hash);
if (!(current[0] && event.shiftKey)) {
// If there's no current selection, or there is but Shift wasn't held,
// treat this like a single-line selection.
......@@ -121,12 +121,11 @@ LineHighlighter.prototype.clearHighlight = function() {
//
// Returns an Array
LineHighlighter.prototype.hashToRange = function(hash) {
var first, last, matches;
// ?L(\d+)(?:-(\d+))?$/)
matches = hash.match(/^#?L(\d+)(?:-(\d+))?$/);
const matches = hash.match(/^#?L(\d+)(?:-(\d+))?$/);
if (matches && matches.length) {
first = parseInt(matches[1], 10);
last = matches[2] ? parseInt(matches[2], 10) : null;
const first = parseInt(matches[1], 10);
const last = matches[2] ? parseInt(matches[2], 10) : null;
return [first, last];
} else {
return [null, null];
......@@ -160,7 +159,7 @@ LineHighlighter.prototype.highlightRange = function(range) {
// Set the URL hash string
LineHighlighter.prototype.setHash = function(firstLineNumber, lastLineNumber) {
var hash;
let hash;
if (lastLineNumber) {
hash = `#L${firstLineNumber}-${lastLineNumber}`;
} else {
......
......@@ -19,7 +19,6 @@
= f.label :expires_at, _('Expires at'), class: 'label-bold'
.input-icon-wrapper
= f.text_field :expires_at, class: "datepicker form-control", placeholder: 'YYYY-MM-DD'
= icon('calendar', { class: 'input-icon-right' })
.form-group
= 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:
- 2FA enforcement/grace period 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)**
NOTE: **Note:**
......@@ -107,6 +109,8 @@ the filter drop-down. You can further filter by specific group, project or user
![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
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).
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
......@@ -83,7 +85,7 @@ Example response:
]
```
## Retrieve single instance audit event
### Retrieve single instance audit event
```
GET /audit_events/:id
......@@ -113,3 +115,109 @@ Example response:
"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
]
```
## 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)**
Syncs the group with its linked LDAP group. Only available to group owners and administrators.
......
......@@ -49,11 +49,12 @@ module Gitlab
].compact
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:
# `"{table_name}"."project_id" = {project.id} OR "{table_name}"."group_id" = {group.id}`
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
......@@ -103,6 +104,10 @@ module Gitlab
klass == Milestone
end
def merge_request?
klass == MergeRequest
end
# If an existing group milestone used the IID
# claim the IID back and set the group milestone to use one available
# This is necessary to fix situations like the following:
......@@ -124,7 +129,7 @@ module Gitlab
# Returns Arel clause for a particular model or `nil`.
def where_clause_for_klass
# no-op
return attrs_to_arel(attributes.slice('iid')) if merge_request?
end
end
end
......
......@@ -329,8 +329,6 @@ module Gitlab
def find_or_create_object!
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
finder_hash = parsed_relation_hash.tap do |hash|
hash['group'] = @project.group if relation_class.attribute_method?('group_id')
......@@ -340,11 +338,6 @@ module Gitlab
GroupProjectObjectBuilder.build(relation_class, finder_hash)
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
......@@ -2,7 +2,7 @@ require 'spec_helper'
describe Gitlab::ImportExport::GroupProjectObjectBuilder do
let(:project) do
create(:project,
create(:project, :repository,
:builds_disabled,
:issues_disabled,
name: 'project',
......@@ -11,8 +11,8 @@ describe Gitlab::ImportExport::GroupProjectObjectBuilder do
end
context 'labels' do
it 'finds the right group label' do
group_label = create(:group_label, 'name': 'group label', 'group': project.group)
it 'finds the existing group label' do
group_label = create(:group_label, name: 'group label', group: project.group)
expect(described_class.build(Label,
'title' => 'group label',
......@@ -31,8 +31,8 @@ describe Gitlab::ImportExport::GroupProjectObjectBuilder do
end
context 'milestones' do
it 'finds the right group milestone' do
milestone = create(:milestone, 'name' => 'group milestone', 'group' => project.group)
it 'finds the existing group milestone' do
milestone = create(:milestone, name: 'group milestone', group: project.group)
expect(described_class.build(Milestone,
'title' => 'group milestone',
......@@ -49,4 +49,30 @@ describe Gitlab::ImportExport::GroupProjectObjectBuilder do
expect(milestone.persisted?).to be true
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
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