1
0
mirror of https://koodu.h-i.works/projects/thebadspace synced 2025-06-25 16:04:37 -05:00

Auth Framework, Part 1

Started buildig the authorization infrastructure to 1. create the
initial admin class to then 2. the Auth manager class can be created to
manage access based on roles.

added number of template files as well just as a UI base to get things
started.

Auth Framework Part 2 will complete the Auth mangager and clean up the
admin area.
This commit is contained in:
Ro
2022-12-12 17:42:40 -08:00
parent 74ae426275
commit 54b5227a0d
23 changed files with 3567 additions and 4 deletions

View File

@ -0,0 +1,44 @@
<?php
// src/Controller/DataImport.php
// Grab data from transfer app
namespace App\Controller\Routes\Back;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
//use App\Utils\PageRender;
//use App\Data\Auth;
class Index extends AbstractController
{
/**
* @Route("/screendoor", name="back-index")
*/
public function showBackIndex(Request $request): Response
{
return $this->render("back/index.twig", [
"title" => "Close the door behind you",
]);
/*
$result = $auth->status();
if ($result["status"]) {
return $render->renderPage(
[
"bgImage" => "/images/base/tweed-flowers.png",
"role" => $result["role"],
],
"The Nile List | Welcome Back",
"front/index.html.twig"
);
} else {
//back to index to login
header("Location:/login");
return new Response("<html><body>LOGGED IN</body></html>");
}
*/
}
}

View File

@ -0,0 +1,144 @@
<?php
// src/Controller/DataImport.php
// Grab data from transfer app
namespace App\Controller\Routes\Back;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Doctrine\Persistence\ManagerRegistry;
//use App\Utils\PageRender;
//use App\Utils\StringTools;
use App\Service\Auth;
use App\Service\HandleMembers;
class Members extends AbstractController
{
/**
* @Route("/dashboard/members", name="dash-members")
*/
public function showMembers(
Request $request,
Auth $auth
): Response {
$result = $auth->status();
if ($result["status"]) {
/*
return $render->renderPage(
["bgImage" => "", "mode" => "index"],
"The Nile List | Members",
"dash/members.html.twig"
);
*/
} else {
//back to index to login
header("Location:/knockknock");
return new Response("<html><body>LOGGED IN</body></html>");
}
}
/**
* @Route("/screendoor/members/add", name="members-add")
*/
public function addMembers(
Request $request,
Auth $auth,
HandleMembers $members,
ManagerRegistry $doctrine
): Response {
$result = $auth->status();
if ($result["status"]) {
if ($request->getMethod() == "GET") {
return $this->render("back/members.twig", [
"title" => "Get a class from the cupboard",
"mode" => "add"
]);
} else {
//add new member
$token = $request->get("token");
$notice = "";
$entityManager = $doctrine->getManager();
//token check
if (!$this->isCsrfTokenValid("upload", $token)) {
$logger->info("CSRF failure");
return new Response(
"Operation not allowed",
Response::HTTP_BAD_REQUEST,
[
"content-type" => "text/plain",
]
);
}
if (
$request->request->get("handle") == "" ||
$request->request->get("role") == "" ||
$request->request->get("gender") == "" ||
$request->request->get("email") == "" ||
$request->request->get("pronoun") == ""
) {
return new Response("<html><body>All fields required</body></html>");
/*
$notice = "All fields are required, champ.";
return $render->renderPage(
["bgImage" => "", "mode" => "add", "notice" => $notice],
"The Nile List | Add Member Error",
"dash/members.html.twig"
);
*/
}
if (
!filter_var($request->request->get("email"), FILTER_VALIDATE_EMAIL)
) {
return new Response("<html><body>BOGUS EMAIL</body></html>");
/*
$notice = "Need a valid email, slick.";
return $render->renderPage(
["bgImage" => "", "mode" => "add", "notice" => $notice],
"The Nile List | Add Member Error",
"dash/members.html.twig"
);
*/
}
//check clear, call add method
$response = $members->addMember($request);
if ($response["status"]) {
/*
return $render->renderPage(
[
"bgImage" => "",
"mode" => "add",
"notice" => $response["message"],
],
"The Nile List | Add Members",
"dash/members.html.twig"
);
*/
return new Response("<html><body>MEMBER ADDED</body></html>");
} else {
return new Response("<html><body>" . $response["message"] . "</body></html>");
/*
return $render->renderPage(
["bgImage" => "", "message" => $response["message"]],
"The Nile List | Uh Oh Time",
"front/error.html.twig"
);
*/
}
}
} else {
//back to index to login
header("Location:/knockknock");
return new Response("<html><body>LOGGED IN</body></html>");
}
}
}

View File

