Skip to content

Commit

Permalink
Merge pull request #152 from Pietrucci-Blacher/feat/separate-levels-b…
Browse files Browse the repository at this point in the history
…y-role

Feat/separate levels by role
  • Loading branch information
Pietrucci-Blacher authored Nov 20, 2023
2 parents 757aaa6 + 7c7b984 commit b3bc81b
Show file tree
Hide file tree
Showing 30 changed files with 427 additions and 81 deletions.
Binary file added .DS_Store
Binary file not shown.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
| Feature Name | Author | Link PR |
|-------------------------------------------------------------------------------|--------------|---------|
| Separer le front par role & rajouter la securité & rajouter layout par niveau | Ossama DAHBI | https://github.com/Pietrucci-Blacher/Challenge-Semestriel-1-5IW/pull/152 |
18 changes: 16 additions & 2 deletions back/api/src/Entity/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,11 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
* @var string The hashed password
*/
#[ORM\Column]
private ?string $password = null;

#[Assert\NotBlank(groups: ['user:create'])]
#[Groups(['user:create', 'user:update'])]
private ?string $password = null;
private ?string $plainPassword = null;

#[ORM\Column]
private ?bool $is_active = false;
Expand Down Expand Up @@ -214,6 +216,18 @@ public function setPassword(string $password): static
return $this;
}

public function getPlainPassword(): ?string
{
return $this->plainPassword;
}

public function setPlainPassword(?string $plainPassword): self
{
$this->plainPassword = $plainPassword;

return $this;
}

