Skip to content

Commit

Permalink
add registerAdmin, deleteUsers and retrieveAllUsers final logics | al…
Browse files Browse the repository at this point in the history
…l with specs and HTML test b00tc4mp#361
  • Loading branch information
abelpriem committed Mar 21, 2024
1 parent 6030b4d commit b454338
Show file tree
Hide file tree
Showing 15 changed files with 244 additions and 15 deletions.
Binary file not shown.
Binary file removed staff/abel-prieto/PROYECT/API/downloads/robin.jpg
Binary file not shown.
41 changes: 41 additions & 0 deletions staff/abel-prieto/PROYECT/API/handlers/deleteUsersHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import jwt from 'jsonwebtoken'
import deleteUsers from '../logic/deleteUsers.js'
import { errors } from 'com'

const { JsonWebTokenError } = jwt
const { NotFoundError, AuthorizationError, TokenError, ContentError } = errors


export default async (req, res) => {
const token = req.headers.authorization.substring(7)
const { sub: userId } = jwt.verify(token, process.env.JWT_SECRET)

const { userToDelete } = req.params

try {
await deleteUsers(userId, userToDelete)
res.status(201).send()

} catch (error) {
let status = 500

if (error instanceof NotFoundError) {
status = 404
}

if (error instanceof ContentError || error instanceof TypeError) {
status = 406
}

if (error instanceof AuthorizationError) {
status = 409
}

if (error instanceof JsonWebTokenError) {
status = 401
error = new TokenError(error.message)
}

res.status(status).json({ error: error.constructor.name, message: error.message })
}
}
10 changes: 9 additions & 1 deletion staff/abel-prieto/PROYECT/API/handlers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import uploadFileHandler from './uploadFileHandler.js'
import downloadFileHandler from './downloadFileHandler.js'
import deleteFileHandler from './deleteFileHandler.js'

import retrieveAllUsersHandler from './retrieveAllUsersHandler.js'
import deleteUsersHandler from './deleteUsersHandler.js'
import registerAdminHandler from './registerAdminHandler.js'

export {
authenticateUserHandler,
registerUserHandler,
Expand All @@ -21,5 +25,9 @@ export {
retrieveFilesHandler,
uploadFileHandler,
downloadFileHandler,
deleteFileHandler
deleteFileHandler,

retrieveAllUsersHandler,
deleteUsersHandler,
registerAdminHandler
}
40 changes: 40 additions & 0 deletions staff/abel-prieto/PROYECT/API/handlers/registerAdminHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import jwt from 'jsonwebtoken'
import registerAdmin from '../logic/registerAdmin.js'
import { errors } from 'com'

const { JsonWebTokenError } = jwt
const { TokenError, ContentError, NotFoundError, AuthorizationError } = errors

export default async (req, res) => {
const token = req.headers.authorization.substring(7)
const { sub: userId } = jwt.verify(token, process.env.JWT_SECRET)

const { username, email, password } = req.body

try {
await registerAdmin(userId, username, email, password)
res.status(200).send()

} catch (error) {
let status = 500

if (error instanceof AuthorizationError) {
error = 401
}

if (error instanceof NotFoundError) {
status = 404
}

if (error instanceof ContentError || error instanceof TypeError) {
status = 406
}

if (error instanceof JsonWebTokenError) {
status = 409
error = new TokenError(error.message)
}

res.status(status).json({ error: error.constructor.name, message: error.message })
}
}
39 changes: 39 additions & 0 deletions staff/abel-prieto/PROYECT/API/handlers/retrieveAllUsersHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import jwt from 'jsonwebtoken'
import retrieveAllUsers from '../logic/retrieveAllUsers.js'
import { errors } from 'com'

const { JsonWebTokenError } = jwt
const { NotFoundError, AuthorizationError, TokenError, ContentError } = errors


export default async (req, res) => {
const token = req.headers.authorization.substring(7)
const { sub: userId } = jwt.verify(token, process.env.JWT_SECRET)

try {
const allUsers = await retrieveAllUsers(userId)
res.json(allUsers)

} catch (error) {
let status = 500

if (error instanceof NotFoundError) {
status = 404
}

if (error instanceof ContentError || error instanceof TypeError) {
status = 406
}

if (error instanceof AuthorizationError) {
status = 409
}

if (error instanceof JsonWebTokenError) {
status = 401
error = new TokenError(error.message)
}

res.status(status).json({ error: error.constructor.name, message: error.message })
}
}
13 changes: 10 additions & 3 deletions staff/abel-prieto/PROYECT/API/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ import {
uploadFileHandler,
downloadFileHandler,
deleteFileHandler,
retrieveFilesHandler
retrieveFilesHandler,

deleteUsersHandler,
retrieveAllUsersHandler,
registerAdminHandler
} from './handlers/index.js'

dotenv.config()
Expand Down Expand Up @@ -63,7 +67,7 @@ mongoose.connect(process.env.URL_MONGODB_HIINIT_API)
server.delete('/download/delete/:fileId', deleteFileHandler)

// REGISTER ADMIN
// server.post('/admin', registerAdminHandler)
server.post('/admin', registerAdminHandler)

// CREATE COMMANDS
// server.post('/admin/commands', createCommandHandler)
Expand All @@ -72,7 +76,10 @@ mongoose.connect(process.env.URL_MONGODB_HIINIT_API)
// server.post('/admin/groups', createGroupHandler)

// DELETE USERS
// server.delete('/users/:userId', deleteUserHandler)
server.delete('/users/delete/:userId', deleteUsersHandler)

// RETRIEVE ALL USERS
server.get('/users/all', retrieveAllUsersHandler)

server.listen(process.env.PORT, () => console.log(`server online! Listen on: ${process.env.PORT}`))
})
Expand Down
4 changes: 2 additions & 2 deletions staff/abel-prieto/PROYECT/API/logic/deleteUsers.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ const { SystemError, NotFoundError, AuthorizationError } = errors
// FINAL: Eliminar usuario