@ -9,7 +9,6 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpClient\HttpClient;
//use App\Utils\PageRender;
//use App\Data\Auth;
@ -22,7 +21,7 @@ class Index extends AbstractController
public function showIndex(Request $request): Response
{
return $this->render("front/index.twig", [
"title" => "This is The Bad Space",
"title" => "This is The Bad Space",
]);
/*
$result = $auth->status();
@ -42,4 +41,14 @@ class Index extends AbstractController
}
*/
}
/**
* @Route("/knockknock", name="access")
*/
public function access(Request $request): Response
{
return $this->render("front/knock.twig", [
"title" => "Wipe Your feet",
]);
}
}

0
src/Entity/.gitignore vendored Normal file
View File

186
src/Entity/Member.php Normal file
View File

@ -0,0 +1,186 @@
<?php
namespace App\Entity;
use App\Repository\MemberRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: MemberRepository::class)]
class Member
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private ?string $uuid = null;
#[ORM\Column(length: 255)]
private ?string $handle = null;
#[ORM\Column(length: 255)]
private ?string $email = null;
#[ORM\Column(length: 255)]
private ?string $password = null;
#[ORM\Column]
private ?bool $active = null;
#[ORM\Column(nullable: true)]
private ?int $role = null;
#[ORM\Column(length: 255, nullable: true)]
private ?string $avatar = null;
#[ORM\Column(length: 255)]
private ?string $pronoun = null;
#[ORM\Column(length: 255)]
private ?string $gender = null;
#[ORM\Column]
private ?\DateTimeImmutable $createdAt = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
private ?\DateTimeInterface $lastLogin = null;
public function getId(): ?int
{
return $this->id;
}
public function getUuid(): ?string
{
return $this->uuid;
}
public function setUuid(string $uuid): self
{
$this->uuid = $uuid;
return $this;
}
public function getHandle(): ?string
{
return $this->handle;
}
public function setHandle(string $handle): self
{
$this->handle = $handle;
return $this;
}
public function getEmail(): ?string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
public function getPassword(): ?string
{
return $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
public function isActive(): ?bool
{
return $this->active;
}
public function setActive(bool $active): self
{
$this->active = $active;
return $this;
}
public function getRole(): ?int
{
return $this->role;
}
public function setRole(?int $role): self
{
$this->role = $role;
return $this;
}
public function getAvatar(): ?string
{
return $this->avatar;
}
public function setAvatar(?string $avatar): self
{
$this->avatar = $avatar;
return $this;
}
public function getPronoun(): ?string
{
return $this->pronoun;
}
public function setPronoun(string $pronoun): self
{
$this->pronoun = $pronoun;
return $this;
}
public function getGender(): ?string
{
return $this->gender;
}
public function setGender(string $gender): self
{
$this->gender = $gender;
return $this;
}
public function getCreatedAt(): ?\DateTimeImmutable
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeImmutable $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getLastLogin(): ?\DateTimeInterface
{
return $this->lastLogin;
}
public function setLastLogin(\DateTimeInterface $lastLogin): self
{
$this->lastLogin = $lastLogin;
return $this;
}
}

0
src/Repository/.gitignore vendored Normal file
View File

View File

@ -0,0 +1,66 @@
<?php
namespace App\Repository;
use App\Entity\Member;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<Member>
*
* @method Member|null find($id, $lockMode = null, $lockVersion = null)
* @method Member|null findOneBy(array $criteria, array $orderBy = null)
* @method Member[] findAll()
* @method Member[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class MemberRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Member::class);
}
public function save(Member $entity, bool $flush = false): void
{
$this->getEntityManager()->persist($entity);
if ($flush) {
$this->getEntityManager()->flush();
}
}
public function remove(Member $entity, bool $flush = false): void
{
$this->getEntityManager()->remove($entity);
if ($flush) {
$this->getEntityManager()->flush();
}
}
// /**
// * @return Member[] Returns an array of Member objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('m')
// ->andWhere('m.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('m.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }
// public function findOneBySomeField($value): ?Member
// {
// return $this->createQueryBuilder('m')
// ->andWhere('m.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}

97
src/Service/Auth.php Normal file
View File

@ -0,0 +1,97 @@
<?php
// src/Controller/ProductController.php
namespace App\Service;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use App\Entity\Members;
use ReallySimpleJWT\Token;
class Auth
{
private $session;
private $entityManager;
public function __construct(
EntityManagerInterface $entityManager,
RequestStack $requestStack
) {
$this->entityManager = $entityManager;
$this->session = $requestStack->getSession();
$this->secret = '!$ec7eT$l0w*';
}
public function authCheck($email, $password)
{
$response = [];
$member = new Members();
$members = $this->entityManager->getRepository(Members::class);
$member = $members->findOneBy(["email" => $email]);
if (!$member) {
$response = ["status" => false, "message" => "Member Not Found"];
} else {
if (!password_verify($password, $member->getPassword())) {
$response = ["status" => false, "message" => "Check that password"];
} else {
$this->session->set("member", $member);
$secret = $this->secret;
$expiration = time() + 3600;
$token = Token::create(
$member->getMemberId(),
$secret,
$expiration,
"nile_admin"
);
$this->session->set("token", $token);
$response = ["status" => true, "message" => "Welcome Back"];
}
}
return $response;
}
public function logOut()
{
$this->session->set("member", null);
$this->session->set("token", null);
}
public function APIStatus()
{
$response = [];
$verify = Token::validate($this->session->get("token"), $this->secret);
if ($verify) {
$response = [
"status" => true,
"message" => "Token is good",
"token" => $this->session->get("token"),
];
} else {
$response = ["status" => false, "message" => "Bad Token, champ."];
}
return $response;
}
public function status()
{
$response = [];
if ($this->session->get("member")) {
//$member = $this->session->get("member");
$response = [
"status" => true,
"role" => $this->session->get("member")->getRole(),
"token" => $this->session->get("token"),
];
} else {
$response = ["status" => false, "role" => null];
}
return $response;
}
}