public function getBirthdate(): ?\DateTimeInterface
{
return $this->birthdate;
Expand Down Expand Up @@ -386,7 +400,7 @@ public function getUserIdentifier(): string
public function eraseCredentials(): void
{
// If you store any temporary, sensitive data on the user, clear it here
// $this->plainPassword = null;
$this->plainPassword = null;
}

public function getIsActive(): ?bool
Expand Down
8 changes: 3 additions & 5 deletions back/api/src/State/UserPasswordHasher.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,17 @@ public function __construct(private readonly ProcessorInterface $processor, priv
*/
public function process($data, Operation $operation, array $uriVariables = [], array $context = [])
{
if (!$data->getPassword()) {
if (!$data->getPlainPassword()) {
return $this->processor->process($data, $operation, $uriVariables, $context);
}

$hashedPassword = $this->passwordHasher->hashPassword(
$data,
$data->getPassword()
$data->getPlainPassword()
);
$data->setPassword($hashedPassword);
$data->eraseCredentials();


// $email = new Email();
// $email->sendEmail("[email protected]", $data->getEmail(), 'Welcome to Resend', 'Welcome to Resend');
return $this->processor->process($data, $operation, $uriVariables, $context);
}
}
8 changes: 7 additions & 1 deletion front/next.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
/** @type {import('next').NextConfig} */
const nextConfig = {}
const nextConfig = {
async rewrites() {
return {
fallback: [{source: '/:path*', destination: '/user/:path*'}]
}
},
}

module.exports = nextConfig
8 changes: 8 additions & 0 deletions front/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

87 changes: 87 additions & 0 deletions front/src/components/ChooseLayout.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import {useAuthContext} from "@/providers/AuthProvider";
import {useRouter} from "next/router";
import AdminLayout from "@/layouts/AdminLayout";
import UserLayout from "@/layouts/UserLayout";
import ProviderLayout from "@/layouts/ProviderLayout";
import DefaultLayout from "@/layouts/DefaultLayout";
import Header from "@/components/Header";
import {Flowbite} from "flowbite-react";
import {useEffect} from "react";

const canAccessTo = (path, roles) => {
const lowerCaseRoles = roles.join(',').toLowerCase() ?? ""
if (path.startsWith('/admin')) {
return lowerCaseRoles.includes('admin');
}
else if (path.startsWith('/provider')) {
return lowerCaseRoles.includes('provider') || lowerCaseRoles.includes('admin');
}
else if (path.startsWith('/user')) {
return lowerCaseRoles.includes('user') || lowerCaseRoles.includes('admin') || lowerCaseRoles.includes('provider');
}
return true
};

const ChooseLayout = ({children}) => {
const {user, isLogged} = useAuthContext()
const router = useRouter()
const path = router.pathname
const needsAuth = path.startsWith('/admin') || path.startsWith('/provider') || path.startsWith('/user');
useEffect(() => {
if (user !== undefined && needsAuth && !isLogged) {
router.push('/auth/login');
}
if (user !== undefined && needsAuth && !canAccessTo(path, user?.roles)) {
router.push('/auth/login');
}
}, [user, path]);

let Layout;

if (path.startsWith('/admin')) {
Layout = AdminLayout
} else if (path.startsWith('/provider')) {
Layout = ProviderLayout
} else if (path.startsWith('/user')) {
Layout = UserLayout
} else {
Layout = DefaultLayout
}
if (!needsAuth) {
return (
<>
<Flowbite>
<div className="grid grid-rows-[auto,1fr] h-screen dark:bg-gray-900">
<div>
<Header/>
</div>
<div className="flex flex-row">

<Layout>
{children}
</Layout>
</div>
</div>
</Flowbite>
</>
);
}
return (
<>
{isLogged && <Flowbite>
<div className="grid grid-rows-[auto,1fr] h-screen dark:bg-gray-900">
<div>
<Header/>
</div>
<div className="flex flex-row">

<Layout>
{children}
</Layout>
</div>
</div>
</Flowbite>}
</>
)
}
export default ChooseLayout
58 changes: 58 additions & 0 deletions front/src/components/Header.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import {Avatar, DarkThemeToggle, Dropdown, Navbar} from "flowbite-react";
import Image from "next/image";
import {useAuthContext} from "@/providers/AuthProvider";

export default function Header() {
const {user} = useAuthContext();
return (
<header className="sticky top-0 z-20">
<Navbar fluid rounded>
<Navbar.Brand href="/">
<Image
alt="Flowbite logo"
height="32"
src="https://flowbite.com/docs/images/logo.svg"
width="32"
/>
<span
className="self-center whitespace-nowrap pl-3 text-xl font-semibold dark:text-white">Flowbite</span>
</Navbar.Brand>

<div className="flex md:order-2">
<DarkThemeToggle className="mx-4"/>
{ user && <Dropdown
inline
label={
<Avatar
alt="User settings"
img="https://flowbite.com/docs/images/people/profile-picture-5.jpg"
rounded
/>
}
>
<Dropdown.Header>
<span className="block text-sm">{user.lastname} {user.firstname}</span>
<span className="block truncate text-sm font-medium">{user.email}</span>
</Dropdown.Header>
<Dropdown.Item>Dashboard</Dropdown.Item>
<Dropdown.Item>Settings</Dropdown.Item>
<Dropdown.Item>Earnings</Dropdown.Item>
<Dropdown.Divider/>
<Dropdown.Item href="/auth/logout">Sign out</Dropdown.Item>
</Dropdown> }
<Navbar.Toggle/>
</div>

<Navbar.Collapse>
<Navbar.Link href="#" active>
Home
</Navbar.Link>
<Navbar.Link href="#">About</Navbar.Link>
<Navbar.Link href="#">Services</Navbar.Link>
<Navbar.Link href="#">Pricing</Navbar.Link>
<Navbar.Link href="#">Contact</Navbar.Link>
</Navbar.Collapse>
</Navbar>
</header>
)
}
39 changes: 39 additions & 0 deletions front/src/components/Sidebar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {useState} from "react";
import {HiChartPie, HiViewBoards} from "react-icons/hi";
import {Sidebar as FlowbiteSidebar} from "flowbite-react";
import {BiBuoy} from "react-icons/bi";

const Sidebar = function ({content = []}) {
const [isOpen, setOpen] = useState(false);

const toggle = () => {
setOpen(!isOpen);
}

return (
<FlowbiteSidebar>
<FlowbiteSidebar.Items className="flex flex-col h-full justify-between">
<FlowbiteSidebar.ItemGroup>
{content.map((element, index)=>(
<FlowbiteSidebar.Item key={index} {...element}>
{element.text}
</FlowbiteSidebar.Item>
))}
</FlowbiteSidebar.ItemGroup>
<FlowbiteSidebar.ItemGroup className="py-4">
<FlowbiteSidebar.Item href="#" icon={HiChartPie}>
Upgrade to Pro
</FlowbiteSidebar.Item>
<FlowbiteSidebar.Item href="#" icon={HiViewBoards}>
Documentation
</FlowbiteSidebar.Item>
<FlowbiteSidebar.Item href="#" icon={BiBuoy}>
Help
</FlowbiteSidebar.Item>
</FlowbiteSidebar.ItemGroup>
</FlowbiteSidebar.Items>
</FlowbiteSidebar>
);
};

export default Sidebar;
12 changes: 8 additions & 4 deletions front/src/hooks/useAuth.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ export const useAuth = () => {

const login = async (credentials) => {
try {
sessionStorage.removeItem('token');
sessionStorage.removeItem('refreshToken');
const response = await loginService(credentials);
const token = response.token
const refreshToken = response.refresh_token
localStorage.setItem('token', token)
localStorage.setItem('refreshToken', refreshToken)
sessionStorage.setItem('token', token, {expires: 1});
sessionStorage.setItem('refreshToken', refreshToken, {expires: 7});
const user = await fetchCurrentUser()
setIsLogged(true);
setUser(user);
Expand All @@ -24,10 +26,12 @@ export const useAuth = () => {
await registerService(payload);
};

const logout = async () => {
// Logique de déconnexion
const logout = () => {
sessionStorage.removeItem('user')
setIsLogged(false);
setUser(null);
sessionStorage.removeItem("token")
sessionStorage.removeItem("refreshToken")
};

return {login, register, logout};
Expand Down
2 changes: 0 additions & 2 deletions front/src/hooks/useRequestsProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,13 @@ export default function useRequestsProvider() {
}

const getListOfRequests = async () =>{

const response = await getListOfRequestsService()
setRequests(response["hydra:member"])
}

const getRequest = async (payload) =>{
const response = await getRequestService(payload)
setRequest(response)
console.log(response)
}

const approveRequest = async (payload) =>{
Expand Down
7 changes: 2 additions & 5 deletions front/src/hooks/useResetPassword.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,10 @@ export function useResetPassword() {
async function checkResetToken(token) {
setIsLoading(true);
try {
const response = await checkResetTokenRequest(token)
console.log("re", response)
await checkResetTokenRequest(token)
setIsLoading(false);
setIsTokenValid(true);
} catch (err) {
createToast('error', 'Error recuperation token')
setIsLoading(false);
setIsTokenValid(false);
}
Expand All @@ -36,8 +34,7 @@ export function useResetPassword() {
async function updatePassword(token, newPassword) {
setIsLoading(true);
try {
const response = await updatePasswordRequest(token, newPassword)
createToast('success', 'Vous avez bien modifié votre password')
await updatePasswordRequest(token, newPassword)
return true
} catch (err) {
return false
Expand Down
24 changes: 24 additions & 0 deletions front/src/layouts/AdminLayout.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Sidebar from "@/components/Sidebar";
import {HiChartPie, HiInbox, HiShoppingBag, HiTable, HiUser, HiViewBoards} from "react-icons/hi";

const AdminLayout = ({children}) => {

const sidebarContent = [
{icon: HiChartPie, text: "Dashboard", href: "/admin", label: "Pro", labelColor: "gray"},
{icon: HiViewBoards, text: "Requests", href: "/admin/requests", label: "Pro", labelColor: "gray"},
{icon: HiInbox, text: "Establishment", href: "#", label: "Pro", labelColor: "gray"},
{icon: HiShoppingBag, text: "Services", href: "#", label: "Pro", labelColor: "gray"},
{icon: HiUser, text: "Users", href: "#", label: "Pro", labelColor: "gray"},
{icon: HiTable, text: "Reviews", href: "#", label: "Pro", labelColor: "gray"}
]
return (
<>

<Sidebar content={sidebarContent}/>
<main className="p-6">
{children}
</main>
</>
)
}
export default AdminLayout
11 changes: 11 additions & 0 deletions front/src/layouts/DefaultLayout.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const DefaultLayout = ({children}) => {
return (
<>
<main className="p-6">
{children}
</main>
</>
)
}

export default DefaultLayout
Loading

0 comments on commit b3bc81b

Please sign in to comment.