Skip to content

Commit

Permalink
ft(backend): creates user
Browse files Browse the repository at this point in the history
- god can create a user
- god can update a user
- god can get a user

[Finishes #167190460]
  • Loading branch information
Lundii committed Aug 15, 2019
1 parent 49adbf4 commit 1327913
Show file tree
Hide file tree
Showing 12 changed files with 1,406 additions and 641 deletions.
3 changes: 3 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ PUSHER_APP_ID=YOUR_APP_ID
PUSHER_APP_KEY=YOUR_APP_KEY
PUSHER_APP_SECRET=YOUR_APP_SECRET
PUSHER_APP_CLUSTER=YOUR_APP_CLUSTER
NEW_USER_PASSWORD=default password of a new user
FACEBOOK_SDK = 'string'
TWITTER_SDK = 'string'
112 changes: 111 additions & 1 deletion server/controllers/adminController.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import sequelize from 'sequelize';
import models from '../db/models';
import helpers from '../helpers';

const { errorStat, successStat } = helpers;

const {
errorStat, successStat, hashPassword, generateToken, Mail
} = helpers;

const { Op } = sequelize;
const { User } = models;

/**
* @Module AdminController
* @description Controls all Admin based activity
Expand Down Expand Up @@ -134,6 +142,108 @@ class AdminController {

return successStat(res, 200, 'data', foundUser);
}

/**
* @static
* @description Allows a super-admin to create new user
* @param {Object} req - Request object
* @param {Object} res - Response object
* @returns {Object} object containing user data and access Token
* @memberof AdminController
*/
static async createUser(req, res) {
const {
firstname, lastname, email, username
} = req.body.user;
const userRole = req.body.user.role;
const { role } = req.user;
if (role !== 'god') return errorStat(res, 401, 'You cannot perform this action. Please contact a god');
const password = process.env.NEW_USER_PASSWORD;
const existingUser = await models.User.findOne({
where: {
[Op.or]: [{ email }]
}
});
if (existingUser) {
return errorStat(res, 409, 'User Already Exists');
}
const newUser = { ...req.body.user, password: hashPassword(password), verified: false };
const user = await models.User.create(newUser);
const token = generateToken({ id: user.id, email });

const mail = new Mail({
to: user.email,
subject: "Welcome to Authors' Haven",
messageHeader: `Hi, ${user.firstname}!`,
messageBody: `You have being added a/an ${userRole}, your username is ${username} and password ${password}
please, click on the link below to verify your email and change your password as soon as possible`,
iButton: true
});
mail.InitButton({
text: 'Verify Email',
link: `${process.env.APP_URL}/api/v1/users/confirmEmail?token=${token}&id=${user.id}`,
});
mail.sendMail();
return successStat(res, 201, 'user', {
id: user.id,
token,
firstname,
lastname,
username,
email,
role: userRole,
isActive: user.isActive
});
}

/**
* @static
* @description Allows a super-admin to update new user
* @param {Object} req - Request object
* @param {Object} res - Response object
* @returns {Object} object containing user data and access Token
* @memberof AdminController
*/
static async updateUser(req, res) {
const { id } = req.params;
const { role } = req.user;
if (role !== 'god') return errorStat(res, 401, 'You cannot perform this action. Please contact a god');
await User.update(req.body.user, { where: { id }, returning: true });
const user = await User.findOne({ where: { id } });
return successStat(res, 201, 'user', {
id: user.id,
firstname: user.firstname,
lastname: user.lastname,
username: user.username,
email: user.email,
role: user.role,
isActive: user.isActive
});
}

/**
* @static
* @description Allows a super-admin to update new user
* @param {Object} req - Request object
* @param {Object} res - Response object
* @returns {Object} object containing user data and access Token
* @memberof AdminController
*/
static async getUser(req, res) {
const { id } = req.params;
const { role } = req.user;
if (role !== 'god') return errorStat(res, 401, 'You cannot perform this action. Please contact a god');
const user = await User.findOne({ where: { id } });
return successStat(res, 200, 'user', {
id: user.id,
firstname: user.firstname,
lastname: user.lastname,
username: user.username,
email: user.email,
role: user.role,
isActive: user.isActive
});
}
}