View File

@ -0,0 +1,173 @@
<?php
// src/Controller/ProductController.php
namespace App\Service;
use Doctrine\DBAL\DBALException;
use Doctrine\ORM\ORMException;
use PDOException;
use Exception;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Uid\Uuid;
use App\Entity\Member;
//use App\Utils\StringTools;
/**
* Members
*
* Data class for interacting with Member data from the DB
*/
class HandleMembers
{
private $session;
private $entityManager;
public function __construct(
EntityManagerInterface $entityManager,
RequestStack $requestStack
) {
$this->entityManager = $entityManager;
$this->session = $requestStack->getSession();
}
/**
* Grabs member data object from the current section
*
* @return MEMBERS data object
*/
public function getMember()
{
$member = $this->session->get("member");
return $member;
}
/**
* Add new member to db
*
* @param Request $request object containing posted data
* @return JSON
*/
public function addMember($request)
{
$errorMessage = null;
$member = new Member();
//submitted values
$handle = $request->request->get("handle");
$member->setHandle($handle);
$gender = $request->request->get("gender");
$member->setGender($gender);
$role = $request->request->get("role");
$member->setRole($role);
$email = $request->request->get("email");
$member->setEmail($email);
$pronoun = $request->request->get("pronoun");
$member->setPronoun($pronoun);
//set defaults
//$utils = new StringTools();
$uuid = $hash = password_hash("passw0rd!", PASSWORD_DEFAULT);
$member->setPassword($hash);
$member->setAvatar("default-member-avatar");
$member->setUuid(Uuid::v4());
$member->setActive(false);
$member->setCreatedAt(new \DateTimeImmutable());
$member->setLastLogin(new \DateTimeImmutable());
$this->entityManager->persist($member);
try {
$this->entityManager->flush();
} catch (PDOException $error) {
$errorMessage = $error->getMessage();
} catch (DBALException $error) {
$errorMessage = $error->getMessage();
} catch (ORMException $error) {
$errorMessage = $error->getMessage();
} catch (Exception $error) {
$errorMessage = $error->getMessage();
} catch (SyntaxErrorException $e) {
$errorMessage = $error->getMessage();
}
// return result status
if ($errorMessage == null) {
return $response = [
"status" => true,
"message" => "New member added. Woohoo!",
];
} else {
return $response = ["status" => false, "message" => $errorMessage];
}
}
/**
* Updates member data in db
*
* @param Request $request object containing posted data
* @return JSON
*/
public function updateMember($request)
{
$errorMessage = null;
$currentMember = $this->getMember();
$id = $currentMember->getMemberId();
$member = $this->entityManager->getRepository(Members::class)->find($id);
$image = $request->files->get("avi");
if (!empty($image)) {
$name = $image->getClientOriginalName();
$member->setAvatar($name);
}
$first = $request->request->get("first_name");
$member->setFirstName($first);
$last = $request->request->get("last_name");
$member->setLastName($last);
$handle = $request->request->get("handle");
$member->setHandle($handle);
$gender = $request->request->get("gender");
$member->setGender($gender);
$public = $request->request->get("public");
if ($public == "true") {
$member->setPublicProfile(true);
} else {
$member->setPublicProfile(false);
}
$email = $request->request->get("email");
$member->setEmail($email);
$pronoun = $request->request->get("pronoun");
$member->setPronouns($pronoun);
$pass_new = $request->request->get("password_new");
if ($pass_new != "" || $pass_new != null) {
$hash = password_hash($pass_new, PASSWORD_DEFAULT);
$member->setPassword($hash);
}
$this->entityManager->persist($member);
//error checking
try {
$this->entityManager->flush();
} catch (PDOException $error) {
$errorMessage = $error->getMessage();
} catch (DBALException $error) {
$errorMessage = $error->getMessage();
} catch (ORMException $error) {
$errorMessage = $error->getMessage();
} catch (Exception $error) {
$errorMessage = $error->getMessage();
} catch (SyntaxErrorException $e) {
$errorMessage = $error->getMessage();
}
// return result status
if ($errorMessage == null) {
$this->session->set("member", $member);
return $response = [
"status" => true,
"message" => "Profile Updated! Nice!",
];
} else {
return $response = ["status" => false, "message" => $errorMessage];
}
}
}