Skip to content

Commit

Permalink
GitLab base integration
Browse files Browse the repository at this point in the history
  • Loading branch information
vtsykun committed Jun 3, 2023
1 parent 5ec3ccf commit 7b53797
Show file tree
Hide file tree
Showing 36 changed files with 925 additions and 86 deletions.
5 changes: 4 additions & 1 deletion config/packages/security.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ 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:
Expand All @@ -53,7 +56,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 Down
4 changes: 4 additions & 0 deletions 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 @@ -218,3 +220,5 @@ services:
calls:
- [addTokenChecker, ['@Packeton\Security\Token\PatTokenChecker']]
- [addTokenChecker, ['@Packeton\Security\Token\PatTokenChecker']]

Symfony\Component\HttpClient\NoPrivateNetworkHttpClient: ~
12 changes: 12 additions & 0 deletions 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 @@ -1830,3 +1831,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;
}
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);
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
20 changes: 18 additions & 2 deletions src/Composer/PackagistFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
use Packeton\Composer\Repository\PacketonRepositoryInterface;
use Packeton\Composer\Util\ConfigFactory;
use Packeton\Composer\Util\ProcessExecutor;
use Packeton\Entity\OAuthIntegration;
use Packeton\Integrations\IntegrationRegistry;
use Packeton\Model\CredentialsInterface;
use Packeton\Package\RepTypes;

Expand All @@ -24,6 +26,7 @@ class PackagistFactory