export default AdminController;
10 changes: 6 additions & 4 deletions server/controllers/articleController.js
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,9 @@ class ArticleController {
*/
static async createTag(req, res) {
const { tagName, description } = req.body;
const tag = await Tags.findOrCreate({ where: { name: tagName }, defaults: { description } });
const existingTag = await Tags.findOne({ where: { name: tagName } });
if (existingTag) return errorStat(res, 409, 'Tag already exits');
const tag = await Tags.create({ name: tagName, description });
return successStat(res, 200, 'tag', tag);
}

Expand All @@ -350,9 +352,9 @@ class ArticleController {
*/
static async createCategory(req, res) {
const { categoryName, description } = req.body;
const category = await Categories.findOrCreate({
where: { name: categoryName }, defaults: { description }
});
const existingCategory = await Categories.findOne({ where: { name: categoryName } });
if (existingCategory) return errorStat(res, 409, 'Category already exits');
const category = await Categories.create({ name: categoryName, description });
return successStat(res, 200, 'category', category);
}

Expand Down
14 changes: 14 additions & 0 deletions server/db/seeders/20190731122700-demo-user.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,20 @@ module.exports = {
updatedAt: new Date(),
role: 'god'
},
{
firstname: 'updatefirstname',
lastname: 'updatelastname',
username: 'updateusername',
email: 'new.update@andela.com',
password: '$2a$06$loVt9DxXF97PGJxkjyfJj.PVHNz5FUjNhU4yXIzTK4HQ2EesmuoPi',
image: null,
bio: null,
newPostEmailSub: false,
isActive: true,
createdAt: new Date(),
updatedAt: new Date(),
role: 'user'
}
]),
down: queryInterface => queryInterface.dropAllTables()
};
127 changes: 127 additions & 0 deletions server/docs/ah-commando-doc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ tags:
description: Operations related to User's profile
- name: Articles
description: Operations about the Articles
- name: god
description: god base role

paths:
/:
Expand Down Expand Up @@ -1719,6 +1721,131 @@ paths:
description: successfully view a single user found by username
'401':
description: Unauthorized
/admin/user:
put:
tags:
- god
security:
- bearerAuth: []
summary: god creates a new user
requestBody:
content:
application/json:
schema:
type: object
properties:
firstname:
type: string
lastname:
type: string
username:
username: string
email:
username: string
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: "#/components/schemas/successResponse"
'400':
description: validation error
content:
application/json:
schema:
$ref: "#/components/schemas/errorResponse"
'401':
description: Authorization error
content:
application/json:
schema:
$ref: "#/components/schemas/errorResponse"
'500':
description: Server error
content:
application/json:
schema:
$ref: "#/components/schemas/errorResponse"
/admin/user/{id}:
get:
tags:
- god
security:
- bearerAuth: []
summary: god gets a user
parameters:
- in: path
name: id
schema:
type: integer
required: true
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: "#/components/schemas/successResponse"
'400':
description: validation error
content:
application/json:
schema:
$ref: "#/components/schemas/errorResponse"
'401':
description: Authorization error
content:
application/json:
schema:
$ref: "#/components/schemas/errorResponse"
'500':
description: Server error
content:
application/json:
schema:
$ref: "#/components/schemas/errorResponse"
patch:
tags:
- god
security:
- bearerAuth: []
summary: god updates a user
parameters:
- in: path
name: id
schema:
type: integer
required: true
requestBody:
content:
application/json:
schema:
type: object
properties:
firstname:
type: string
lastname:
type: string
username:
username: string
email:
username: string
responses:
'201':
description: Success
content:
application/json:
schema:
$ref: "#/components/schemas/successResponse"
'400':
description: validation error
content:
application/json:
schema:
$ref: "#/components/schemas/errorResponse"
'401':
description: Authorization error
content:
application/json:
schema:
Expand Down
10 changes: 8 additions & 2 deletions server/middlewares/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const {
const {
validateLogin,
validateUser,
validateNewUser,
validateArticle,
validateProfileUpdate,
validatePasswordReset,
Expand All @@ -21,14 +22,17 @@ const {
validateHighlightData,
validateGetHighlight,
validateRoleInput,
validateParamsInput
validateParamsInput,
validateUpdateUser,
validateGetUser
} = InputValidator;

export default {
multerUploads,
verifyToken,
validateLogin,
validateUser,
validateNewUser,
validateProfileUpdate,
validateArticle,
validatePasswordReset,
Expand All @@ -45,5 +49,7 @@ export default {
validateGetHighlight,
isActive,
validateRoleInput,
validateParamsInput
validateParamsInput,
validateUpdateUser,
validateGetUser
};
Loading

0 comments on commit 1327913

Please sign in to comment.