async function deleteUser(userId, userIdDeleted) {
validate.id(userId, 'ID User')
validate.id(userIdDeleted, 'ID Deleted user')
validate.text(userId, 'ID User')
validate.text(userIdDeleted, 'ID Deleted user')

try {
//BUSCAR ADMIN
Expand Down
19 changes: 13 additions & 6 deletions staff/abel-prieto/PROYECT/API/logic/registerAdmin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,32 @@ import { User, Group } from '../data/models.js'
import { validate, errors } from 'com'
const { SystemError, NotFoundError, AuthorizationError } = errors

async function registerAdmin(userId) {
validate.id(userId)
async function registerAdmin(userId, username, email, password) {
validate.id(userId, 'ID Admin')
validate.text(username, 'New ADMIN username')
validate.email(email, 'New ADMIN email')
validate.password(password, 'New ADMIN password')

try {
const user = await User.findById(userId)
const requestAdmin = await User.findById(userId).lean()

if (!user)
if (!requestAdmin)
throw new NotFoundError('User not found')

if (user.role[0] !== 'admin')
if (requestAdmin.role[0] !== 'admin')
throw new AuthorizationError('Authorization denied. Only ADMIN mode')

const admin = await User.create({ username: user.username, email: user.email, password: user.password, group: 'root', role: 'admin' })
const admin = await User.create({ username: username, email: email, password: password, group: 'root', role: 'admin' })
const group = await Group.findOne({ name: 'root' });

group.members.push(admin._id)
await group.save()

} catch (error) {
if (error instanceof NotFoundError || error instanceof AuthorizationError) {
throw error
}

throw new SystemError(error.message)
}
}
Expand Down
9 changes: 7 additions & 2 deletions staff/abel-prieto/PROYECT/API/logic/retrieveAllUsers.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@ async function retrieveAllUsers(userId) {
}

if (admin.role[0] === 'admin') {
const users = await User.find().distinct('username')
const users = await User.find({ 'role': { $ne: 'admin' } }).lean()

return users
const usersArray = users.map(user => ({
id: user._id.toString(),
username: user.username
}))

return usersArray
} else {
throw new AuthorizationError('Authorization denied. Only ADMIN user')
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
}
}

fetch('http://localhost:9001/users/65e8e1a8f2e29243b05b5961', req)
fetch('http://localhost:9001/delete/users/65e8e1a8f2e29243b05b5961', req)
.catch(error => console.error(error))
.then(res => {
if (res.ok) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<script>
const req = {
method: 'GET',
headers: {
Authorization: 'Bearer 65e8c15ef35504a2bcecf912'
}
}

fetch('http://localhost:9001/users/all', req)
.catch(error => console.error(error))
.then(res => {
if (res.ok) {
res.json()
.catch(error => console.error(error))
.then(body => console.log(res.status, body))
} else {
console.error(res.status)
}
})
</script>
62 changes: 62 additions & 0 deletions staff/abel-prieto/PROYECT/API/test/retrieveAllUsers.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import mongoose from 'mongoose'
import random from './helpers/random.js'
import dotenv from 'dotenv'
import retrieveAllUsers from '../logic/retrieveAllUsers.js'
import { User } from '../data/models.js'
import { expect } from 'chai'
import { errors } from 'com'
const { NotFoundError, AuthorizationError } = errors

dotenv.config()

describe('retrieveAllUsers', () => {
before(() => mongoose.connect(process.env.URL_MONGODB_TEST))

beforeEach(() => User.deleteMany())

// POSITIVE CASE
it('success with retrieve ALL users', async () => {
const admin = await User.create({ username: random.username(), email: random.email(), password: random.password(), group: 'root', role: 'admin' })

const user1 = await User.create({ username: random.username(), email: random.email(), password: random.password(), group: 'localhost', role: 'user' })
const user2 = await User.create({ username: random.username(), email: random.email(), password: random.password(), group: 'localhost', role: 'user' })
const user3 = await User.create({ username: random.username(), email: random.email(), password: random.password(), group: 'localhost', role: 'user' })
const user4 = await User.create({ username: random.username(), email: random.email(), password: random.password(), group: 'localhost', role: 'user' })

const allUsers = await retrieveAllUsers(admin.id)

expect(allUsers).to.be.an('Array').that.has.lengthOf(4)
expect(allUsers).to.includes(user1.username)
expect(allUsers).to.includes(user2.username)
expect(allUsers).to.includes(user3.username)
expect(allUsers).to.includes(user4.username)
})

// NEGATIVE CASE - Admin not found
it('fails on admin not found', async () => {
const userRequest = random.id()

try {
await retrieveAllUsers(userRequest)
throw new Error('should not reach this point!')
} catch (error) {
expect(error).to.be.instanceOf(NotFoundError)
expect(error.message).to.be.equal('Admin not found. Try again')
}
})

// NEGATIVE CASE - Authorization denied
it('fails on admin not found', async () => {
const userRequest = await User.create({ username: random.username(), email: random.email(), password: random.password(), group: 'localhost', role: 'user' })

try {
await retrieveAllUsers(userRequest.id)
throw new Error('should not reach this point!')
} catch (error) {
expect(error).to.be.instanceOf(AuthorizationError)
expect(error.message).to.be.equal('Authorization denied. Only ADMIN user')
}
})

after(() => mongoose.disconnect())
})
Binary file not shown.
Binary file not shown.

0 comments on commit b454338

Please sign in to comment.