Admin Panel - Anniegavr/Collab-Buddy GitHub Wiki
The Admin Panel is protected with an extra authentication:
Here is how the User as a model is created in the frontend, as User.vue:
<template>
</template>
<script>
export default {
name: "User",
}
export interface User {
id: number;
name: string;
email: string;
role: string;
}
export class UserClass implements User {
id: number;
name: string;
email: string;
role: string;
constructor(id: number, name: string, email: string, role: string) {
this.id = id;
this.name = name;
this.email = email;
this.role = role;
}
isAdmin(): boolean {
return this.role === 'admin';
}
}
</script>
<style scoped>
</style>`
To restrict access to the admin panel only for users with admin privileges right in the frontend, I used Vue Router's navigation guards in my router:
// some router initialization here
// and then
// authentication guard function
const isAdmin = () => {
const user = isAuthenticated(); // get the authenticated user
return user && user.isAdmin; // check if the user has admin privileges
}
// navigation guard to restrict access to admin panel
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAdmin)) {
if (!isAdmin()) {
next({ path: '/login' }); // redirect to login page if not authorized
} else {
next();
}
} else {
next();
}
});
This is my router's list that of the frontend endpoints:
{
path: '/',
component: import('./components/MainPage.vue'),
},
{
path: '/home',
component: () => import('./components/MainPage.vue'),
},
{
path: '/login',
component: () => import('./components/LoginPage.vue'),
},
{
path: '/admin',
component: () => import('./components/AdminPanel.vue')
},
{
path: '/admin_proxy',
component: () => import('./components/AdminAuthPopup.vue')
},
{
path: '/user',
component: () => import('./models/User.vue')
},
{
path: '/users',
component: () => import('./components/UsersPage.vue')
},
{
path: '/signup',
component: () => import('./components/SignUpPage.vue'),
},
{
path: '/admin/all_courses',
component: () => import('./components/AllCourses.vue'),
},
{
path: '/admin/all_students',
component: () => import('./components/AllStudents.vue'),
},
{
path: '/teacher/release_assignment',
component: () => import('./components/ReleaseAssignment.vue'),
},
{
path: '/course_overview',
component: () => import('./components/CourseOverview.vue'),
},
{
path: '/profile',
component: () => import('./components/ProfilePage.vue'),
},
{
path: '/admin/assignment_types',
component: () => import('./models/Assignment.vue')
},
{
path: '/menu',
component: () => import('./components/SideBarMenu.vue'),
},
{
path: '/admin/add_groups',
component: () => import('./components/AddGroup.vue'),
meta: { requiresAdmin: true } // add meta field to mark the route as requiring admin privileges
},
{
path: '/admin/add_student',
component: () => import('./components/AddStudentsPage.vue'),
meta: { requiresAdmin: true } // add meta field to mark the route as requiring admin privileges
},
{
path: '/admin/skill_types',
component: () => import('./components/SkillTypesConfigPage.vue'),
meta: { requiresAdmin: true } // add meta field to mark the route as requiring admin privileges
},
{
path: '/admin/assignment_progress',
component: () => import('./components/AssignmentsProgress.vue'),
meta: { requiresAdmin: true } // add meta field to mark the route as requiring admin privileges
},
{
path: '/teachers',
component: () => import('./components/TeachersPage.vue')
},
{
path: '/admin/negotiations',
component: () => import('./components/NegotiationsPage.vue'),
meta: { requiresAdmin: true } // add meta field to mark the route as requiring admin privileges
},
{
path: '/admin/schedule_config',
component: () => import('./components/StudentScheduleConfigPage.vue'),
meta: { requiresAdmin: true } // add meta field to mark the route as requiring admin privileges
},
{
path: '/admin/ll_students',
component: () => import('./components/AllStudents.vue'),
meta: { requiresAdmin: true } // add meta field to mark the route as requiring admin privileges
},
]
It is the meta: { requiresAdmin: true }
that does the trick, by double-checking who the user is. So, if I am not authenticated as an admin, the request is forwarded to the login page.
To do so, I firstly created a configuration to record the blacklisted and the whitelisted IP addresses:
export const ipFilterConfig = {
whitelist: ['127.0.0.1', '::1'], // example whitelist, replace with your own list
mode: 'allow'
};
export class allowedIps {
static includes(ipAddress: any) {
return false;
}
}
This list shall be iterated through by the same meta guards of the router when checking the request origin and block IP addresses that should not be allowed through.
I created a component that keeps track of these requests:
<template>
<div>
<h2>Total Requests</h2>
<div>{{ totalRequests }}</div>
</div>
</template>
<script>
export default {
name: 'TotalRequests',
data() {
return {
totalRequests: 0,
}
},
created() {
// make an API call to get the total number of requests
// replace the API endpoint with your own
axios.get('/api/requests/total')
.then(response => {
this.totalRequests = response.data;
})
.catch(error => {
console.error(error);
});
},
};
</script>
The requests' total shall be saved in the database and the value shall be reset everyday.