| @@ -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(); | |||||
| } | |||||
| } | |||||