Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
873cfffe
Commit
873cfffe
authored
Jan 13, 2022
by
Darby Frey
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adding Secure Files API
parent
d627ce1d
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
323 additions
and
0 deletions
+323
-0
lib/api/api.rb
lib/api/api.rb
+1
-0
lib/api/ci/secure_files.rb
lib/api/ci/secure_files.rb
+94
-0
lib/api/entities/ci/secure_file.rb
lib/api/entities/ci/secure_file.rb
+15
-0
spec/requests/api/ci/secure_files_spec.rb
spec/requests/api/ci/secure_files_spec.rb
+213
-0
No files found.
lib/api/api.rb
View file @
873cfffe
...
...
@@ -171,6 +171,7 @@ module API
mount
::
API
::
Ci
::
ResourceGroups
mount
::
API
::
Ci
::
Runner
mount
::
API
::
Ci
::
Runners
mount
::
API
::
Ci
::
SecureFiles
mount
::
API
::
Ci
::
Triggers
mount
::
API
::
Ci
::
Variables
mount
::
API
::
Commits
...
...
lib/api/ci/secure_files.rb
0 → 100644
View file @
873cfffe
# frozen_string_literal: true
module
API
module
Ci
class
SecureFiles
<
::
API
::
Base
include
PaginationParams
before
do
authenticate!
authorize!
:admin_build
,
user_project
end
feature_category
:pipeline_authoring
default_format
:json
params
do
requires
:id
,
type:
String
,
desc:
'The ID of a project'
end
resource
:projects
,
requirements:
API
::
NAMESPACE_OR_PROJECT_REQUIREMENTS
do
desc
'List all Secure Files for a Project'
params
do
use
:pagination
end
route_setting
:authentication
,
basic_auth_personal_access_token:
true
,
job_token_allowed:
true
get
':id/secure_files'
do
secure_files
=
user_project
.
secure_files
present
paginate
(
secure_files
),
with:
Entities
::
Ci
::
SecureFile
end
desc
'Get an individual Secure File'
params
do
requires
:id
,
type:
Integer
,
desc:
'The Secure File ID'
end
route_setting
:authentication
,
basic_auth_personal_access_token:
true
,
job_token_allowed:
true
get
':id/secure_files/:secure_file_id'
do
secure_file
=
user_project
.
secure_files
.
find
(
params
[
:secure_file_id
])
not_found!
(
'Secure File'
)
unless
secure_file
present
secure_file
,
with:
Entities
::
Ci
::
SecureFile
end
desc
'Download a Secure File'
route_setting
:authentication
,
basic_auth_personal_access_token:
true
,
job_token_allowed:
true
get
':id/secure_files/:secure_file_id/download'
do
secure_file
=
user_project
.
secure_files
.
find
(
params
[
:secure_file_id
])
not_found!
(
'Secure File'
)
unless
secure_file
content_type
'application/octet-stream'
env
[
'api.format'
]
=
:binary
header
[
'Content-Disposition'
]
=
"attachment; filename=
#{
secure_file
.
name
}
"
body
secure_file
.
file
.
read
end
desc
'Upload a Secure File'
params
do
requires
:name
,
type:
String
,
desc:
'The name of the file'
requires
:file
,
types:
[
Rack
::
Multipart
::
UploadedFile
,
::
API
::
Validations
::
Types
::
WorkhorseFile
],
desc:
'The secure file file to be uploaded'
optional
:permissions
,
type:
String
,
desc:
'The file permissions'
end
route_setting
:authentication
,
basic_auth_personal_access_token:
true
,
job_token_allowed:
true
post
':id/secure_files'
do
secure_file
=
user_project
.
secure_files
.
new
(
name:
params
[
:name
],
permissions:
params
[
:permissions
]
||
:read_only
)
secure_file
.
file
=
params
[
:file
]
if
secure_file
.
valid?
secure_file
.
save!
present
secure_file
,
with:
Entities
::
Ci
::
SecureFile
else
render_validation_error!
(
secure_file
)
end
end
desc
'Delete an individual Secure File'
route_setting
:authentication
,
basic_auth_personal_access_token:
true
,
job_token_allowed:
true
delete
':id/secure_files/:secure_file_id'
do
secure_file
=
user_project
.
secure_files
.
find
(
params
[
:secure_file_id
])
not_found!
(
'Secure File'
)
unless
secure_file
secure_file
.
destroy!
no_content!
end
end
end
end
end
lib/api/entities/ci/secure_file.rb
0 → 100644
View file @
873cfffe
# frozen_string_literal: true
module
API
module
Entities
module
Ci
class
SecureFile
<
Grape
::
Entity
expose
:id
expose
:name
expose
:permissions
expose
:checksum
expose
:checksum_algorithm
end
end
end
end
spec/requests/api/ci/secure_files_spec.rb
0 → 100644
View file @
873cfffe
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
API
::
Ci
::
SecureFiles
do
before
do
stub_ci_secure_file_object_storage
end
let
(
:user
)
{
create
(
:user
)
}
let
(
:user2
)
{
create
(
:user
)
}
let!
(
:project
)
{
create
(
:project
,
creator_id:
user
.
id
)
}
let!
(
:maintainer
)
{
create
(
:project_member
,
:maintainer
,
user:
user
,
project:
project
)
}
let!
(
:developer
)
{
create
(
:project_member
,
:developer
,
user:
user2
,
project:
project
)
}
let!
(
:secure_file
)
{
create
(
:ci_secure_file
,
project:
project
)
}
describe
'GET /projects/:id/secure_files'
do
context
'authorized user with proper permissions'
do
it
'returns project secure files'
do
get
api
(
"/projects/
#{
project
.
id
}
/secure_files"
,
user
)
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
json_response
).
to
be_a
(
Array
)
end
end
context
'authorized user with invalid permissions'
do
it
'does not return project secure files'
do
get
api
(
"/projects/
#{
project
.
id
}
/secure_files"
,
user2
)
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
end
context
'unauthorized user'
do
it
'does not return project secure files'
do
get
api
(
"/projects/
#{
project
.
id
}
/secure_files"
)
expect
(
response
).
to
have_gitlab_http_status
(
:unauthorized
)
end
end
end
describe
'GET /projects/:id/secure_files/:secure_file_id'
do
context
'authorized user with proper permissions'
do
it
'returns project secure file details'
do
get
api
(
"/projects/
#{
project
.
id
}
/secure_files/
#{
secure_file
.
id
}
"
,
user
)
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
json_response
[
'name'
]).
to
eq
(
secure_file
.
name
)
expect
(
json_response
[
'permissions'
]).
to
eq
(
secure_file
.
permissions
)
end
it
'responds with 404 Not Found if requesting non-existing secure file'
do
get
api
(
"/projects/
#{
project
.
id
}
/secure_files/99999"
,
user
)
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
context
'authorized user with invalid permissions'
do
it
'does not return project secure file details'
do
get
api
(
"/projects/
#{
project
.
id
}
/secure_files/
#{
secure_file
.
id
}
"
,
user2
)
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
end
context
'unauthorized user'
do
it
'does not return project secure file details'
do
get
api
(
"/projects/
#{
project
.
id
}
/secure_files/
#{
secure_file
.
id
}
"
)
expect
(
response
).
to
have_gitlab_http_status
(
:unauthorized
)
end
end
end
describe
'POST /projects/:id/secure_files'
do
context
'authorized user with proper permissions'
do
it
'creates a secure file'
do
params
=
{
file:
fixture_file_upload
(
'spec/fixtures/ci_secure_files/upload-keystore.jks'
),
name:
'upload-keystore.jks'
,
permissions:
'execute'
}
expect
do
post
api
(
"/projects/
#{
project
.
id
}
/secure_files"
,
user
),
params:
params
end
.
to
change
{
project
.
secure_files
.
count
}.
by
(
1
)
expect
(
response
).
to
have_gitlab_http_status
(
:created
)
expect
(
json_response
[
'name'
]).
to
eq
(
'upload-keystore.jks'
)
expect
(
json_response
[
'permissions'
]).
to
eq
(
'execute'
)
expect
(
json_response
[
'checksum'
]).
to
eq
(
secure_file
.
checksum
)
expect
(
json_response
[
'checksum_algorithm'
]).
to
eq
(
'sha256'
)
secure_file
=
Ci
::
SecureFile
.
find
(
json_response
[
'id'
])
expect
(
secure_file
.
checksum
).
to
eq
(
Digest
::
SHA256
.
hexdigest
(
fixture_file
(
'ci_secure_files/upload-keystore.jks'
))
)
expect
(
json_response
[
'id'
]).
to
eq
(
secure_file
.
id
)
end
it
'creates a secure file with read_only permissions by default'
do
params
=
{
file:
fixture_file_upload
(
'spec/fixtures/ci_secure_files/upload-keystore.jks'
),
name:
'upload-keystore.jks'
}
expect
do
post
api
(
"/projects/
#{
project
.
id
}
/secure_files"
,
user
),
params:
params
end
.
to
change
{
project
.
secure_files
.
count
}.
by
(
1
)
expect
(
json_response
[
'permissions'
]).
to
eq
(
'read_only'
)
end
it
'uploads and downloads a secure file'
do
post_params
=
{
file:
fixture_file_upload
(
'spec/fixtures/ci_secure_files/upload-keystore.jks'
),
name:
'upload-keystore.jks'
}
post
api
(
"/projects/
#{
project
.
id
}
/secure_files"
,
user
),
params:
post_params
secure_file_id
=
json_response
[
'id'
]
get
api
(
"/projects/
#{
project
.
id
}
/secure_files/
#{
secure_file_id
}
/download"
,
user
)
expect
(
Base64
.
encode64
(
response
.
body
)).
to
eq
(
Base64
.
encode64
(
fixture_file_upload
(
'spec/fixtures/ci_secure_files/upload-keystore.jks'
).
read
))
end
it
'returns an error when the file checksum fails to validate'
do
secure_file
.
update!
(
checksum:
'foo'
)
get
api
(
"/projects/
#{
project
.
id
}
/secure_files/
#{
secure_file
.
id
}
/download"
,
user
)
expect
(
response
.
code
).
to
eq
(
"500"
)
end
it
'returns an error when no file is uploaded'
do
post_params
=
{
name:
'upload-keystore.jks'
}
post
api
(
"/projects/
#{
project
.
id
}
/secure_files"
,
user
),
params:
post_params
expect
(
response
).
to
have_gitlab_http_status
(
:bad_request
)
expect
(
json_response
[
'error'
]).
to
eq
(
'file is missing'
)
end
it
'returns an error when the file name is missing'
do
post_params
=
{
file:
fixture_file_upload
(
'spec/fixtures/ci_secure_files/upload-keystore.jks'
)
}
post
api
(
"/projects/
#{
project
.
id
}
/secure_files"
,
user
),
params:
post_params
expect
(
response
).
to
have_gitlab_http_status
(
:bad_request
)
expect
(
json_response
[
'error'
]).
to
eq
(
'name is missing'
)
end
end
context
'authorized user with invalid permissions'
do
it
'does not create a secure file'
do
post
api
(
"/projects/
#{
project
.
id
}
/secure_files"
,
user2
)
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
end
context
'unauthorized user'
do
it
'does not create a secure file'
do
post
api
(
"/projects/
#{
project
.
id
}
/secure_files"
)
expect
(
response
).
to
have_gitlab_http_status
(
:unauthorized
)
end
end
end
describe
'DELETE /projects/:id/secure_files/:secure_file_id'
do
context
'authorized user with proper permissions'
do
it
'deletes the secure file'
do
expect
do
delete
api
(
"/projects/
#{
project
.
id
}
/secure_files/
#{
secure_file
.
id
}
"
,
user
)
expect
(
response
).
to
have_gitlab_http_status
(
:no_content
)
end
.
to
change
{
project
.
secure_files
.
count
}.
by
(
-
1
)
end
it
'responds with 404 Not Found if requesting non-existing secure_file'
do
delete
api
(
"/projects/
#{
project
.
id
}
/secure_files/99999"
,
user
)
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
context
'authorized user with invalid permissions'
do
it
'does not delete the secure_file'
do
delete
api
(
"/projects/
#{
project
.
id
}
/secure_files/
#{
secure_file
.
id
}
"
,
user2
)
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
end
context
'unauthorized user'
do
it
'does not delete the secure_file'
do
delete
api
(
"/projects/
#{
project
.
id
}
/secure_files/
#{
secure_file
.
id
}
"
)
expect
(
response
).
to
have_gitlab_http_status
(
:unauthorized
)
end
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment