diff options
-rw-r--r-- | app/assets/javascripts/line_highlighter.js | 17 | ||||
-rw-r--r-- | app/views/shared/_personal_access_tokens_form.html.haml | 1 | ||||
-rw-r--r-- | changelogs/unreleased/27464-misleading-input-controller-for-dates.yml | 5 | ||||
-rw-r--r-- | changelogs/unreleased/34078-extend-audit-events-api-for-gitlab-com.yml | 5 | ||||
-rw-r--r-- | changelogs/unreleased/remove_var_from_line_highlighter_js.yml | 5 | ||||
-rw-r--r-- | doc/administration/audit_events.md | 4 | ||||
-rw-r--r-- | doc/api/audit_events.md | 114 | ||||
-rw-r--r-- | doc/api/groups.md | 4 | ||||
-rw-r--r-- | lib/gitlab/import_export/group_project_object_builder.rb | 11 | ||||
-rw-r--r-- | lib/gitlab/import_export/relation_factory.rb | 7 | ||||
-rw-r--r-- | spec/lib/gitlab/import_export/group_project_object_builder_spec.rb | 36 |
11 files changed, 181 insertions, 28 deletions
diff --git a/app/assets/javascripts/line_highlighter.js b/app/assets/javascripts/line_highlighter.js index b6b96fe7bd5..dd868bb9f4c 100644 --- a/app/assets/javascripts/line_highlighter.js +++ b/app/assets/javascripts/line_highlighter.js @@ -1,4 +1,4 @@ -/* 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 { diff --git a/app/views/shared/_personal_access_tokens_form.html.haml b/app/views/shared/_personal_access_tokens_form.html.haml index 1d96feda3b0..ca0b473addf 100644 --- a/app/views/shared/_personal_access_tokens_form.html.haml +++ b/app/views/shared/_personal_access_tokens_form.html.haml @@ -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' diff --git a/changelogs/unreleased/27464-misleading-input-controller-for-dates.yml b/changelogs/unreleased/27464-misleading-input-controller-for-dates.yml new file mode 100644 index 00000000000..5c5c699122b --- /dev/null +++ b/changelogs/unreleased/27464-misleading-input-controller-for-dates.yml @@ -0,0 +1,5 @@ +--- +title: Remove calendar icon from personal access tokens +merge_request: 20183 +author: +type: other diff --git a/changelogs/unreleased/34078-extend-audit-events-api-for-gitlab-com.yml b/changelogs/unreleased/34078-extend-audit-events-api-for-gitlab-com.yml new file mode 100644 index 00000000000..8b4d640c3f8 --- /dev/null +++ b/changelogs/unreleased/34078-extend-audit-events-api-for-gitlab-com.yml @@ -0,0 +1,5 @@ +--- +title: Add Group Audit Events API +merge_request: 19868 +author: +type: added diff --git a/changelogs/unreleased/remove_var_from_line_highlighter_js.yml b/changelogs/unreleased/remove_var_from_line_highlighter_js.yml new file mode 100644 index 00000000000..1de400f807b --- /dev/null +++ b/changelogs/unreleased/remove_var_from_line_highlighter_js.yml @@ -0,0 +1,5 @@ +--- +title: Remove var from line_highlighter.js +merge_request: 20108 +author: Lee Tickett +type: other diff --git a/doc/administration/audit_events.md b/doc/administration/audit_events.md index 61ea673071e..ccb4ccbd525 100644 --- a/doc/administration/audit_events.md +++ b/doc/administration/audit_events.md @@ -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 diff --git a/doc/api/audit_events.md b/doc/api/audit_events.md index 0b8351062e5..e451b975d42 100644 --- a/doc/api/audit_events.md +++ b/doc/api/audit_events.md @@ -1,10 +1,12 @@ -# 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" +} +``` diff --git a/doc/api/groups.md b/doc/api/groups.md index 312bd04e24c..94f46b11a0f 100644 --- a/doc/api/groups.md +++ b/doc/api/groups.md @@ -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. diff --git a/lib/gitlab/import_export/group_project_object_builder.rb b/lib/gitlab/import_export/group_project_object_builder.rb index de1629d0e28..b94839363df 100644 --- a/lib/gitlab/import_export/group_project_object_builder.rb +++ b/lib/gitlab/import_export/group_project_object_builder.rb @@ -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 diff --git a/lib/gitlab/import_export/relation_factory.rb b/lib/gitlab/import_export/relation_factory.rb index f8f6c3e6107..ae6b3c161ce 100644 --- a/lib/gitlab/import_export/relation_factory.rb +++ b/lib/gitlab/import_export/relation_factory.rb @@ -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 diff --git a/spec/lib/gitlab/import_export/group_project_object_builder_spec.rb b/spec/lib/gitlab/import_export/group_project_object_builder_spec.rb index 6a803c48b34..1a5cb7806a3 100644 --- a/spec/lib/gitlab/import_export/group_project_object_builder_spec.rb +++ b/spec/lib/gitlab/import_export/group_project_object_builder_spec.rb @@ -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 |