You are on page 1of 73

api-user 17/07/2018

────────────────────────────────────

MASTROMONACO Julien
RainbowBash
42 rue des Arcs-en-ciel
42000 Web Internet (near the mid’ clouds �)

This document is an alpha version, it can be updated at any time.


1

Overview

The project is to build an API-REST distributing or receiving user data. This will be responsible
for managing users, different roles, access, and more.

All the basics functions that one could imagine will be made in order to be able to
accommodate changes quickly and cleanly. But, the maleability of the application will allow the
deactivation of lot of "components" without altering the health of the application.

It must be possible to maintain performance constantly, the dispersion of loads on different


servers with monitoring (ELK) is really accurate and should allow the application to respond
very quickly. In the event of server or application failures, redundancy must take over.

Objectives

1. API progressive & Flexible

2. API Scalable

3. API performing 800ms max/request (out of jobs & SSR)

4. Code Quality > 90%

Links
● Trello (https://trello.com/b/sT3QTBc3/user-api)

● Github (https://github.com/JuMastro/user-api)
2

Technologies

Prod

● Ts / Nodejs + Express Framework


● Redis
● PostgresSQL + TypeORM
● MongoDB + Mongoose
● ELK Stack (Elasticsearch, Logstash, Kibana)
● SocketIO (for real-time)

Dev

● Mocha & Chai (Tests)


● Eslint (Linter)
● Jsdoc (Doc generator)
● Supervisor (Restart server on updates or errors)
● Webpack (HTML from PUG)

More

● Docker
● Npm
● TravisCI (v2)

Requirements

● Docker >= 17.0.0


● NodeJS >= 10.0.0
● Npm >= 6.0.0
3

Architecture

Requests workflow
4

Stories

Users

First stage

● Registration ● Profile update


● Registration confirmation ● Email update
● Resend registration confirmation ● Email update confirmation
● Login ● Password update
● Password forgot ● Get my public tokens
● Password reset ● Create public token
● Get profile data ● Delete public token
● Username update

Second stage

● Disable account ● Get own data

Administrators

First stage
5

● Add roles ● Update an individual user


● Remove roles ● Update users by selecting
● Get users list (small dataset) ● Have filters for users list
● Get individual user data ● Create account

Second stage

● Disable accounts ● Get user data set


● Delete accounts ● Get anonymous user data set
● Get disabled users ● Get statistics for each use case of
● Send a newsletter application
● Add group ● Get monitoring
● Remove group ● Reset user public_key
● Update group ● Add user public_token
● Add user to group ● Remove user public_token
● Remove user to group ● Ban user or ip
● Get banned users
● Get banned ip
6

Developers

First stage

● Structured app tree ● Translation module


● Docker configurations ● PUG to HTML script
● Globals configurations ● Response (external)
● Server running ● ErrorClass response (internal)
● Load balancer app ● SQL (entities schemas abstracts)
● Middleware body-parser ● noSQL (entities schemas abstracts)
● Middleware requestHandler ● SQL Repository
● Middleware ip-access ● noSQL Repository
● Middleware (auth) user-access ● Fixtures SQL
● Define roles hierarchy ● Fixtures NoSQL
● Abstract Controller ● SQL expected errors handler
● Routing module ● Mailer module using nodemailer
● Public keys generator ● Hasher module using Argon2i
● Tokens generator ● JsonWebToken provider module
● Identifiant key generator (uuid) ● Data validator module (recipe-
● Data formatter & anonymizer consumer, izitjs rewriting)

Second stage

● ELK Stack dockerized ● Redis dockerized


● Elasticsearch config & module ● Redis Cluster Adapter
● Logstash config & module ● Client tracker
● Kibana config & module
7

SQL schemas definitions

SQL Input data validations


8

username length(3, 16), alphanumeric + -_&+(space)

email regex(email)

password length(8, 64)

Norms
Naming Conventions

variables camelCase var infoUser = {}


functions infoUser.js
function files

constants camelCase const infoUser = {}


UPPER_SNAKE_CASE const INFO_USER = {}

class CapitalizedCamelCase class InfoUser {}


class files InfoUser.js

module files camelCase infoUser.js


kebak-case info-user.js

For more norms, follow the linter configuration.


9

Specs
Errors
If an error is detected there are two possible cases, first if the error is an expected error then
the route will return the error object with error code 400 (Bad request).In the second case, the
one where the error is not an expected error, the route will console.log the error and return an
error code 500 (Internal error).

Routes

POST PUBLIC /registration Register an user

GET PUBLIC /registration/{token} Confirm an user registration

POST PUBLIC /registration-confirmation-reset/{token} Resend an user registration confirmation

POST PUBLIC /login Log to an account

POST PUBLIC /password-forgot Send a recovery password email

POST PUBLIC /password-reset Redefine a password

GET User /account/profile See current logged account profile

POST User /account/profile Update user profile

POST User /account/username Update username

POST User /account/email Update email

GET User /account/email-confirmation Confirm new email

POST User /account/password Update password

GET User /account/tokens Get current user tokens

POST User /account/tokens Create new token

GET User /account/tokens/delete/{tokenId} Delete user token

GET User /account/disable Disable user account

GET User /account/disable/{token} Disable account confirmation

GET User /account/get-my-data Get current user dataset


10

POST Admin /admin/roles/add Add roles to an user

POST Admin /admin/roles/delete Delete roles to an user

GET Admin /admin/users/{userId} Get user data

GET Admin /admin/users Get users data list

POST Admin /admin/users/{userId} Update an user

POST Admin /admin/users Update an users list

POST Admin /admin/users/create Create an user

POST Admin /admin/users/disable Disable an users list

POST Admin /admin/users/delete Delete an users list

GET Admin /admin/users/is-disabled Get disabled users

POST Admin /admin/newsletter Send a newsletter

GET Admin /admin/users/{userId}/reset-public-key Reset an user public key

POST Admin /admin/users/public-token Create an user public token

GET Admin /admin/users/public-token/{tokenId}/delete Remove an user public token

POST Admin /admin/users/ban Ban an user

POST Admin /admin/ip/ban Ban an ip

GET Admin /admin/users/banned Get banned users

GET Admin /admin/ip/banned Get banned ip

GET Admin /admin/users/{userId}/dataset Download an user dataset

GET Admin /admin/users/{userId}/dataset?anonymous=true Download anonymized user dataset

POST Admin /admin/groups Create a group

GET Admin /admin/groups/{groupId}/delete Delete a group

POST Admin /admin/groups/{groupId} Update a group

GET Admin /admin/groups Get list of groups

POST Admin /admin/groups/add-user Add an user to a group


11
12

Developers

Routes

No developper route needed...

Modules

I. Structured app tree


0H
NO_REQUIREMENT

● Create application tree


○ etc
■ docker
■ scripts
○ src
■ controllers
■ db
● sql
○ entities
○ models
● nosql
○ entities
○ models
■ modules
■ recipes
■ routes
■ templates
■ translations
● lang
○ FR_fr
○ EN_us
○ static
○ test
■ specs
13

II. Docker configurations


2H
NO_REQUIREMENT
● Create/Pull postgres image
● Create/Pull mysql image
● Create/Pull nodeJS image
● Configure .env files
● Create docker-compose
● Create commons scripts to run services

III. Globals configurations


3H
NO_REQUIREMENT
● Create tooling configuration
○ Git
○ Npm
○ Eslint
○ Jsdoc
○ Mocha/Chai
○ Webpack
○ README
○ LICENCE
○ (TravisCI)

IV. Server running


1H
NO_REQUIREMENT
● Make express server running on defined configuration port
● Make tests
14

V. Load balancer
4H
NO_REQUIREMENT
● Make express load-balancer app
● Make tests

WORKFLOW:

App instance
Select the laziest
server
REQUEST Load
App instance
Balancer

App instance

VI. Middleware body-parse


30Min
NO_REQUIREMENT

● Make body-parser middleware module


● Plug middleware module to app

WORKFLOW:

Express app
MIDDLEWARES
REQUEST body- ...next RESPONSE
parser (routes)

Works with
request to get
friendly js/json
objects.
15

VII. Middleware ip-access


2H
NO_REQUIREMENT
● Make ip-access middleware module
● Plug middleware module to app
● Make tests

WORKFLOW:

Express app
MIDDLEWARES
REQUEST ...next RESPONSE
ip_access
(routes)

Check if client ip
is blocked.

VIII. Middleware user-access


2H
NO_REQUIREMENT

● Make ip-access middleware module


● Plug middleware module to app
● Make tests

WORKFLOW:

Express app
MIDDLEWARES
REQUEST user_acce ...next RESPONSE
ss (routes)

Check if client is
authenticated
and he’s
allowed
16

IX. Define roles hierarchy


4H
NO_REQUIREMENT
● Defines roles
● Make roles-hierarchy module to select roles level
● Make tests

X. Abstract Controller
1H
NO_REQUIREMENT

● Write an abstract controller with differents “commons methods & modules”

XI. Routing module


1H
NO_REQUIREMENT

● Make a dynamic module to works as provider to register application routes

XII. Public_keys generator


2H
NO_REQUIREMENT

● Make public keys generator


● Make tests

XIII. Tokens generator


2H
NO_REQUIREMENT

● Make tokens generator


● Make tests
17

XIV. Identifiant generator (uuid)


1H
NO_REQUIREMENT

● Implement uuid library to generate unique identifiant

XV. Data formatter & anonymizer


4H
NO_REQUIREMENT

● Make module to get dataset of user


● Make module to get anonymized dataset of user
● Makes tests

XVI. Translation module


6H
NO_REQUIREMENT

● Find more information about the existence of translation module with node
● Make translation configuration
● Make translation module
● Make tests

XVII. Pug to Html script


2H
NO_REQUIREMENT
● Make webpack script to transform pug files to html (emails)
18

XVIII. Response external


1H
NO_REQUIREMENT
● Make a module function to normalize external response
● Make tests

XIX. Response class internal errors


3H
NO_REQUIREMENT
● Make complete module to handle expected errors
● Implement him as class module
● Make tests

XX. SQL entities, schemas, abstract


4H
NO_REQUIREMENT
● Make abstract model
● Make sql entities
● Make sql models

XXI. NoSQL entities, schemas, abstract


2H
NO_REQUIREMENT
● Make nosql entities
● Make nosql models

XXII. SQL repository


30Min
NO_REQUIREMENT
● Make an empty repositories for each entities
19

XXIII. NoSQL repository


30Min
NO_REQUIREMENT
● Make an empty repositories for each entities

XXIV. Fixtures SQL


3H
NO_REQUIREMENT
● Make fixtures for each sql tables

XXV. Fixtures NoSQL


3H
NO_REQUIREMENT
● Make fixtures for each nosql schemas

XXVI. SQL expected error handler


4H
NO_REQUIREMENT
● Make a module to handle SQL expected errors has :
○ Duplication
○ Invalid types
○ ect...
● Make tests

XXVII. Mailer module using nodemailer


3H
HTML_TO_PUG
● Make module to send email
○ Can send to user
○ Can send to list of users
○ Can send an attachment
○ Can send text, html or hybrid version of a message
20

XXVIII. Hasher module using Argon2i


2H
NO_REQUIREMENT
● Make module to hash users passwords using argon2i
● Find the security level of encryption of the password without affecting the functioning of
the application in perfomances
● Make hasher
● Make checker
● Make tests

XXIX. JsonWebToken Provider&Checker


2H
NO_REQUIREMENT
● Make module to read and provide JsonWebToken
● Make reader
● Make provider
● Make tests

XXX. Data validator (izitjs & recipe-consumer rewriting)


8H
NO_REQUIREMENT
● Rewrite a performing data validator as izit-js + recipe-consumer
● Need more flexibility to errors handling
● Need more flexibility to application-cases
● Need to set builded recipe from app cache
21

XXXI. Redis dockerized


3H
NO_REQUIREMENT
● Make a docker redis cluster configuration
● Run and write commands to package.json

XXXII. Redis cluster adapter


4H
NO_REQUIREMENT
● Make redis-adapter module to friendly work with him
● Get reading functions
● Get writing functions

XXXIII. ELK Dockerized stack


// Sub project, need to clear all basicals features and modules.
XXXIV. Elasticsearch config & module
// Sub project, need to clear all basicals features and modules.
XXXV. Logstash config & module
// Sub project, need to clear all basicals features and modules.
XXXVI. Kibana config & module
// Sub project, need to clear all basicals features and modules.
XXXVII. Client tracker
// Sub project, need to clear all basicals features and modules.
22

Users

Modules

No user module needed...


23

Routes

I. Registration

3-4 H
PUBLIC_KEY_GENERATOR, TOKEN_GENERATOR, EXTERNAL_ID_GENERATOR

● Create route configuration file and register it to app


● Create email registration confirmation template
● Create controller.action with WORKFLOW
● Create tests

DETAILS:

Route path /registration


Method POST: Public
Controller action name SecurityController: registration
Post data username, email, password, passwordConfirmation

WORKFLOW:
24

db.userInfo.create({
last_user_ip: *UserIP*,
last_user_ip_date: Date(now),
registration_date: Date(now)
})

db.userProfile.create({
*EMPTY*
})

db.userArchive.create({
olds_usernames: [],
olds_emails: [],
olds_public_key: [],
user_id: *UserID*
})

db.userSecurity.create({
public_key: *generated*,
account_confirmation_token: *generated*,
account_confirmation_token_limit: Date(now+1H)
})

db.user.create({
identifiant_key: *generated*,
username: validate(*input*),
email: validate(*input*),
password: hash(validate(*input*)),
roles: [‘ROLE_USER’],
groups: [],
is_active: false,
is_blocked: false,
is_disabled: false,
is_confirmed: false,
user_security_id: *UserSecurityID*,
user_profile_id: *UserProfileID*,
user_info_id: *UserInfoID*
})
25

II. Registration confirmation


2H
NO REQUIREMENT
● Create route configuration file and register it to app
● Create email registration template
● Create controller.action with WORKFLOW
● Create tests

DETAILS:

Route path /registration/{token}


Method GET: Public
Controller action name SecurityController: registrationConfirmation
Get data token

WORKFLOW:

Clien API
t client.get (token)

ERROR: Invalid token


Check existing token
and validity

Database update

Send account confirmation


Return valid response email

db.userInfo.update({
registration_confirmation_date: Date(now)
})
db.user.update({
is_active: true,
is_confirmed: true
})
db.userSecurity.update({
account_confirmation_token: null,
account_confirmation_token_limit: null
})
26

III. Resend confirmation registration

2H
TOKEN_GENERATOR
● Create route configuration file and register it to app
● Create controller.action with WORKFLOW
● Create tests

DETAILS:

Route path /registration-confirmation-reset/{token}


Method POST: Public
Controller action name SecurityController: resendAccountConfirmaton
Post data email

WORKFLOW:

Clien API
t client.post (email)

ERROR: Invalid email


(if account don’t wait confirmation or don’t
exist) Check if the email provided match
to an account with a exceeded
validation

Generate new token

Database update

Send email
Return valid response (account confirmation)

db.userSecurity.update({
account_confirmation_token: *generated*,
account_confirmation_token_limit: Date(now + 1H)
})
27

IV. Login

3H
HASHER, JWT_ADAPTER

● Create route configuration file and register it to app


● Create controller.action with WORKFLOW
● Create tests

DETAILS:

Route path /login


Method POST: Public
Controller action name SecurityController: login
Post data email | username, password

WORKFLOW:

Clien API
t client.post (email | username, password)

ERROR: Invalid login (Invalid Identifiants)


Check in DB if login match
with password

Generate JsonWebToken

Database update
Return valid response (data: JWT)

db.userInfo.update({
last_conneted_date: Date(now)
})
28

V. Password forgot
3H
TOKEN_GENERATOR
● Create route configuration file and add it to app
● Create email template
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /forgot-password


Method POST: Public
Controller action name SecurityController: forgotPassword
Post data email

WORKFLOW:

Clien API
t client.post (email)

Check if email exist in


database

Generate new
ERROR:
ResetPasswordToken
(Email not
found)
Update new token info in
database

Send email
Return valid response for each case (privacy) (Password recovery)

db.userSecurity.update({
reset_password_token: *generated*,
reset_password_token_limit: *generated*
})
29

VI. Password reset


3H
HASHER
● Create route configuration file and add it to app
● Create email template
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /reset-password


Method POST: Public
Controller action name SecurityController: resetPassword
Post data password, passwordConfirmation, token

WORKFLOW:

Clien API
t client.post (email)

ERROR: (Passwords should match)


Check if password and
passwordConfirmation is valid
and match
ERROR: (Impossible to reset password)
Check if token exist and is
valid

Database update

Send email
Valid response (Password updated)

db.user.update({
password: *hash(validate(input))*,
reset_password_token: null,
reset_password_token_limit: null
})

db.userInfo.update({
last_password_update: Date(now)
})
30

VII. Get profile


2H
NO_REQUIREMENT
● Create route configuration file and add it to app
● Create controller.action with WORKFLOW
● Create route tests

WORKFLOW:

Clien API
t client(Private: authUser).get

Database reading
Valid response

DETAILS:

Route path /account/profile


Method GET: Protected(Auth-User)
Controller action name UserController: getProfile
Get data
31

VIII. Update profile


3H
NO_REQUIREMENT

● Create route configuration file and add it to app


● Create email template
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /account/profile


Method POST: Private(Auth-User)
Controller action name UserController: updateProfile
Post data { profileData }

WORKFLOW:

Clien API
client.post (Private: authUser)
t ({ profileData })

ERROR: Invalid data (+details)


Validate profile data

Database update

Send email
Return valid response (Profile update)

db.userProfile.update({ *PROFILE_DATA* })

db.userInfos.update({
last_profile_update: Date(now)
})
32

IX. Username update


3H
JWT_ADAPTER
● Create route configuration file and add it to app
● Create email template
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /account/username


Method POST: Private(Auth-User)
Controller action name UserController: updateUsername
Post data username

WORKFLOW:

Clien API
client.post (Private: authUser)
t (username)

ERROR: Invalid username (+details)


Validate username

ERROR: Username already used (+details)


Database update

Generate new
JsonWebToken

Send email
Return valid response (Username update)

db.user.update({
username: *validate(input)*
})
db.userArchive.update({
olds_username: exist.push(old_username)
})
db.userInfos.update({
last_username_update_date: Date(now)
33

})

X. Email update

3H
TOKEN_GENERATOR, HASHER

● Create route configuration file and add it to app


● Create email template
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /account/email


Method POST: Private(Auth-User)
Controller action name SecurityController: updateEmail
Post data email, password

WORKFLOW:

Clien API
client.post (Private: authUser)
t (email, password)

ERROR: Invalid password


Check if password is valid

Generate confirmation
token
ERROR: Email already used
Database update

Send email
Return valid response (email update confirmation)
34

db.user.update({
email: *validate(input)*,
is_confirmed: false
})

db.userArchive.update({
olds_email: exists.push(old_email)
})

db.userInfos.update({
last_email_update: Date(now)
})

db.userSecurity.update({
update_email_token: *generated*,
update_email_token_limit: Date(now + 1H)
})
35

XI. Email update confirmation


2H
NO_REQUIREMENT

● Create route configuration file and add it to app


● Create email template
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /account/email-confirmation/{token}


Method GET: Private(Auth-User)
Controller action name SecurityController: emailUpdateConfirmation
Get data userID, token

WORKFLOW:

Clien API
t client.get (token)

ERROR: Invalid token


Check if token is valid

Database update

Send email (new email)


Return valid response

db.user.update({
is_confirmed: true
})

db.userSecurity.update({
update_email_token: null,
update_email_token_limit: null
})
36

XII. Password update


3H
TOKEN_GENERATOR, HASHER
● Create route configuration file and add it to app
● Create email template
● Create controller.action with WORKFLOW
● Create route tests

WORKFLOW:

Clien API
client.post
t (oldPassword, password,
passwordConfirmation)

ERROR: Invalid passwords


Validate new password

ERROR: Invalid old password


Check old password

Database update

Send email
Valid response (Password has been
updated)

DETAILS:

Route path /account/password


Method POST: Private(Auth-User)
Controller action name SecurityController: updatePassword
Get data oldPassword, password, passwordConfirmation

db.user.update({
password: *hash(validate(input))*
})

db.userInfo.update({
last_password_update: Date(now)
})
37

XIII. Get my public tokens


3H
NO_REQUIREMENT
● Create route configuration file and add it to app
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /account/tokens


Method GET: Private(Auth-User) Protected(Auth-Admin)
Controller action name UserController: getTokens
Get data
38

XIV. Create public tokens


3H
NO_REQUIREMENT
● Create route configuration file and add it to app
● Create email templates (new)
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /account/tokens


Method POST: Private(Auth-User)
Controller action name PublicTokensController: createToken
Post data description

WORKFLOW:

Clien API
t client.get

ERROR: Invalid input data (+details)


Validate data (description)

Generate token

Database update

Send email
Valid response (New token created)

db.publicTokens.create({
secure_token: *generated*,
description: validate(input),
date: Date(now),
date_limit: Date(now + 120D),
user_id: *UserID*
})
39

XV. Delete public tokens


3H
NO_REQUIREMENT
● Create route configuration file and add it to app
● Create email templates (delete)
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /account/tokens/delete/{token}


Method GET: Private(Auth-User)
Controller action name PublicTokensController: deleteToken
Get data token

WORKFLOW:

Clien API
t client.get (token)

ERROR: Invalid token


Get token entity

Database delete (token)

Send email
Valid response (Token deleted)

db.publicTokens.delete(WHERE token = GET[token])


40

XVI. Disable account


3H
TOKEN_GENERATOR
● Create route configuration file and add it to app
● Create email templates
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /account/disable


Method GET: Private(Auth-User)
Controller action name SecurityController: disableAccount
Get data

WORKFLOW:

Clien API
t client.get ()

Generate token

Database update

Send email
Valid response (Disable account
confirmation)

db.userSecurity.update({
disable_account_token: *generated*,
disable_account_token_limit: Date(now)
})
41

XVII. Disable account confirmation


3H
TOKEN_GENERATOR
● Create route configuration file and add it to app
● Create email templates
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /account/disable/{token}


Method GET: Private(Auth-User)
Controller action name SecurityController: disableAccountConfirmation
Get data token

WORKFLOW:

Clien API
t client.get ()

Check token validity

Database update

Send email
Valid response (Disabled account)

db.user.update({
is_disabled: true
})

db.userSecurity.update({
disable_account_token: null,
disable_account_token_limit: null
})
42
43

XVIII. Get own data


3H
DATA_FORMATTER
● Create route configuration file and add it to app
● Create email templates
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /account/get-my-data


Method GET: Private(Auth-User)
Controller action name UserController: getMyOwnData
Get data

WORKFLOW:

Clien API
t client.get ()

Send job in queue to get


Valid response
structured dataset

Send email
ASYNC
(Dataset)
Build user dataset and send it to user
Parse many data
44

Administrators
Routes

I. Add roles
2H
NO_REQUIREMENT
● Create route configuration file and add it to app
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/roles/add


Method POST: Private(Auth-Admin)
Controller action name AdminManagementController: addRoles
Post data userId, [rolesList]

WORKFLOW:

Clien API
t client.post (rolesList)

ERROR: Invalid roles (+details)


Check roles validity

Database update
Valid response

db.user.update({
roles: exists.merge(input)
})
45

II. Remove roles


2H
NO_REQUIREMENT
● Create route configuration file and add it to app
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/user-roles/delete


Method POST: Private(Auth-Admin)
Controller action name AdminManagementController: removeRolesPost
Post data userId, [rolesList]

WORKFLOW:

Clien API
t client.post (rolesList)

ERROR: No roles found (+details)


Database update
(remove existing item from list to db)
Valid response

db.user.update({
roles: exists.remove(inputs)
})
46

III. Get individual user data


2H
NO_REQUIREMENT
● Create route configuration file and add it to app
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/users/{userId}


Method GET: Private(Auth-Admin)
Controller action name AdminManagementController: getUser
Get data userId

WORKFLOW:

Clien API
t client.get

Database request
Return response
47

IV. Update individual user data


3H
NO_REQUIREMENT
● Create route configuration file and add it to app
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/users/{userId}


Method POST: Private(Auth-Admin)
Controller action name AdminManagementController: updateUser
Post data dataSet

WORKFLOW:

Clien API
t client.post (dataSet)

ERROR: Invalid data (+details)


Validate posted data

Database update
Valid response
48

V. Update user by selecting


4H
NO_REQUIREMENT
● Create route configuration file and add it to app
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/users


Method POST: Private(Auth-Admin)
Controller action name AdminManagementController: updateUsers
Post data dataSet

WORKFLOW:

Clien API
t client.post (dataset list)

ERROR: Invalid data (+details)


Validate data

Database update
Valid response
49

VI. Get users list


3H
NO_REQUIREMENT
● Create route configuration file and add it to app
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/users


Method POST: Private(Auth-Admin)
Controller action name AdminManagementController: getUserList
Get data PAGINATE list

WORKFLOW:

Clien API
t client.get (page)

Database request
(select user using paginate)
Valid response
50

VII. Create account


4H
NO_REQUIREMENT
● Create route configuration file and add it to app
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/users/create


Method POST: Private(Auth-Admin)
Controller action name AdminManagementController: createUser
Get data username, email, password, passwordConfirmation

WORKFLOW:

Clien API
client.post
t (username, email, password,
passwordConfirmation)

ERROR: Invalid data (+details)


Validate data

Hash password

Generate public_key &


identifiant_key
ERROR: Email or username already used
Database input
Valid response
51

db.userInfo.create({
last_user_ip: *UserIP*,
last_user_ip_date: Date(now),
registration_date: Date(now),
registration_confirmation_date: Date(now)
})

db.userProfile.create({
*EMPTY*
})

db.userArchive.create({
olds_usernames: [],
olds_emails: [],
user_id: *UserID*
})

db.userSecurity.create({
public_key: *generated*,
account_confirmation_token: null,
account_confirmation_token_limit: null
})

db.user.create({
identifiant_key: *generated*,
username: validate(*input*),
email: validate(*input*),
password: hash(validate(*input*)),
roles: [‘ROLE_USER’],
groups: [],
is_active: false,
is_blocked: false,
is_disabled: false,
is_confirmed: false,
user_security_id: *UserSecurityID*,
user_profile_id: *UserProfileID*,
user_info_id: *UserInfoID*
})
52

VIII. Disable accounts


4H
NO_REQUIREMENT
● Create route configuration file and add it to app
● Create controller.action with WORKFLOW
● Create email template (account disabled)
● Create route tests

DETAILS:

Route path /admin/users/disable


Method POST: Private(Auth-Admin)
Controller action name AdminManagementController: disableUsers
Post data userList, reason

WORKFLOW:

Clien API
t client.post (userList)

ERROR: Invalid data (+details)


Database update

Send email for each disable


accounts
Valid response (Account disabled)

db.each.userInfo.update({
reason_disable: *input*
})

db.each.user.update({
is_disabled: true
})
53

IX. Delete accounts


4H
NO_REQUIREMENT
● Create route configuration file and add it to app
● Create controller.action with WORKFLOW
● Create email template (account deleted)
● Create route tests

DETAILS:

Route path /admin/users/delete


Method POST: Private(Auth-Admin)
Controller action name AdminManagementController: deleteUsers
Post data userList, reason

WORKFLOW:

Clien API
t client.post (userList)

ERROR: Invalid data (+details)


Database update
(delete users)

Send email for each deleted


accounts
Valid response (Account deleted)

db.each.user.delete( * CASCADE * )
54

X. Get disabled users


2H
NO_REQUIREMENT
● Create route configuration file and add it to app
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/users/is-disabled


Method GET: Private(Auth-Admin)
Controller action name AdminManagementController: getDisabledUser
GET data PAGINATE
55

XI. Send newsletter


8H
WYSIWYG
● Create route configuration file and add it to app
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/newsletter


Method POST: Private(Auth-Admin)
Controller action name AdminManagementController: sendNewsletter
Post data users (group), title, subject, content

WORKFLOW:

Clien API
t client.post (users, title, subject, content)

ERROR: Invalid data (+details)


Validate data

Valid response Send jobs to service


mailer

Do jobs and send emails


ASYNC
56

XII. Reset user public_key


4H
PUBLIC_KEY_GENERATOR
● Create route configuration file and add it to app
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/users/{userId}/reset-public-key


Method GET: Private(Auth-Admin)
Controller action name AdminManagementController: resetUserPk
Get data

WORKFLOW:

Clien API
t client.get (userId)

Generate new public keys

ERROR: Invalid data (user not found)


Database update
Valid response

db.userSecurity.update({
public_key: *generated*
})

db.userArchive.update({
olds_public_key: exist.push(input)
})
57

XIII. Add user public token


2H
TOKEN_GENERATOR
● Create route configuration file and add it to app
● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/users/public-token


Method POST: Private(Auth-Admin)
Controller action name AdminManagementController: addPublicToken
Get data userId, description

WORKFLOW:

Clien API
t client.get (userId)

Generate public token

ERROR: User not found


Database update
Valid response

db.userPublicTokens.create({
secure_token: *generated*,
description: *validate(input)*,
date: Date(now),
date_limit Date(now + 120D),
user_id: *UserID*
})
58

XIV. Remove user public token

2H
NO_REQUIREMENT

● Create route configuration file and add it to app


● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/publics-tokens/{tokenId}/remove


Method GET: Private(Auth-Admin)
Controller action name AdminManagementController: removePublicToken
Get data tokenId

WORKFLOW:

Clien API
t client.get (tokenId)

ERROR: Token not found


Database update
Valid response (Delete tokens)

db.userPublicTokens.create(WHERE id = :tokenId)
59

XV. Ban user


2H
NO_REQUIREMENT

● Create route configuration file and add it to app


● Create controller.action with WORKFLOW
● Create email template (user banned)
● Create route tests

DETAILS:

Route path /admin/users/ban


Method POST: Private(Auth-Admin)
Controller action name AdminManagementController: banUser
Post data userId, time, reason

WORKFLOW:

Clien API
t client.post (userId, time, reason)

ERROR: User not found


Database update

Send email
Valid response (Banned user)
60

db.user.update({
is_active: false,
is_blocked: true
})

db.userSecurity.update({
blocked_account_date: Date(now),
blocked_account_limit: Date(now + input)
})

db.userInfo.update({
reason_blocked: validate(input)
})
61

XVI. Ban ip

2H
NO_REQUIREMENT

● Create route configuration file and add it to app


● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/ip/ban


Method POST: Private(Auth-Admin)
Controller action name AdminManagementController: banIp
Post data ip, type, reason

WORKFLOW:

Clien API
t client.post (ip, type, reason, time)

Database update
Valid response

db.blockedIp.create({
ip: validate(input),
type: validate(input),
reason: validate(input),
date: Date(now),
date_limit: Date=(input)
})
62

XVII. Get banned users


2H
NO_REQUIREMENT

● Create route configuration file and add it to app


● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/users/ban


Method GET: Private(Auth-Admin)
Controller action name AdminManagementController: getBlockedUsers
Get data PAGINATE

WORKFLOW:

Clien API
t client.get (PAGINATE)

Database read
Valid response
63

XVIII. Get banned ip

2H
NO_REQUIREMENT

● Create route configuration file and add it to app


● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/ip/ban


Method GET: Private(Auth-Admin)
Controller action name AdminManagementController: getBlockedIp
Get data PAGINATE

WORKFLOW:

Clien API
t client.get (PAGINATE)

Database read
Valid response
64

XIX. Get user data set (dl)


2H
DATA_FORMATTER

● Create route configuration file and add it to app


● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/users/{userId}/dataset


Method GET: Private(Auth-Admin)
Controller action name AdminManagementController: getUserDataset
Get data PAGINATE

WORKFLOW:

Clien API
t client.get (userId)

ERROR: User not found


Check if user exist

Return valid response Send jobs to queue

Send email
(User Dataset)
65

XX. Get anonymized user dataset


2H
DATA_FORMATTER

● Create route configuration file and add it to app (route option)


● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/users/dataset/{userId}?anonymous=true


Method GET: Private(Auth-Admin)
Controller action name AdminManagementController: getUserDataset extention
Get data optional=anonymous(boolean)

WORKFLOW:

Clien API
t client.get (userId)

ERROR: User not found


Check if user exist

Return valid response Send jobs to queue

Send email
(User Anonymyzed
Dataset)
66

XXI. Create group


2H
NO_REQUIREMENT

● Create route configuration file and add it to app


● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /groups/create


Method POST: Private(Auth-Admin)
Controller action name GroupsController: addGroup
Post data name, description

WORKFLOW:

Clien API
t client.post (name, description)

ERROR: Invalid data (+details)


Validate data

ERROR: Name already used


Database update
Return valid response

db.group.create({
name: validate(input),
description: validate(input),
created_date: Date(now)
})
67

XXII. Remove group

2H
NO_REQUIREMENT

● Create route configuration file and add it to app


● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/groups/{groupId}/delete


Method GET: Private(Auth-Admin)
Controller action name GroupsController: removeGroup
Get data groupId

WORKFLOW:

Clien API
t client.get (groupId)

ERROR: Group not found


Database update
Valid response (delete group)

db.group.remove(WHERE group_id = :id)


68

XXIII. Update group


2H
NO_REQUIREMENT

● Create route configuration file and add it to app


● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path admin/groups


Method POST: Private(Auth-Admin)
Controller action name GroupsController: updateGroup
Post data groupId, ?name, ?description

WORKFLOW:

Clien API
t client.post (groupID, name, description)

ERROR: Invalid data (+details)


Validate data

ERROR: Name already used or group not


found Database update
Valid response

db.group.update({
name: validate(input),
description: validate(input),
updated_date: Date(now)
})
69

XXIV. Get list of groups


2H
NO_REQUIREMENT

● Create route configuration file and add it to app


● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/groups


Method GET: Private(Auth-Admin)
Controller action name GroupsController: getGroups
Get data PAGINATE
70

XXV. Add user to group


2H
NO_REQUIREMENT

● Create route configuration file and add it to app


● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/groups/add-user


Method POST: Private(Auth-Admin)
Controller action name GroupsController: addUserGroup
Post data groupId, userId

WORKFLOW:

Clien API
t client.post (groupID, userID)

ERROR: User or Group not found


Find group and user

Database update
Valid response

db.usersGroups.create({
user_id: validate(input),
group_id: validate(input),
joinded_date: Date(now)
})
71

XXVI. Remove user to group


2H
NO_REQUIREMENT

● Create route configuration file and add it to app


● Create controller.action with WORKFLOW
● Create route tests

DETAILS:

Route path /admin/groups/remove-user


Method POST: Private(Auth-Admin)
Controller action name GroupsController: removeUserGroup
Post data groupId, userId

WORKFLOW:

Clien API
t client.post (groupID, userID)

ERROR: usersGroups not found


Database update
Valid response (remove usersGroups)

db.usersGroups.remove(
WHERE user_id = userId,
group_id = groupId
)
72

XXVII. Get statistic for each application case (v2)


// Sub project, need to clear all basicals features and modules.

XXVIII. Get monitoring (v2)


// Sub project, need to clear all basicals features and modules.

Module

I. Have filters for users list

8H
ADMINISTRATORS_ROUTES

● Create module
● Plug module to app
● Create module tests

The purpose of this module is to consume the parameters of the query of the route to see the
list of users. As the route is only accessible by admins, a large number of parameters can serve
as filters, starting with the global dates, roles, groups, username and more.

More details on StoriesBoard

You might also like