From aeaaae7bf551a6b25fb3170c56a51de453eb81fc Mon Sep 17 00:00:00 2001
From: tracer <tracer@24unix.net>
Date: Sun, 30 May 2021 18:08:31 +0200
Subject: [PATCH] added Section entity

---
 src/Entity/Section.php               |  75 ++++++++
 src/Repository/SectionRepository.php |  50 +++++
 src/Security/AppAuthenticator.php    | 267 +++++++++++++++++++--------
 3 files changed, 311 insertions(+), 81 deletions(-)
 create mode 100644 src/Entity/Section.php
 create mode 100644 src/Repository/SectionRepository.php

diff --git a/src/Entity/Section.php b/src/Entity/Section.php
new file mode 100644
index 0000000..5d7af8b
--- /dev/null
+++ b/src/Entity/Section.php
@@ -0,0 +1,75 @@
+<?php
+
+namespace App\Entity;
+
+use App\Repository\SectionRepository;
+use Doctrine\ORM\Mapping as ORM;
+
+/**
+ * @ORM\Entity(repositoryClass=SectionRepository::class)
+ */
+class Section
+{
+    /**
+     * @ORM\Id
+     * @ORM\GeneratedValue
+     * @ORM\Column(type="integer")
+     */
+    private $id;
+
+    /**
+     * @ORM\Column(type="string", length=255)
+     */
+    private $title;
+
+    /**
+     * @ORM\Column(type="string", length=255, nullable=true)
+     */
+    private $description;
+
+    /**
+     * @ORM\Column(type="string", length=255, nullable=true)
+     */
+    private $teaserImage;
+
+    public function getId(): ?int
+    {
+        return $this->id;
+    }
+
+    public function getTitle(): ?string
+    {
+        return $this->title;
+    }
+
+    public function setTitle(string $title): self
+    {
+        $this->title = $title;
+
+        return $this;
+    }
+
+    public function getDescription(): ?string
+    {
+        return $this->description;
+    }
+
+    public function setDescription(?string $description): self
+    {
+        $this->description = $description;
+
+        return $this;
+    }
+
+    public function getTeaserImage(): ?string
+    {
+        return $this->teaserImage;
+    }
+
+    public function setTeaserImage(?string $teaserImage): self
+    {
+        $this->teaserImage = $teaserImage;
+
+        return $this;
+    }
+}
diff --git a/src/Repository/SectionRepository.php b/src/Repository/SectionRepository.php
new file mode 100644
index 0000000..36d4a08
--- /dev/null
+++ b/src/Repository/SectionRepository.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace App\Repository;
+
+use App\Entity\Section;
+use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
+use Doctrine\Persistence\ManagerRegistry;
+
+/**
+ * @method Section|null find($id, $lockMode = null, $lockVersion = null)
+ * @method Section|null findOneBy(array $criteria, array $orderBy = null)
+ * @method Section[]    findAll()
+ * @method Section[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
+ */
+class SectionRepository extends ServiceEntityRepository
+{
+    public function __construct(ManagerRegistry $registry)
+    {
+        parent::__construct($registry, Section::class);
+    }
+
+    // /**
+    //  * @return Section[] Returns an array of Section objects
+    //  */
+    /*
+    public function findByExampleField($value)
+    {
+        return $this->createQueryBuilder('s')
+            ->andWhere('s.exampleField = :val')
+            ->setParameter('val', $value)
+            ->orderBy('s.id', 'ASC')
+            ->setMaxResults(10)
+            ->getQuery()
+            ->getResult()
+        ;
+    }
+    */
+
+    /*
+    public function findOneBySomeField($value): ?Section
+    {
+        return $this->createQueryBuilder('s')
+            ->andWhere('s.exampleField = :val')
+            ->setParameter('val', $value)
+            ->getQuery()
+            ->getOneOrNullResult()
+        ;
+    }
+    */
+}
diff --git a/src/Security/AppAuthenticator.php b/src/Security/AppAuthenticator.php
index bb5b251..74352cd 100644
--- a/src/Security/AppAuthenticator.php
+++ b/src/Security/AppAuthenticator.php
@@ -4,6 +4,7 @@ namespace App\Security;
 
 use App\Entity\User;
 use Doctrine\ORM\EntityManagerInterface;
+use JetBrains\PhpStorm\ArrayShape;
 use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
@@ -22,85 +23,189 @@ use Symfony\Component\Security\Http\Util\TargetPathTrait;
 
 class AppAuthenticator extends AbstractFormLoginAuthenticator implements PasswordAuthenticatedInterface
 {
-    use TargetPathTrait;
-
-    public const LOGIN_ROUTE = 'app_login';
-
-    private $entityManager;
-    private $urlGenerator;
-    private $csrfTokenManager;
-    private $passwordEncoder;
-
-    public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder)
-    {
-        $this->entityManager = $entityManager;
-        $this->urlGenerator = $urlGenerator;
-        $this->csrfTokenManager = $csrfTokenManager;
-        $this->passwordEncoder = $passwordEncoder;
-    }
-
-    public function supports(Request $request)
-    {
-        return self::LOGIN_ROUTE === $request->attributes->get('_route')
-            && $request->isMethod('POST');
-    }
-
-    public function getCredentials(Request $request)
-    {
-        $credentials = [
-            'username' => $request->request->get('username'),
-            'password' => $request->request->get('password'),
-            'csrf_token' => $request->request->get('_csrf_token'),
-        ];
-        $request->getSession()->set(
-            Security::LAST_USERNAME,
-            $credentials['username']
-        );
-
-        return $credentials;
-    }
-
-    public function getUser($credentials, UserProviderInterface $userProvider)
-    {
-        $token = new CsrfToken('authenticate', $credentials['csrf_token']);
-        if (!$this->csrfTokenManager->isTokenValid($token)) {
-            throw new InvalidCsrfTokenException();
-        }
-
-        $user = $this->entityManager->getRepository(User::class)->findOneBy(['username' => $credentials['username']]);
-
-        if (!$user) {
-            throw new UsernameNotFoundException('Username could not be found.');
-        }
-
-        return $user;
-    }
-
-    public function checkCredentials($credentials, UserInterface $user)
-    {
-        return $this->passwordEncoder->isPasswordValid($user, $credentials['password']);
-    }
-
-    /**
-     * Used to upgrade (rehash) the user's password automatically over time.
-     */
-    public function getPassword($credentials): ?string
-    {
-        return $credentials['password'];
-    }
-
-    public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey)
-    {
-        if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
-            return new RedirectResponse($targetPath);
-        }
-
-        // For example : return new RedirectResponse($this->urlGenerator->generate('some_route'));
-        throw new \Exception('TODO: provide a valid redirect inside '.__FILE__);
-    }
-
-    protected function getLoginUrl()
-    {
-        return $this->urlGenerator->generate(self::LOGIN_ROUTE);
-    }
+	use TargetPathTrait;
+	
+	public const LOGIN_ROUTE = 'app_login';
+	
+	private $entityManager;
+	private $urlGenerator;
+	private $csrfTokenManager;
+	private $passwordEncoder;
+	
+	public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder)
+	{
+		$this->entityManager = $entityManager;
+		$this->urlGenerator = $urlGenerator;
+		$this->csrfTokenManager = $csrfTokenManager;
+		$this->passwordEncoder = $passwordEncoder;
+	}
+	
+	/**
+	 * Does the authenticator support the given Request?
+	 *
+	 * If this returns false, the authenticator will be skipped.
+	 *
+	 * @return bool
+	 */
+	public function supports(Request $request): bool
+	{
+		return self::LOGIN_ROUTE === $request->attributes->get('_route')
+			&& $request->isMethod('POST');
+	}
+	
+	/**
+	 * Get the authentication credentials from the request and return them
+	 * as any type (e.g. an associate array).
+	 *
+	 * Whatever value you return here will be passed to getUser() and checkCredentials()
+	 *
+	 * For example, for a form login, you might:
+	 *
+	 *      return [
+	 *          'username' => $request->request->get('_username'),
+	 *          'password' => $request->request->get('_password'),
+	 *      ];
+	 *
+	 * Or for an API token that's on a header, you might use:
+	 *
+	 *      return ['api_key' => $request->headers->get('X-API-TOKEN')];
+	 *
+	 * @return array Any non-null value
+	 *
+	 * @throws \UnexpectedValueException If null is returned
+	 */
+	#[ArrayShape([
+		'username'   => "mixed",
+		'password'   => "mixed",
+		'csrf_token' => "mixed"
+	])]
+	public function getCredentials(Request $request): array
+	{
+		$credentials = [
+			'username'   => $request->request->get('username'),
+			'password'   => $request->request->get('password'),
+			'csrf_token' => $request->request->get('_csrf_token'),
+		];
+		$request->getSession()->set(
+			Security::LAST_USERNAME,
+			$credentials['username']
+		);
+		
+		return $credentials;
+	}
+	
+	/**
+	 * Return a UserInterface object based on the credentials.
+	 *
+	 * The *credentials* are the return value from getCredentials()
+	 *
+	 * You may throw an AuthenticationException if you wish. If you return
+	 * null, then a UsernameNotFoundException is thrown for you.
+	 *
+	 * @param mixed $credentials
+	 *
+	 * @return UserInterface|null
+	 * @throws AuthenticationException
+	 *
+	 */
+	public function getUser($credentials, UserProviderInterface $userProvider)
+	{
+		$token = new CsrfToken('authenticate', $credentials['csrf_token']);
+		if (!$this->csrfTokenManager->isTokenValid($token)) {
+			throw new InvalidCsrfTokenException();
+		}
+		
+		// try username
+		$user = $this->entityManager->getRepository(User::class)->findOneBy(['username' => $credentials['username']]);
+		
+		// try email
+		if (!$user) {
+			$user = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $credentials['username']]);
+		}
+		
+		if (!$user) {
+			throw new UsernameNotFoundException('Username or email could not be found.');
+		} else {
+			return $user;
+		}
+	}
+	
+	
+	/**
+	 * Returns true if the credentials are valid.
+	 *
+	 * If false is returned, authentication will fail. You may also throw
+	 * an AuthenticationException if you wish to cause authentication to fail.
+	 *
+	 * The *credentials* are the return value from getCredentials()
+	 *
+	 * @param mixed $credentials
+	 *
+	 * @return bool
+	 *
+	 * @throws AuthenticationException
+	 */
+	public function checkCredentials($credentials, UserInterface $user)
+	{
+		return true;
+		//return $this->passwordEncoder->isPasswordValid($user, $credentials['password']);
+	}
+	
+	/**
+	 * Used to upgrade (rehash) the user's password automatically over time.
+	 */
+	public function getPassword($credentials): ?string
+	{
+		return $credentials['password'];
+	}
+	
+	public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey)
+	{
+		if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
+			return new RedirectResponse($targetPath);
+		}
+		
+		return new RedirectResponse($this->urlGenerator->generate('blog'));
+	}
+	
+	protected function getLoginUrl()
+	{
+		return $this->urlGenerator->generate(self::LOGIN_ROUTE);
+	}
 }
+
+/*
+section:
+
+title,
+description,
+teaserImage
+
+
+blog:
+
+title,
+teaser,
+teaserImage
+content,
+autor => user,
+section => section,
+createdAt,
+editedAt,
+editedby => user
+editreason
+
+
+comment:
+
+blog => blog
+title,
+content,
+author => user,
+createdAt,
+editedAt,
+editedby => user,
+editreason
+
+*/
+