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
da86b006
Commit
da86b006
authored
Dec 14, 2021
by
Steve Abrams
Committed by
Nikola Milojevic
Dec 14, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Deploy token support for the Composer package registry
parent
8de5854f
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
171 additions
and
22 deletions
+171
-22
app/finders/packages/group_packages_finder.rb
app/finders/packages/group_packages_finder.rb
+8
-4
doc/user/packages/composer_repository/index.md
doc/user/packages/composer_repository/index.md
+60
-13
lib/api/composer_packages.rb
lib/api/composer_packages.rb
+5
-5
spec/finders/packages/group_packages_finder_spec.rb
spec/finders/packages/group_packages_finder_spec.rb
+22
-0
spec/requests/api/composer_packages_spec.rb
spec/requests/api/composer_packages_spec.rb
+14
-0
spec/support/shared_examples/requests/api/composer_packages_shared_examples.rb
...xamples/requests/api/composer_packages_shared_examples.rb
+62
-0
No files found.
app/finders/packages/group_packages_finder.rb
View file @
da86b006
...
...
@@ -40,11 +40,15 @@ module Packages
# access to packages is ruled by:
# - project is public or the current user has access to it with at least the reporter level
# - the repository feature is available to the current_user
if
current_user
.
is_a?
(
DeployToken
)
current_user
.
accessible_projects
else
::
Project
.
in_namespace
(
groups
)
.
public_or_visible_to_user
(
current_user
,
Gitlab
::
Access
::
REPORTER
)
.
with_feature_available_for_user
(
:repository
,
current_user
)
end
end
def
groups
return
[
group
]
if
exclude_subgroups?
...
...
doc/user/packages/composer_repository/index.md
View file @
da86b006
...
...
@@ -9,6 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15886) in GitLab 13.2.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/221259) from GitLab Premium to GitLab Free in 13.3.
> - Support for Composer 2.0 [added](https://gitlab.com/gitlab-org/gitlab/-/issues/259840) in GitLab 13.10.
> - Deploy token support [added](https://gitlab.com/gitlab-org/gitlab/-/issues/240897) in GitLab 14.6.
WARNING:
The Composer package registry for GitLab is under development and isn't ready for production use due to
...
...
@@ -88,13 +89,12 @@ Prerequisites:
-
A valid
`composer.json`
file.
-
The Packages feature is enabled in a GitLab repository.
-
The project ID, which is on the project's home page.
-
A
[
personal access token
](
../../../user/profile/personal_access_tokens.md
)
with the scope set to
`api`
.
-
One of the following token types:
-
A
[
personal access token
](
../../../user/profile/personal_access_tokens.md
)
with the scope set to
`api`
.
-
A
[
deploy token
](
../../project/deploy_tokens/index.md
)
with the scope set to
`write_package_registry`
.
NOTE:
[
Deploy tokens
](
../../project/deploy_tokens/index.md
)
are
[
not yet supported
](
https://gitlab.com/gitlab-org/gitlab/-/issues/240897
)
for use with Composer.
To publish the package:
To publish the package with a personal access token:
-
Send a
`POST`
request to the
[
Packages API
](
../../../api/packages.md
)
.
...
...
@@ -109,6 +109,21 @@ To publish the package:
-
`<tag>`
is the Git tag name of the version you want to publish.
To publish a branch, use
`branch=<branch>`
instead of
`tag=<tag>`
.
To publish the package with a deploy token:
-
Send a
`POST`
request to the
[
Packages API
](
../../../api/packages.md
)
.
For example, you can use
`curl`
:
```
shell
curl
--data
tag
=
<tag>
--header
"Deploy-Token: <deploy-token>"
"https://gitlab.example.com/api/v4/projects/<project_id>/packages/composer"
```
-
`<deploy-token>`
is your deploy token
-
`<project_id>`
is your project ID.
-
`<tag>`
is the Git tag name of the version you want to publish.
To publish a branch, use
`branch=<branch>`
instead of
`tag=<tag>`
.
You can view the published package by going to
**Packages & Registries > Package Registry**
and
selecting the
**Composer**
tab.
...
...
@@ -159,11 +174,11 @@ Prerequisites:
-
A package in the Package Registry.
-
The group ID, which is on the group's home page.
-
A
[
personal access token
](
../../../user/profile/personal_access_tokens.md
)
with the scope set to, at minimum,
`read_api`
.
NOTE:
[
Deploy tokens
](
../../project/deploy_tokens/index.md
)
are
[
not yet supported
](
https://gitlab.com/gitlab-org/gitlab/-/issues/240897
)
for use with Composer
.
-
One of the following token types:
-
A
[
personal access token
](
../../../user/profile/personal_access_tokens.md
)
with the scope set to, at minimum,
`api`
.
-
A
[
deploy token
](
../../project/deploy_tokens/index.md
)
with the scope set to
`read_package_registry`
,
`write_package_registry`
, or both
.
To install a package:
...
...
@@ -213,6 +228,8 @@ To install a package:
1.
Create an
`auth.json`
file with your GitLab credentials:
Using a personal access token:
```
shell
composer config gitlab-token.<DOMAIN-NAME> <personal_access_token>
```
...
...
@@ -229,6 +246,26 @@ To install a package:
}
```
Using a deploy token:
```
shell
composer config gitlab-token.<DOMAIN-NAME> <deploy_token_username> <deploy_token>
```
Result in the
`auth.json`
file:
```
json
{
...
"gitlab-token"
:
{
"<DOMAIN-NAME>"
:
{
"username"
:
"<deploy_token_username>"
,
"token"
:
"<deploy_token>"
,
...
}
}
```
You can unset this with the command:
```
shell
...
...
@@ -236,7 +273,8 @@ To install a package:
```
-
`<DOMAIN-NAME>`
is the GitLab instance URL
`gitlab.com`
or
`gitlab.example.com`
.
-
`<personal_access_token>`
with the scope set to
`read_api`
.
-
`<personal_access_token>`
with the scope set to
`api`
, or
`<deploy_token>`
with the scope set
to
`read_package_registry`
and/or
`write_package_registry`
.
1.
If you are on a GitLab self-managed instance, add
`gitlab-domains`
to
`composer.json`
.
...
...
@@ -298,10 +336,19 @@ To install a package:
WARNING:
Never commit the
`auth.json`
file to your repository. To install packages from a CI/CD job,
consider using the
[
`composer config`
](
https://getcomposer.org/doc/articles/handling-private-packages.md#satis
)
tool with your
personal
access token
consider using the
[
`composer config`
](
https://getcomposer.org/doc/articles/handling-private-packages.md#satis
)
tool with your access token
stored in a
[
GitLab CI/CD variable
](
../../../ci/variables/index.md
)
or in
[
HashiCorp Vault
](
../../../ci/secrets/index.md
)
.
### Working with Deploy Tokens
Although Composer packages are accessed at the group level, a group or project deploy token can be
used to access them:
-
A group deploy token has access to all packages published to projects in that group or its
subgroups.
-
A project deploy token only has access to packages published to that particular project.
## Supported CLI commands
The GitLab Composer repository supports the following Composer CLI commands:
...
...
lib/api/composer_packages.rb
View file @
da86b006
...
...
@@ -70,7 +70,7 @@ module API
end
desc
'Composer packages endpoint at group level'
route_setting
:authentication
,
job_token_allowed:
true
,
basic_auth_personal_access_token:
true
route_setting
:authentication
,
job_token_allowed:
true
,
basic_auth_personal_access_token:
true
,
deploy_token_allowed:
true
get
':id/-/packages/composer/packages'
do
presenter
.
root
end
...
...
@@ -79,7 +79,7 @@ module API
params
do
requires
:sha
,
type:
String
,
desc:
'Shasum of current json'
end
route_setting
:authentication
,
job_token_allowed:
true
,
basic_auth_personal_access_token:
true
route_setting
:authentication
,
job_token_allowed:
true
,
basic_auth_personal_access_token:
true
,
deploy_token_allowed:
true
get
':id/-/packages/composer/p/:sha'
do
presenter
.
provider
end
...
...
@@ -88,7 +88,7 @@ module API
params
do
requires
:package_name
,
type:
String
,
file_path:
true
,
desc:
'The Composer package name'
end
route_setting
:authentication
,
job_token_allowed:
true
,
basic_auth_personal_access_token:
true
route_setting
:authentication
,
job_token_allowed:
true
,
basic_auth_personal_access_token:
true
,
deploy_token_allowed:
true
get
':id/-/packages/composer/p2/*package_name'
,
requirements:
COMPOSER_ENDPOINT_REQUIREMENTS
,
file_path:
true
do
not_found!
if
packages
.
empty?
...
...
@@ -99,7 +99,7 @@ module API
params
do
requires
:package_name
,
type:
String
,
file_path:
true
,
desc:
'The Composer package name'
end
route_setting
:authentication
,
job_token_allowed:
true
,
basic_auth_personal_access_token:
true
route_setting
:authentication
,
job_token_allowed:
true
,
basic_auth_personal_access_token:
true
,
deploy_token_allowed:
true
get
':id/-/packages/composer/*package_name'
,
requirements:
COMPOSER_ENDPOINT_REQUIREMENTS
,
file_path:
true
do
not_found!
if
packages
.
empty?
not_found!
if
params
[
:sha
].
blank?
...
...
@@ -119,7 +119,7 @@ module API
desc
'Composer packages endpoint for registering packages'
namespace
':id/packages/composer'
do
route_setting
:authentication
,
job_token_allowed:
true
,
basic_auth_personal_access_token:
true
route_setting
:authentication
,
job_token_allowed:
true
,
basic_auth_personal_access_token:
true
,
deploy_token_allowed:
true
params
do
optional
:branch
,
type:
String
,
desc:
'The name of the branch'
...
...
spec/finders/packages/group_packages_finder_spec.rb
View file @
da86b006
...
...
@@ -107,6 +107,28 @@ RSpec.describe Packages::GroupPackagesFinder do
end
end
context
'deploy tokens'
do
let
(
:add_user_to_group
)
{
false
}
context
'group deploy token'
do
let_it_be
(
:deploy_token_for_group
)
{
create
(
:deploy_token
,
:group
,
read_package_registry:
true
)
}
let_it_be
(
:group_deploy_token
)
{
create
(
:group_deploy_token
,
deploy_token:
deploy_token_for_group
,
group:
group
)
}
let
(
:user
)
{
deploy_token_for_group
}
it
{
is_expected
.
to
match_array
([
package1
,
package2
,
package4
])
}
end
context
'project deploy token'
do
let_it_be
(
:deploy_token_for_project
)
{
create
(
:deploy_token
,
read_package_registry:
true
)
}
let_it_be
(
:project_deploy_token
)
{
create
(
:project_deploy_token
,
deploy_token:
deploy_token_for_project
,
project:
subproject
)
}
let
(
:user
)
{
deploy_token_for_project
}
it
{
is_expected
.
to
match_array
([
package4
])
}
end
end
context
'avoid N+1 query'
do
it
'avoids N+1 database queries'
do
count
=
ActiveRecord
::
QueryRecorder
.
new
{
subject
}
...
...
spec/requests/api/composer_packages_spec.rb
View file @
da86b006
...
...
@@ -9,6 +9,10 @@ RSpec.describe API::ComposerPackages do
let_it_be
(
:personal_access_token
)
{
create
(
:personal_access_token
,
user:
user
)
}
let_it_be
(
:package_name
)
{
'package-name'
}
let_it_be
(
:project
,
reload:
true
)
{
create
(
:project
,
:custom_repo
,
files:
{
'composer.json'
=>
{
name:
package_name
}.
to_json
},
group:
group
)
}
let_it_be
(
:deploy_token_for_project
)
{
create
(
:deploy_token
,
read_package_registry:
true
,
write_package_registry:
true
)
}
let_it_be
(
:project_deploy_token
)
{
create
(
:project_deploy_token
,
deploy_token:
deploy_token_for_project
,
project:
project
)
}
let_it_be
(
:deploy_token_for_group
)
{
create
(
:deploy_token
,
:group
,
read_package_registry:
true
,
write_package_registry:
true
)
}
let_it_be
(
:group_deploy_token
)
{
create
(
:group_deploy_token
,
deploy_token:
deploy_token_for_group
,
group:
group
)
}
let
(
:snowplow_gitlab_standard_context
)
{
{
project:
project
,
namespace:
project
.
namespace
,
user:
user
}
}
let
(
:headers
)
{
{}
}
...
...
@@ -92,6 +96,8 @@ RSpec.describe API::ComposerPackages do
group
.
update!
(
visibility_level:
Gitlab
::
VisibilityLevel
::
PRIVATE
)
end
it_behaves_like
'Composer access with deploy tokens'
context
'with access to the api'
do
where
(
:project_visibility_level
,
:user_role
,
:member
,
:user_token
,
:include_package
)
do
'PRIVATE'
|
:developer
|
true
|
true
|
:include_package
...
...
@@ -162,6 +168,8 @@ RSpec.describe API::ComposerPackages do
it_behaves_like
params
[
:shared_examples_name
],
params
[
:user_role
],
params
[
:expected_status
],
params
[
:member
]
end
end
it_behaves_like
'Composer access with deploy tokens'
end
it_behaves_like
'rejects Composer access with unknown group id'
...
...
@@ -219,6 +227,8 @@ RSpec.describe API::ComposerPackages do
end
end
end
it_behaves_like
'Composer access with deploy tokens'
end
it_behaves_like
'rejects Composer access with unknown group id'
...
...
@@ -265,6 +275,8 @@ RSpec.describe API::ComposerPackages do
it_behaves_like
params
[
:shared_examples_name
],
params
[
:user_role
],
params
[
:expected_status
],
params
[
:member
]
end
end
it_behaves_like
'Composer access with deploy tokens'
end
it_behaves_like
'rejects Composer access with unknown group id'
...
...
@@ -308,6 +320,8 @@ RSpec.describe API::ComposerPackages do
it_behaves_like
params
[
:shared_examples_name
],
params
[
:user_role
],
params
[
:expected_status
],
params
[
:member
]
end
end
it_behaves_like
'Composer publish with deploy tokens'
end
it_behaves_like
'rejects Composer access with unknown project id'
...
...
spec/support/shared_examples/requests/api/composer_packages_shared_examples.rb
View file @
da86b006
...
...
@@ -173,3 +173,65 @@ RSpec.shared_examples 'rejects Composer access with unknown project id' do
end
end
end
RSpec
.
shared_examples
'Composer access with deploy tokens'
do
shared_examples
'a deploy token for Composer GET requests'
do
context
'with deploy token headers'
do
let
(
:headers
)
{
basic_auth_header
(
deploy_token
.
username
,
deploy_token
.
token
)
}
before
do
group
.
update!
(
visibility_level:
Gitlab
::
VisibilityLevel
::
PRIVATE
)
end
context
'valid token'
do
it_behaves_like
'returning response status'
,
:success
end
context
'invalid token'
do
let
(
:headers
)
{
basic_auth_header
(
deploy_token
.
username
,
'bar'
)
}
it_behaves_like
'returning response status'
,
:not_found
end
end
end
context
'group deploy token'
do
let
(
:deploy_token
)
{
deploy_token_for_group
}
it_behaves_like
'a deploy token for Composer GET requests'
end
context
'project deploy token'
do
let
(
:deploy_token
)
{
deploy_token_for_project
}
it_behaves_like
'a deploy token for Composer GET requests'
end
end
RSpec
.
shared_examples
'Composer publish with deploy tokens'
do
shared_examples
'a deploy token for Composer publish requests'
do
let
(
:headers
)
{
basic_auth_header
(
deploy_token
.
username
,
deploy_token
.
token
)
}
context
'valid token'
do
it_behaves_like
'returning response status'
,
:success
end
context
'invalid token'
do
let
(
:headers
)
{
basic_auth_header
(
deploy_token
.
username
,
'bar'
)
}
it_behaves_like
'returning response status'
,
:unauthorized
end
end
context
'group deploy token'
do
let
(
:deploy_token
)
{
deploy_token_for_group
}
it_behaves_like
'a deploy token for Composer publish requests'
end
context
'group deploy token'
do
let
(
:deploy_token
)
{
deploy_token_for_project
}
it_behaves_like
'a deploy token for Composer publish requests'
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