Skip to content

Commit

Permalink
Merge pull request #124 from vtsykun/oauth2
Browse files Browse the repository at this point in the history
GitHub/GitLab integration
  • Loading branch information
vtsykun committed Jun 9, 2023
2 parents 73d9ebd + 1e19e7f commit f2232c7
Show file tree
Hide file tree
Showing 104 changed files with 4,710 additions and 155 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Table of content
- [Ssh key access](#ssh-key-access-and-composer-oauth-token)
- [Configuration](#configuration)
- [LDAP Authenticating](/docs/authentication-ldap.md)
- [OAuth2 and Sync](/docs/oauth2.md)
- [Update Webhooks](#update-webhooks)
- [Github](#github-webhooks)
- [GitLab](#gitlab-service)
Expand Down
8 changes: 5 additions & 3 deletions config/packages/security.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ security:
lazy: true
pattern: .*
user_checker: Packeton\Security\UserChecker
provider: all_users
custom_authenticators:
- Packeton\Integrations\Security\OAuth2Authenticator
'%default_login_provider%': '%default_login_options%'

remember_me:
secret: '%env(APP_SECRET)%'
user_providers: all_users
name: pauth
always_remember_me: true
samesite: 'lax'
lifetime: 31104000 # 1y
logout: true
Expand All @@ -53,7 +55,7 @@ security:
- { path: ^/_profiler/, roles: PUBLIC_ACCESS }

- { path: ^/login$, roles: PUBLIC_ACCESS }
- { path: ^/login/, roles: PUBLIC_ACCESS }
- { path: (^(/login/|/oauth2/))+, roles: PUBLIC_ACCESS }
- { path: ^/reset-password, roles: PUBLIC_ACCESS }

# Packagist
Expand All @@ -69,7 +71,7 @@ security:
# Maintainers
- { path: (^(/users/(.+)/packages))+, roles: ROLE_MAINTAINER }
- { path: (^(/users/(.+)/favorites))+, roles: ROLE_MAINTAINER }
- { path: (^(/metadata/changes.json$|/explore|/jobs/|/archive/))+, roles: ROLE_MAINTAINER }
- { path: (^(/metadata/changes.json$|/explore|/jobs/|/archive/|/api/hooks/))+, roles: ROLE_MAINTAINER }

# Secured part of the site
# This config requires being logged for the whole site and having the admin role for the admin part.
Expand Down
7 changes: 6 additions & 1 deletion config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ parameters:
- 'Packeton\Entity\Job'
- 'Packeton\Entity\SshCredentials'
- 'Packeton\Entity\ApiToken'
- 'Packeton\Entity\OAuthIntegration'
security_policy_forbidden_properties:
'Packeton\Entity\User': ['apiToken', 'githubToken', 'password', 'salt']
'Packeton\Entity\Package': ['credentials']
Expand Down Expand Up @@ -62,6 +63,7 @@ services:
$packageRegexp: '%package_name_regex%'
$swaggerDocsDir: '%kernel.project_dir%/swagger'
$artifactPaths: '%packeton_artifact_paths%'
$noPrivateHttpClient: '@Symfony\Component\HttpClient\NoPrivateNetworkHttpClient'
'Symfony\Component\Security\Core\User\UserCheckerInterface': '@Packeton\Security\UserChecker'

Packeton\:
Expand Down Expand Up @@ -217,4 +219,7 @@ services:
- '@Packeton\Security\Token\DefaultTokenChecker'
calls:
- [addTokenChecker, ['@Packeton\Security\Token\PatTokenChecker']]
- [addTokenChecker, ['@Packeton\Security\Token\PatTokenChecker']]
- [addTokenChecker, ['@Packeton\Security\Token\JwtTokenChecker']]
- [addTokenChecker, ['@Packeton\Security\Token\IntegrationTokenChecker']]

Symfony\Component\HttpClient\NoPrivateNetworkHttpClient: ~
File renamed without changes.
13 changes: 9 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@ services:
build:
context: .
image: packeton/packeton:latest
restart: unless-stopped
container_name: packagist
hostname: packagist
environment:
ADMIN_USER: admin
ADMIN_PASSWORD: 123456
ADMIN_EMAIL: admin@example.com
# ADMIN_USER: admin
# ADMIN_PASSWORD: 123456
# ADMIN_EMAIL: admin@example.com
TRUSTED_PROXIES: 172.16.0.0/12
# Default SQLite
# DATABASE_URL: "mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8&charset=utf8mb4"
DATABASE_URL: "mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8&charset=utf8mb4"

# MAILER_DSN: smtp://user:pass@smtp.mailgun.org:587
# MAILER_FROM: Packeton <packeton@example.com>
ports:
# setup nginx reverse proxy for ssl
- '127.0.0.1:8088:80'
volumes:
- .docker:/data
1 change: 1 addition & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
- [User Authentication](authentication.md)
- [JWT Configuration](authentication-jwt.md)
- [LDAP Configuration](authentication-ldap.md)
- [OAuth2 Integrations](oauth2.md)

# Development
- [Contributing](dev/CONTRIBUTING.md)
Expand Down
Binary file added docs/img/gitlab.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
78 changes: 78 additions & 0 deletions docs/oauth2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# OAuth2 and Sync integrations

## Base configuration

To enable OAuth2 integrations you need to add following configuration
```yml
packeton:
integrations:
github: # Alias name
allow_login: true # default false
allow_register: true # default false
default_roles: ['ROLE_USER', 'ROLE_MAINTAINER', 'ROLE_GITLAB']
login_title: Login or Register with GitHub
clone_preference: 'api'
repos_synchronization: true
# webhook_url: 'https://packeton.google.dev/' - overwrite host when setup webhooks
github:
client_id: 'xxx'
client_secret: 'xxx'

gitlab2: # Alias name - may be any url safe value.
base_url: 'https://gitlab.production.com/'
clone_preference: 'clone_https' # Allows [api, clone_https, clone_ssh]
gitlab: # Provider name: github, gitlab, bitbucket etc
client_id: 'xxx'
client_secret: 'xxx'
api_version: 'v4' # you may overwrite only for gitlab provider, default v4
```

Where `clone_preference`:

- `api` - Use api to get composer info
- `clone_https` - clone repo with using oauth api token
- `clone_ssh` - clone repo with system ssh key

`repos_synchronization` - If enabled, a new package will be automatically created when you will push to a new or exists repo that contains `composer.json`

## Supported 3-d provider

### GitHub

Scopes:

- login: `user:email`
- repositories: `read:org`, `repo`

Redirect Urls:

```
https://example.com/
```

### GitLab

Scopes:

- login: `read_user`
- repositories: `api`

Redirect Urls:

```
https://example.com/oauth2/{alias}/install
https://example.com/oauth2/{alias}/check
```

#### GitLab Groups Webhooks notices

A group webhooks needed for synchronization a new package.
They are triggered by events that occur across all projects in the group.
This feature enabled only for Premium / EE / Gold paid plan, but it can be replaced with GitLab Packagist Integration

You must manually setup this integration.

[![Gitlab](img/gitlab.png)](img/gitlab.png)

Where token you can find on the packeton integration view page. The token must have `whk` prefix
to find related integration access token.
18 changes: 17 additions & 1 deletion public/packeton/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,7 @@ button {
padding: 7px 11px 6px 9px;
border-radius: 2px;
box-shadow: none;
border-color: inherit;
}

.form-control[data-api-token] {
Expand Down Expand Up @@ -773,14 +774,18 @@ input:focus:invalid:focus, textarea:focus:invalid:focus, select:focus:invalid:fo
font-size: 12px;
}

.btn.loading, .btn.loading:hover, .btn.loading:active, .btn.loading:focus {
a.loading .btn, .btn.loading, .btn.loading:hover, .btn.loading:active, .btn.loading:focus, a.loading .btn:focus, a.loading .btn:active {
background-image: url("../img/loader.gif");
background-position: 95% 50%;
background-repeat: no-repeat;
pointer-events: none;
opacity: 0.75;
}

a.loading, a:has(> .btn.loading ) {
pointer-events: none;
}

.btn-default {
background: #bbbfc4;
border-bottom-color: #a5aab0;
Expand Down Expand Up @@ -1830,3 +1835,14 @@ label.required em {
.well-card .title {
font-size: 26px !important;
}

.select2-selection {
min-height: 33px;
}

.select2-container--default .select2-selection--single .select2-selection__arrow {
height: 33px!important;
}
.select2-selection__rendered {
padding-top: 2px;
}
Binary file added public/packeton/img/logo/bitbucket.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/packeton/img/logo/gitea.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/packeton/img/logo/github.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/packeton/img/logo/gitlab.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 44 additions & 0 deletions public/packeton/js/integration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
(function ($, humane) {
"use strict";
let connBtn = $('.connect');

connBtn.on('click', (e) => {

e.preventDefault();
let el = $(e.currentTarget);
let btn = el.find('.btn')
btn.addClass('loading');
let url = el.attr('href');

let options = {
type: 'POST',
url: url,
data: {
'token': el.attr('data-token'),
'org': el.attr('data-org')
},

success: (data) => {
btn.removeClass('loading');
if (data['connected']) {
btn.removeClass('btn-primary');
btn.addClass('btn-danger');
btn.html('Discontent');
} else {
btn.removeClass('btn-danger');
btn.addClass('btn-primary');
btn.html('Connect');
}
},
error: (err) => {
btn.removeClass('loading');
console.log(err);
},
always: () => {
btn.removeClass('loading');
}
};

$.ajax(options);
});
})(jQuery, humane);
36 changes: 36 additions & 0 deletions public/packeton/js/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,37 @@
}
});

$('.onclick-confirm').on('click', (e) => {
let message = $(e.currentTarget).attr('data-msg') || $(e.target).attr('data-msg');
if (!confirm(message ? message : 'Are you sure?')) {
e.preventDefault();
}
});

$('.ajax-url').on('click', (e) => {
e.preventDefault();
let message = $(e.currentTarget).attr('data-msg') || $(e.target).attr('data-msg');
let btn = $(e.currentTarget || e.target);
let url = $(e.currentTarget).attr('data-url') || $(e.target).attr('data-url');
let method = $(e.currentTarget).attr('data-method') || $(e.target).attr('data-method') || 'POST';

if (message && !confirm(message)) {
return;
}
btn.addClass('loading');

$.ajax({
url: url,
type: method,
success: () => {
btn.removeClass('loading');
},
error: () => {
btn.removeClass('loading');
}
});
});

/**
* Ajax error handler
*/
Expand Down Expand Up @@ -90,4 +121,9 @@
if (typeof select2.select2 === 'function') {
select2.select2();
}

let tooltip = $('[data-toggle="tooltip"]');
if (typeof tooltip.tooltip === 'function') {
tooltip.tooltip();
}
})(jQuery, humane);
9 changes: 9 additions & 0 deletions public/packeton/js/redirect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
(function () {
"use strict";
let el = document.getElementById('route');
let route = el.getAttribute('href');

setTimeout(() => {
location.href = route;
}, 500);
})();
2 changes: 1 addition & 1 deletion public/packeton/js/submitPackage.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
});
$('#submit-package-form').prepend('<ul class="list-unstyled package-errors">'+html+'</ul>');
} else {
if (data.similar.length) {
if (data.similar && data.similar.length) {
let $similar = $('<ul class="list-unstyled similar-packages">');
let limit = data.similar.length > showSimilarMax ? showSimilarMax : data.similar.length;
for ( let i = 0; i < limit; i++ ) {
Expand Down
1 change: 0 additions & 1 deletion public/packeton/js/uploadZipball.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@
wrap.select2({'data': result});
wrap.html(options.join('')).change();
wrap.val(prev);

}
}
});
Expand Down
5 changes: 5 additions & 0 deletions src/Composer/Archiver/ArchiveManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ public function setSubDirectory(?string $subDir): void
$this->subDirectory = $subDir;
}

public function getDownloadManager(): DownloadManager
{
return $this->downloadManager;
}

/**
* {@inheritdoc}
*/
Expand Down
Loading

0 comments on commit f2232c7

Please sign in to comment.