public function __construct(
protected PacketonRepositoryFactory $repositoryFactory,
protected IntegrationRegistry $integrations,
protected bool $githubNoApi = true,
string $composerHome = null
) {
Expand Down Expand Up @@ -56,7 +59,7 @@ public function createDownloadManager(IOInterface $io, PacketonRepositoryInterfa
* @param PacketonRepositoryInterface $repository
* @param DownloadManager|null $dm
*
* @return \Composer\Package\Archiver\ArchiveManager
* @return \Composer\Package\Archiver\ArchiveManager|Archiver\ArchiveManager
*/
public function createArchiveManager(IOInterface $io, PacketonRepositoryInterface $repository, DownloadManager $dm = null): ArchiveManager
{
Expand Down Expand Up @@ -105,7 +108,8 @@ public function createConfig(CredentialsInterface $credentials = null)

if ($credentials->getKey()) {
$uid = @getmyuid();
$credentialsFile = rtrim($this->tmpDir, '/') . '/packeton_priv_key_' . $credentials->getId() . '_' . $uid;
$keyId = method_exists($credentials, 'getId') ? $credentials->getId() : sha1((string)$credentials->getKey());
$credentialsFile = rtrim($this->tmpDir, '/') . '/packeton_priv_key_' . $keyId . '_' . $uid;
if (!file_exists($credentialsFile)) {
file_put_contents($credentialsFile, $credentials->getKey());
chmod($credentialsFile, 0600);
Expand Down Expand Up @@ -139,6 +143,11 @@ public function createRepository(string $url, IOInterface $io = null, Config $co
$config = $this->createConfig($credentials);
$io->loadConfiguration($config);
}
$oauth2 = $repoConfig['oauth2'] ?? null;
if ($oauth2 instanceof OAuthIntegration && $this->integrations->has($oauth2->getAlias())) {
$app = $this->integrations->get($oauth2->getAlias());
$app->authenticateIO($oauth2, $io, $config, $url);
}

$repoConfig['url'] = $url;
if (isset($repoConfig['subDirectory']) || ($repoConfig['repoType'] ?? null) === RepTypes::MONO_REPO) {
Expand All @@ -152,6 +161,13 @@ public function createRepository(string $url, IOInterface $io = null, Config $co
}
}

if ($config->has('_no_api')) {
$repoConfig['no-api'] = $config->get('_no_api');
}
if ($config->has('_driver')) {
$repoConfig['driver'] = $config->get('_driver');
}

return $this->repositoryFactory->create($repoConfig, $io, $config, $repoConfig['repoType'] ?? null);
}
}
8 changes: 8 additions & 0 deletions src/Controller/Api/ApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Doctrine\Persistence\ManagerRegistry;
use Packeton\Attribute\Vars;
use Packeton\Controller\ControllerTrait;
use Packeton\Entity\OAuthIntegration;
use Packeton\Entity\Package;
use Packeton\Entity\User;
use Packeton\Entity\Webhook;
Expand Down Expand Up @@ -74,6 +75,13 @@ public function createPackageAction(Request $request): Response
return new JsonResponse(['status' => 'success', 'job' => $job->getId()], 202);
}

#[Route('/api/hooks/{alias}/{id}', name: 'api_integration_postreceive')]
public function integrationHook(Request $request, string $alias, #[Vars] OAuthIntegration $oauth): Response
{
// parse the payload
$payload = $this->getJsonPayload($request);
}

#[Route('/api/github', name: 'github_postreceive')]
#[Route('/api/bitbucket', name: 'bitbucket_postreceive')]
#[Route('/api/update-package', name: 'generic_postreceive')]
Expand Down
11 changes: 10 additions & 1 deletion src/Entity/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
use Doctrine\ORM\Mapping as ORM;
use Packeton\Model\BaseUser;
use Packeton\Model\PacketonUserInterface;
use Packeton\Repository\UserRepository;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;

#[ORM\Entity(repositoryClass: 'Packeton\Repository\UserRepository')]
#[ORM\Entity(repositoryClass: UserRepository::class)]
#[ORM\Table(name: 'fos_user')]
#[ORM\UniqueConstraint(columns: ['email_canonical'])]
#[ORM\UniqueConstraint(columns: ['username_canonical'])]
Expand Down Expand Up @@ -187,10 +188,13 @@ public function getGithubId()
* Set githubId.
*
* @param string $githubId
* @return $this
*/
public function setGithubId($githubId)
{
$this->githubId = $githubId;

return $this;
}

/**
Expand Down Expand Up @@ -358,6 +362,11 @@ public function isMaintainer()
return $this->hasRole('ROLE_MAINTAINER') || $this->isAdmin() || $this->isSuperAdmin();
}

public function isExternal(): bool
{
return $this->hasRole('ROLE_OAUTH') || $this->githubId !== null;
}

/**
* {@inheritdoc}
*/
Expand Down
3 changes: 2 additions & 1 deletion src/Entity/Version.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Packeton\Composer\MetadataMinifier;
use Packeton\Repository\VersionRepository;
use Symfony\Component\Validator\Constraints as Assert;

#[ORM\Entity(repositoryClass: 'Packeton\Repository\VersionRepository')]
#[ORM\Entity(repositoryClass: VersionRepository::class)]
#[ORM\Table(name: 'package_version')]
#[ORM\UniqueConstraint(name: 'pkg_ver_idx', columns: ['package_id', 'normalizedVersion'])]
#[ORM\Index(columns: ['releasedAt'], name: 'release_idx')]
Expand Down
26 changes: 21 additions & 5 deletions src/Form/Type/BasePackageType.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace Packeton\Form\Type;

use Doctrine\Persistence\ManagerRegistry;
use Packeton\Entity\OAuthIntegration;
use Packeton\Entity\Package;
use Packeton\Package\RepTypes;
use Symfony\Component\Form\AbstractType;
Expand All @@ -13,20 +15,34 @@

class BasePackageType extends AbstractType
{
public function __construct(protected ManagerRegistry $registry)
{
}

public function buildForm(FormBuilderInterface $builder, array $options): void
{
if ($options['is_created']) {
$choices = [
'VCS (auto)' => RepTypes::VCS,
'MonoRepos (only GIT)' => RepTypes::MONO_REPO,
'Artifacts' => RepTypes::ARTIFACT,
];
if ($this->hasActiveIntegration()) {
$choices['Integration'] = RepTypes::INTEGRATION;
}

$builder->add('repoType', ChoiceType::class, [
'choices' => [
'VCS (auto)' => RepTypes::VCS,
'MonoRepos (only GIT)' => RepTypes::MONO_REPO,
'Artifacts' => RepTypes::ARTIFACT,
],
'choices' => $choices,
'attr' => ['class' => 'repo-type']
]);
}
}

protected function hasActiveIntegration(): bool
{
return (bool) $this->registry->getRepository(OAuthIntegration::class)->findOneBy([]);
}

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

0 comments on commit 7b53797

Please sign in to comment.