| @@ -0,0 +1,8 @@ | |||
| # Default ignored files | |||
| /shelf/ | |||
| /workspace.xml | |||
| # Editor-based HTTP Client requests | |||
| /httpRequests/ | |||
| # Datasource local storage ignored files | |||
| /dataSources/ | |||
| /dataSources.local.xml | |||
| @@ -0,0 +1,4 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <project version="4"> | |||
| <component name="Encoding" addBOMForNewFiles="with NO BOM" /> | |||
| </project> | |||
| @@ -0,0 +1,39 @@ | |||
| { | |||
| "name": "spt/spt-bundle-core", | |||
| "version": "1.0.0", | |||
| "type": "symfony-bundle", | |||
| "description": "Core bundle for basic functionality", | |||
| "require": { | |||
| "php": ">=8.1", | |||
| "symfony/security-bundle": "^6.3", | |||
| "doctrine/doctrine-bundle": "^2.11", | |||
| "doctrine/orm": "^2.17", | |||
| "doctrine/doctrine-migrations-bundle": "^3.3" | |||
| }, | |||
| "autoload": { | |||
| "psr-4": { | |||
| "Spt\\SptCoreBundle\\": "src/" | |||
| } | |||
| }, | |||
| "authors": [ | |||
| { | |||
| "name": "Daniel Knudsen", | |||
| "email": "d.knudsen@spawntree.de" | |||
| }, | |||
| { | |||
| "name": "Florian Eisenmenger", | |||
| "email": "f.eisenmenger@spawntree.de" | |||
| } | |||
| ], | |||
| "config": { | |||
| }, | |||
| "require-dev": { | |||
| "symfony/maker-bundle": "^1.51" | |||
| }, | |||
| "scripts": { | |||
| "auto-scripts": { | |||
| "cache:clear": "symfony-cmd", | |||
| "assets:install %PUBLIC_DIR%": "symfony-cmd" | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,33 @@ | |||
| parameters: | |||
| services: | |||
| _defaults: | |||
| autowire: true | |||
| autoconfigure: true | |||
| Spt\SptCoreBundle\Controller\SecurityController: ~ | |||
| # makes classes in src/ available to be used as services | |||
| # this creates a service per class whose id is the fully-qualified class name | |||
| Spt\SptCoreBundle\: | |||
| resource: '../src/' | |||
| exclude: | |||
| - '../src/DependencyInjection/' | |||
| - '../src/Entity/' | |||
| - '../src/Kernel.php' | |||
| - '../src/Tests/' | |||
| # controllers are imported separately to make sure services can be injected | |||
| # as action arguments even if you don't extend any base controller class | |||
| Spt\SptCoreBundle\Controller\: | |||
| resource: '../src/Controller/' | |||
| tags: ['controller.service_arguments'] | |||
| Spt\SptCoreBundle\Command\: | |||
| resource: '../src/Command/' | |||
| autowire: true | |||
| autoconfigure: true | |||
| arguments: [ '@doctrine.orm.entity_manager', '@service_container' ] | |||
| tags: | |||
| - { name: 'console.command' } | |||
| @@ -0,0 +1,37 @@ | |||
| <?php | |||
| /** | |||
| * @author Daniel Knudsen <d.knudsen@spawntree.de> | |||
| * @date 20.10.23 | |||
| */ | |||
| namespace Spt\SptCoreBundle\Controller; | |||
| use Spt\SptCoreBundle\Entity\User; | |||
| use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; | |||
| use Symfony\Bundle\SecurityBundle\Security; | |||
| use Symfony\Component\HttpFoundation\JsonResponse; | |||
| use Symfony\Component\HttpFoundation\Request; | |||
| use Symfony\Component\HttpFoundation\Response; | |||
| use Symfony\Component\Routing\Annotation\Route; | |||
| use Symfony\Component\Security\Http\Attribute\CurrentUser; | |||
| class ApiLoginController extends AbstractController | |||
| { | |||
| #[Route('/api/login', name: 'spt_core_api_login', methods: ['POST'])] | |||
| public function index(Request $request): JsonResponse | |||
| { | |||
| $user = $this->getUser(); | |||
| if (null === $user) { | |||
| return $this->json([ | |||
| 'message' => 'missing credentials', | |||
| ], Response::HTTP_UNAUTHORIZED); | |||
| } | |||
| return $this->json([ | |||
| 'message' => 'Welcome to your new controller!', | |||
| 'path' => 'src/Controller/ApiLoginController.php', | |||
| ]); | |||
| } | |||
| } | |||
| @@ -0,0 +1,37 @@ | |||
| <?php | |||
| /** | |||
| * @author Daniel Knudsen <d.knudsen@spawntree.de> | |||
| * @date 20.10.23 | |||
| */ | |||
| namespace Spt\SptCoreBundle\Controller; | |||
| use Spt\SptCoreBundle\Entity\User; | |||
| use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; | |||
| use Symfony\Component\HttpFoundation\JsonResponse; | |||
| use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; | |||
| class RegistrationController extends AbstractController | |||
| { | |||
| public function index(UserPasswordHasherInterface $passwordHasher): JsonResponse | |||
| { | |||
| // manually hash pw | |||
| //php bin/console security:hash-password | |||
| // ... e.g. get the user data from a registration form | |||
| // $user = new User(...); | |||
| // $plaintextPassword = ...; | |||
| // | |||
| // // hash the password (based on the security.yaml config for the $user class) | |||
| // $hashedPassword = $passwordHasher->hashPassword( | |||
| // $user, | |||
| // $plaintextPassword | |||
| // ); | |||
| // $user->setPassword($hashedPassword); | |||
| // ... | |||
| } | |||
| } | |||
| @@ -0,0 +1,22 @@ | |||
| <?php | |||
| namespace Spt\SptCoreBundle\Controller; | |||
| use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; | |||
| use Symfony\Component\HttpFoundation\JsonResponse; | |||
| use Symfony\Component\Routing\Annotation\Route; | |||
| /** | |||
| * @author Daniel Knudsen <d.knudsen@spawntree.de> | |||
| * @date 18.10.23 | |||
| */ | |||
| class SecurityController extends AbstractController | |||
| { | |||
| #[Route('/test', name: 'spt_core_test')] | |||
| public function test() | |||
| { | |||
| return new JsonResponse('test'); | |||
| } | |||
| } | |||
| @@ -0,0 +1,32 @@ | |||
| <?php | |||
| /** | |||
| * @author Daniel Knudsen <d.knudsen@spawntree.de> | |||
| * @date 19.10.23 | |||
| */ | |||
| namespace Spt\SptCoreBundle\DependencyInjections; | |||
| use Exception; | |||
| use Symfony\Component\Config\FileLocator; | |||
| use Symfony\Component\DependencyInjection\ContainerBuilder; | |||
| use Symfony\Component\DependencyInjection\Extension\Extension; | |||
| use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; | |||
| class SptCoreExtension extends Extension | |||
| { | |||
| /** | |||
| * @throws Exception | |||
| */ | |||
| public function load(array $configs, ContainerBuilder $container): void | |||
| { | |||
| $loader = new YamlFileLoader( | |||
| $container, | |||
| new FileLocator(__DIR__ . '/../../config') | |||
| ); | |||
| $loader->load('services.yaml'); | |||
| } | |||
| } | |||
| @@ -0,0 +1,99 @@ | |||
| <?php | |||
| namespace Spt\SptCoreBundle\Entity; | |||
| use Doctrine\ORM\Mapping as ORM; | |||
| use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; | |||
| use Symfony\Component\Security\Core\User\UserInterface; | |||
| #[ORM\Entity] | |||
| #[ORM\Table(name: "user")] | |||
| class User implements UserInterface, PasswordAuthenticatedUserInterface | |||
| { | |||
| #[ORM\Id] | |||
| #[ORM\GeneratedValue] | |||
| #[ORM\Column] | |||
| private ?int $id = null; | |||
| #[ORM\Column(length: 180, unique: true)] | |||
| private ?string $email = null; | |||
| #[ORM\Column] | |||
| private array $roles = []; | |||
| /** | |||
| * @var string The hashed password | |||
| */ | |||
| #[ORM\Column] | |||
| private ?string $password = null; | |||
| public function getId(): ?int | |||
| { | |||
| return $this->id; | |||
| } | |||
| public function getEmail(): ?string | |||
| { | |||
| return $this->email; | |||
| } | |||
| public function setEmail(string $email): static | |||
| { | |||
| $this->email = $email; | |||
| return $this; | |||
| } | |||
| /** | |||
| * A visual identifier that represents this user. | |||
| * | |||
| * @see UserInterface | |||
| */ | |||
| public function getUserIdentifier(): string | |||
| { | |||
| return (string) $this->email; | |||
| } | |||
| /** | |||
| * @see UserInterface | |||
| */ | |||
| public function getRoles(): array | |||
| { | |||
| $roles = $this->roles; | |||
| // guarantee every user at least has ROLE_USER | |||
| $roles[] = 'ROLE_USER'; | |||
| return array_unique($roles); | |||
| } | |||
| public function setRoles(array $roles): static | |||
| { | |||
| $this->roles = $roles; | |||
| return $this; | |||
| } | |||
| /** | |||
| * @see PasswordAuthenticatedUserInterface | |||
| */ | |||
| public function getPassword(): string | |||
| { | |||
| return $this->password; | |||
| } | |||
| public function setPassword(string $password): static | |||
| { | |||
| $this->password = $password; | |||
| return $this; | |||
| } | |||
| /** | |||
| * @see UserInterface | |||
| */ | |||
| public function eraseCredentials(): void | |||
| { | |||
| // If you store any temporary, sensitive data on the user, clear it here | |||
| // $this->plainPassword = null; | |||
| } | |||
| } | |||
| @@ -0,0 +1,26 @@ | |||
| <?php | |||
| /** | |||
| * @author Daniel Knudsen <d.knudsen@spawntree.de> | |||
| * @date 18.10.23 | |||
| */ | |||
| namespace Spt\SptCoreBundle; | |||
| use Spt\SptCoreBundle\DependencyInjections\SptCoreExtension; | |||
| use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; | |||
| use Symfony\Component\HttpKernel\Bundle\AbstractBundle; | |||
| use function dirname; | |||
| class SptCoreBundle extends AbstractBundle | |||
| { | |||
| public function getPath(): string | |||
| { | |||
| return dirname(__DIR__); | |||
| } | |||
| public function getContainerExtension(): ?ExtensionInterface | |||
| { | |||
| return new SptCoreExtension(); | |||
| } | |||
| } | |||