Skip to content

Commit

Permalink
add a new admin user or grant an existing user admin privilege
Browse files Browse the repository at this point in the history
  • Loading branch information
qiandrewj committed May 5, 2024
1 parent 59949ca commit 2f27fa3
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 11 deletions.
1 change: 0 additions & 1 deletion client/src/modules/Admin/Components/AdminUser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ type Props = {

const AdminUser = ({user, token, removeHandler}: Props) => {


return (
<div className={styles.userEntry}>
{user.firstName} {user.lastName}, {user.netId}
Expand Down
38 changes: 36 additions & 2 deletions client/src/modules/Admin/Components/ManageAdminModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ type Props = {

const ManageAdminModal = ({token, open, setOpen}: Props) => {
const [admins, setAdmins] = useState<Student[]>([])
const [netId, setNetId] = useState<string>("")

function closeModal() {
setOpen(false)
}

useEffect(() => {
axios
Expand Down Expand Up @@ -44,8 +49,21 @@ const ManageAdminModal = ({token, open, setOpen}: Props) => {
}).catch((e) => console.log(`Unable to remove admin ${e}`))
}

function closeModal() {
setOpen(false)
function addAdminByNetId(_netId: string) {
axios
.post('/api/grantAdmin', {
userId: _netId,
token: token
})
.then((response) => {
if (response.status === 200) {
console.log(`Successfully gave admin privilege to ${_netId}`)
}
}).catch((e) => console.log(`Unable to remove admin ${e}`))
}

function onTextChange(newText: string) {
setNetId(newText)
}

if (!open) {
Expand All @@ -62,6 +80,22 @@ const ManageAdminModal = ({token, open, setOpen}: Props) => {
src={closeIcon}
alt="close-modal"
/>
<div className={styles.addAdmin}>
<input
className={styles.textInputBox}
value={netId}
onChange={(e) => onTextChange(e.target.value)}
name="new-admin"
id="new-admin"
placeholder="User net-id"
></input>
<button
className = {styles.addAdminButton}
onClick={() => addAdminByNetId(netId)}
>Add administrator</button>
</div>
<br>
</br>
{admins.map((admin) => {
return (
<AdminUser
Expand Down
9 changes: 4 additions & 5 deletions client/src/modules/Admin/Styles/AdminUser.module.css
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
.userEntry {
padding: 1px;
margin: 1px;
margin: 2px;
display: flex;
border-bottom: 1px solid #ccc;
}

.removeButton {
background-color: var(--clr-red-200);
color: var(--clr-white);
color: var(--clr-black);
font-size: var(--font-small-size);
border-radius: 5px;
margin-left: auto;
padding: 5px 3px;
padding: 2px 3px;
cursor: pointer;
}
}
22 changes: 22 additions & 0 deletions client/src/modules/Admin/Styles/ManageAdminModal.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,26 @@
position: absolute;
top: 32px;
right: 32px;
}

.addAdmin {
display: flex;
padding: 2px;
border-bottom: 2px solid #ccc;
}

.addAdminButton {
background-color: var(--clr-blue-300);
color: var(--clr-white);
font-size: var(--font-small-size);
border-radius: 5px;
margin-left: auto;
padding: 3px 7px;
cursor: pointer;
}

.textInputBox {
border-radius: 10px;
border: 0.5px solid #65acff;
padding: 3px 7px;
}
24 changes: 22 additions & 2 deletions server/src/admin/admin.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
createCourseCSV,
findAdminUsers,
removeAdminPrivilege,
grantAdminPrivilege
grantAdminPrivilege,
createNewAdminUser,
} from './admin.data-access';
import {
AdminAddSemesterType,
Expand Down Expand Up @@ -209,7 +210,7 @@ export const getAdminUsers = async ({ auth }: VerifyAdminType) => {
* database because they are retrieved into the ManageAdminModal
*
* @param {Auth} auth: Object that represents the authentication of a request being passed in.
* @param {string} id: String identifying the user in the
* @param {string} id: String identifying the user in the database
* @returns all admin users if operation was successful, null otherwise
*/
export const removeAdmin = async ({auth, id}: VerifyManageAdminType) => {
Expand All @@ -220,6 +221,25 @@ export const removeAdmin = async ({auth, id}: VerifyManageAdminType) => {
}
}

/**
* Grants a user admin privilege by updating them if they are in the database.
* If the user is not in the database, creates a new user with their netid and admin privilege
*
* @param {Auth} auth: Object that represents the authentication of a request being passed in.
* @param {string} id: String identifying the user by netid
* @returns The user with updated admin privilege if operation was successful, null otherwise
*/
export const addOrUpdateAdmin = async ({auth, id}: VerifyManageAdminType) => {
const userIsAdmin = await verifyTokenAdmin({ auth });
if (userIsAdmin) {
let res = await grantAdminPrivilege(id);
if (res.nModified === 0) {
res = await createNewAdminUser(id);
}
return res;
}
}

/**
* Updated all professors in the database by scraping through the Cornell course API.
*
Expand Down
23 changes: 22 additions & 1 deletion server/src/admin/admin.data-access.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import { Classes, ReviewDocument, Reviews, Students } from '../../db/schema';
import { UpdateCourseMetrics } from './admin.type';
import { findCourseById } from '../course/course.data-access';
import { InsertStudentType } from '../auth/auth.type';
import shortid from 'shortid';

export const findStudentById = async (id: string) => {
const student = await Students.findOne({ _id: id }).exec();
Expand Down Expand Up @@ -125,6 +127,25 @@ export const removeAdminPrivilege = async (id: string) => {
}

export const grantAdminPrivilege = async (id: string) => {
const res = await Students.updateOne({ _id: id }, { $set: {privilege: 'admin'} }).exec()
console.log('grant privilege')
const res = await Students.updateOne({ netId: id }, { $set: {privilege: "admin"} }).exec()
return res
}

export const createNewAdminUser = async (id: string) => {

const admin: InsertStudentType = {
_id: shortid.generate(),
firstName: '',
lastName: '',
netId: id,
affiliation: '',
token: '',
privilege: 'admin',
};

const newAdmin = new Students(admin);
const res = await newAdmin.save();

return res
}
22 changes: 22 additions & 0 deletions server/src/admin/admin.router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
reportReview,
getAdminUsers,
removeAdmin,
addOrUpdateAdmin,
} from './admin.controller';

export const adminRouter = express.Router();
Expand Down Expand Up @@ -221,6 +222,27 @@ adminRouter.post('/removeAdmin', async (req, res) => {
}
})

adminRouter.post('/grantAdmin', async (req, res) => {
const {token, userId}: AdminUserRequestType = req.body;

try {
const auth = new Auth({ token });
const result = await addOrUpdateAdmin({ auth: auth, id: userId})

if (result) {
return res.status(200).json({
message: `Granted admin privilege to user with id ${userId}`
});
}

return res.status(400).json({
error: 'User is not an admin.'
})
} catch (err) {
return res.status(500).json({ error: `Internal Server Error: ${err}`})
}
})

adminRouter.post('/addNewSemester', async (req, res) => {
const { semester, token }: AdminAddSemesterRequestType = req.body;
try {
Expand Down

0 comments on commit 2f27fa3

Please sign in to comment.