Skip to content
Snippets Groups Projects
Commit 759cd6c2 authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent 9735395f
No related branches found
No related tags found
No related merge requests found
# Audit Events API **(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
```
GET /audit_events
```
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `created_after` | string | no | Return audit events created on or after the given time. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ |
| `created_before` | string | no | Return audit events created on or before the given time. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ |
| `entity_type` | string | no | Return audit events for the given entity type. Valid values are: `User`, `Group`, or `Project`. |
| `entity_id` | boolean | no | Return audit events for the given entity ID. Requires `entity_type` attribute to be present. |
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/audit_events
```
Example response:
```json
[
{
"id": 1,
"author_id": 1,
"entity_id": 6,
"entity_type": "Project",
"details": {
"custom_message": "Project archived",
"author_name": "Administrator",
"target_id": "flightjs/flight",
"target_type": "Project",
"target_details": "flightjs/flight",
"ip_address": "127.0.0.1",
"entity_path": "flightjs/flight"
},
"created_at": "2019-08-30T07:00:41.885Z"
},
{
"id": 2,
"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"
},
{
"id": 3,
"author_id": 51,
"entity_id": 51,
"entity_type": "User",
"details": {
"change": "email address",
"from": "hello@flightjs.com",
"to": "maintainer@flightjs.com",
"author_name": "Andreas",
"target_id": 51,
"target_type": "User",
"target_details": "Andreas",
"ip_address": null,
"entity_path": "Andreas"
},
"created_at": "2019-08-22T16:34:25.639Z"
}
]
```
## Retrieve single instance audit event
```
GET /audit_events/:id
```
```bash
curl --header "PRIVATE-TOKEN: <your_access_token>" https://primary.example.com/api/v4/audit_events/1
```
Example response:
```json
{
"id": 1,
"author_id": 1,
"entity_id": 6,
"entity_type": "Project",
"details": {
"custom_message": "Project archived",
"author_name": "Administrator",
"target_id": "flightjs/flight",
"target_type": "Project",
"target_details": "flightjs/flight",
"ip_address": "127.0.0.1",
"entity_path": "flightjs/flight"
},
"created_at": "2019-08-30T07:00:41.885Z"
}
```
Loading
Loading
@@ -26,7 +26,8 @@ Example response:
"id": 1,
"name": "review/fix-foo",
"slug": "review-fix-foo-dfjre3",
"external_url": "https://review-fix-foo-dfjre3.example.gitlab.com"
"external_url": "https://review-fix-foo-dfjre3.example.gitlab.com",
"state": "available"
}
]
```
Loading
Loading
@@ -54,12 +55,14 @@ Example of response
"name": "review/fix-foo",
"slug": "review-fix-foo-dfjre3",
"external_url": "https://review-fix-foo-dfjre3.example.gitlab.com"
"state": "available",
"last_deployment": {
"id": 100,
"iid": 34,
"ref": "fdroid",
"sha": "416d8ea11849050d3d1f5104cf8cf51053e790ab",
"created_at": "2019-03-25T18:55:13.252Z",
"status": "success",
"user": {
"id": 1,
"name": "Administrator",
Loading
Loading
@@ -163,7 +166,8 @@ Example response:
"id": 1,
"name": "deploy",
"slug": "deploy",
"external_url": "https://deploy.example.gitlab.com"
"external_url": "https://deploy.example.gitlab.com",
"state": "available"
}
```
 
Loading
Loading
@@ -195,7 +199,8 @@ Example response:
"id": 1,
"name": "staging",
"slug": "staging",
"external_url": "https://staging.example.gitlab.com"
"external_url": "https://staging.example.gitlab.com",
"state": "available"
}
```
 
Loading
Loading
@@ -240,6 +245,7 @@ Example response:
"id": 1,
"name": "deploy",
"slug": "deploy",
"external_url": "https://deploy.example.gitlab.com"
"external_url": "https://deploy.example.gitlab.com",
"state": "stopped"
}
```
Loading
Loading
@@ -1470,11 +1470,13 @@ module API
expose :user, using: Entities::UserBasic
expose :environment, using: Entities::EnvironmentBasic
expose :deployable, using: Entities::Job
expose :status
end
 
class Environment < EnvironmentBasic
expose :project, using: Entities::BasicProjectDetails
expose :last_deployment, using: Entities::Deployment, if: { last_deployment: true }
expose :state
end
 
class LicenseBasic < Grape::Entity
Loading
Loading
Loading
Loading
@@ -8,8 +8,8 @@ module Banzai
# a "Download" link in the case the video cannot be played.
class VideoLinkFilter < HTML::Pipeline::Filter
def call
doc.xpath(query).each do |el|
el.replace(video_node(doc, el))
doc.xpath('descendant-or-self::img[not(ancestor::a)]').each do |el|
el.replace(video_node(doc, el)) if has_video_extension?(el)
end
 
doc
Loading
Loading
@@ -17,22 +17,10 @@ module Banzai
 
private
 
def query
@query ||= begin
src_query = UploaderHelper::SAFE_VIDEO_EXT.map do |ext|
"'.#{ext}' = substring(@src, string-length(@src) - #{ext.size})"
end
def has_video_extension?(element)
src_attr = context[:asset_proxy_enabled] ? 'data-canonical-src' : 'src'
 
if context[:asset_proxy_enabled].present?
src_query.concat(
UploaderHelper::SAFE_VIDEO_EXT.map do |ext|
"'.#{ext}' = substring(@data-canonical-src, string-length(@data-canonical-src) - #{ext.size})"
end
)
end
"descendant-or-self::img[not(ancestor::a) and (#{src_query.join(' or ')})]"
end
element.attr(src_attr).downcase.end_with?(*UploaderHelper::SAFE_VIDEO_EXT)
end
 
def video_node(doc, element)
Loading
Loading
Loading
Loading
@@ -428,8 +428,8 @@ module Gitlab
 
def viewer_class_from(classes)
return unless diffable?
return if different_type? || external_storage_error?
return unless new_file? || deleted_file? || content_changed?
return if different_type? || external_storage_error?
 
verify_binary = !stored_externally?
 
Loading
Loading
Loading
Loading
@@ -47,11 +47,7 @@ module Gitlab
end
 
def description_for(release)
if release.body.present?
release.body
else
"Release for tag #{release.tag_name}"
end
release.body.presence || "Release for tag #{release.tag_name}"
end
end
end
Loading
Loading
Loading
Loading
@@ -93,13 +93,13 @@ describe 'User browses commits' do
context 'when the blob does not exist' do
let(:commit) { create(:commit, project: project) }
 
it 'shows a blank label' do
it 'renders successfully' do
allow_any_instance_of(Gitlab::Diff::File).to receive(:blob).and_return(nil)
allow_any_instance_of(Gitlab::Diff::File).to receive(:binary?).and_return(true)
 
visit(project_commit_path(project, commit))
 
expect(find('.diff-file-changes', visible: false)).to have_content('No file name available')
expect(find('.diff-file-changes', visible: false)).to have_content('files/ruby/popen.rb')
end
end
 
Loading
Loading
Loading
Loading
@@ -60,7 +60,8 @@
"scheduled_actions": {
"type": "array",
"items": { "$ref": "job/job.json" }
}
},
"status": { "type": "string" }
},
"additionalProperties": false
}
Loading
Loading
@@ -26,7 +26,8 @@
{ "type": "null" },
{ "$ref": "job.json" }
]
}
},
"status": { "type": "string" }
},
"additionalProperties": false
}
Loading
Loading
@@ -17,7 +17,8 @@
{ "type": "null" },
{ "$ref": "deployment.json" }
]
}
},
"state": { "type": "string" }
},
"additionalProperties": false
}
Loading
Loading
@@ -3,6 +3,7 @@ import {
updateIncrementalTrace,
parseHeaderLine,
parseLine,
findOffsetAndRemove,
} from '~/jobs/store/utils';
import {
utilsMockData,
Loading
Loading
@@ -83,6 +84,91 @@ describe('Jobs Store Utils', () => {
});
});
 
describe('findOffsetAndRemove', () => {
describe('when last item is header', () => {
const existingLog = [
{
isHeader: true,
isClosed: true,
line: { content: [{ text: 'bar' }], offset: 10, lineNumber: 1 },
},
];
describe('and matches the offset', () => {
it('returns an array with the item removed', () => {
const newData = [{ offset: 10, content: [{ text: 'foobar' }] }];
const result = findOffsetAndRemove(newData, existingLog);
expect(result).toEqual([]);
});
});
describe('and does not match the offset', () => {
it('returns the provided existing log', () => {
const newData = [{ offset: 110, content: [{ text: 'foobar' }] }];
const result = findOffsetAndRemove(newData, existingLog);
expect(result).toEqual(existingLog);
});
});
});
describe('when last item is a regular line', () => {
const existingLog = [{ content: [{ text: 'bar' }], offset: 10, lineNumber: 1 }];
describe('and matches the offset', () => {
it('returns an array with the item removed', () => {
const newData = [{ offset: 10, content: [{ text: 'foobar' }] }];
const result = findOffsetAndRemove(newData, existingLog);
expect(result).toEqual([]);
});
});
describe('and does not match the fofset', () => {
it('returns the provided old log', () => {
const newData = [{ offset: 101, content: [{ text: 'foobar' }] }];
const result = findOffsetAndRemove(newData, existingLog);
expect(result).toEqual(existingLog);
});
});
});
describe('when last item is nested', () => {
const existingLog = [
{
isHeader: true,
isClosed: true,
lines: [{ offset: 101, content: [{ text: 'foobar' }], lineNumber: 2 }],
line: {
offset: 10,
lineNumber: 1,
section_duration: '10:00',
},
},
];
describe('and matches the offset', () => {
it('returns an array with the last nested line item removed', () => {
const newData = [{ offset: 101, content: [{ text: 'foobar' }] }];
const result = findOffsetAndRemove(newData, existingLog);
expect(result[0].lines).toEqual([]);
});
});
describe('and does not match the offset', () => {
it('returns the provided old log', () => {
const newData = [{ offset: 120, content: [{ text: 'foobar' }] }];
const result = findOffsetAndRemove(newData, existingLog);
expect(result).toEqual(existingLog);
});
});
});
});
describe('updateIncrementalTrace', () => {
describe('without repeated section', () => {
it('concats and parses both arrays', () => {
Loading
Loading
Loading
Loading
@@ -17,27 +17,32 @@ describe Banzai::Filter::VideoLinkFilter do
 
let(:project) { create(:project, :repository) }
 
context 'when the element src has a video extension' do
UploaderHelper::SAFE_VIDEO_EXT.each do |ext|
it "replaces the image tag 'path/video.#{ext}' with a video tag" do
container = filter(link_to_image("/path/video.#{ext}")).children.first
shared_examples 'replaces the image tag with a video tag' do |ext|
it "replaces the image tag 'path/video.#{ext}' with a video tag" do
container = filter(link_to_image("/path/video.#{ext}")).children.first
 
expect(container.name).to eq 'div'
expect(container['class']).to eq 'video-container'
expect(container.name).to eq 'div'
expect(container['class']).to eq 'video-container'
video, paragraph = container.children
 
video, paragraph = container.children
expect(video.name).to eq 'video'
expect(video['src']).to eq "/path/video.#{ext}"
 
expect(video.name).to eq 'video'
expect(video['src']).to eq "/path/video.#{ext}"
expect(paragraph.name).to eq 'p'
 
expect(paragraph.name).to eq 'p'
link = paragraph.children.first
 
link = paragraph.children.first
expect(link.name).to eq 'a'
expect(link['href']).to eq "/path/video.#{ext}"
expect(link['target']).to eq '_blank'
end
end
 
expect(link.name).to eq 'a'
expect(link['href']).to eq "/path/video.#{ext}"
expect(link['target']).to eq '_blank'
end
context 'when the element src has a video extension' do
UploaderHelper::SAFE_VIDEO_EXT.each do |ext|
it_behaves_like 'replaces the image tag with a video tag', ext
it_behaves_like 'replaces the image tag with a video tag', ext.upcase
end
end
 
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment