Browse Source

Improving swagger doc

main
ddangelorb 3 years ago
parent
commit
b5933f63a1
  1. 2
      index.html
  2. 170
      src/main/java/org/waterproofingdata/wpdauth/controller/UsersController.java
  3. 34
      src/main/java/org/waterproofingdata/wpdauth/service/UsersService.java
  4. 2
      src/test/java/org/waterproofingdata/wpdauth/integrationtest/UsersServiceIntegrationTest.java
  5. 325
      swagger.yaml

2
index.html

@ -1,5 +1,5 @@
<!DOCTYPE html>
<!-- V1.0.3.0.0-->
<!-- V1.0.3.0.1-->
<html lang="en">
<head>

170
src/main/java/org/waterproofingdata/wpdauth/controller/UsersController.java

@ -31,68 +31,153 @@ public class UsersController {
@Autowired
private UsersService userService;
/*
@ApiParam(
name = "firstName",
type = "String",
value = "First Name of the user",
example = "Vatsal",
required = true)
@RequestParam String firstName)
*/
@PostMapping("/login")
@ApiOperation(value = "${UserController.login}")
@ApiOperation(
value = "${UserController.login}",
notes = "From a valid username and password, this method returns the JWT Token to be used in secure methods."
)
@ApiResponses(value = {//
@ApiResponse(code = 400, message = "Something went wrong"), //
@ApiResponse(code = 422, message = "Invalid username/password supplied")})
@ApiResponse(code = 400, message = "Something went wrong"), //
@ApiResponse(code = 404, message = "Invalid username/password supplied")
}
)
public String login(//
@ApiParam("Username") @RequestParam String username, //
@ApiParam("Password") @RequestParam String password) {
return userService.login(username, password);
@ApiParam(
name = "username",
type = "String",
value = "username of the user",
example = "This is an unique field, and consumers should be aware of it. By convention, WP6 should send the user phone number (i.e. (99)99999-9999).",
required = true
)
@RequestParam String username, //
@ApiParam(
name = "password",
type = "String",
value = "password of the user",
example = "i.e. P@s5w0rD",
required = true
)
@RequestParam String password
) {
return userService.login(username, password);
}
@PostMapping("/signup")
@ApiOperation(value = "${UserController.signup}")
@ApiOperation(
value = "${UserController.signup}",
notes = "This the signup method to create new users. By defaul all users are created as inactive. To activate, the method ${UserController.activate} should be invoked."
)
@ApiResponses(value = {//
@ApiResponse(code = 400, message = "Something went wrong"), //
@ApiResponse(code = 403, message = "Access denied"), //
@ApiResponse(code = 422, message = "Username is already in use")})
public String signup(@ApiParam("Signup User") @RequestBody UsersRequestDTO user) {
return userService.signup(CustomMapper.map(user, Users.class));
@ApiResponse(code = 400, message = "Something went wrong"), //
@ApiResponse(code = 422, message = "Required parameters should be provided")
}
)
public String signup(
@ApiParam(
name = "user",
value = "Signup User",
required = true
)
@RequestBody UsersRequestDTO user
) {
return userService.signup(CustomMapper.map(user, Users.class));
}
@PostMapping("/sendadminkeybyemailcemaden")
@ApiOperation(value = "${UserController.sendadminkeybyemailcemaden}")
@PreAuthorize("hasRole('ROLE_INSTITUTION')")
@ApiOperation(
value = "${UserController.sendadminkeybyemailcemaden}",
authorizations = {@Authorization(value="apiKey")},
notes = "This method is used for role 'ROLE_INSTITUTION'. To activate these users, a key is sent to the EduCemandenOrg e-mail and the user should inform this key to proceed."
)
@ApiResponses(value = {//
@ApiResponse(code = 400, message = "Something went wrong"), //
@ApiResponse(code = 403, message = "Access denied"), //
@ApiResponse(code = 422, message = "Username is already in use")})
public void sendadminkeybyemailcemaden(@ApiParam("Emailcemaden") @PathVariable String emailcemaden, @ApiParam("Username") @PathVariable String username) {
userService.sendAdminKeyByEmailCemaden(emailcemaden, username);
@ApiResponse(code = 400, message = "Something went wrong"), //
@ApiResponse(code = 403, message = "Access denied"), //
@ApiResponse(code = 404, message = "User or Email Cemaden not found"), //
@ApiResponse(code = 500, message = "Expired or invalid JWT token")
}
)
public void sendadminkeybyemailcemaden(
@ApiParam(
name = "emailcemaden",
type = "String",
value = "Emailcemaden associated to the user",
example = "The Cemaden e-mail registred in the database. The key will be sent to this e-mail, and the user should be inform this key to proceed.",
required = true
)
@RequestParam String emailcemaden, //
@ApiParam(
name = "username",
type = "String",
value = "username of the user",
example = "This is an unique field, and consumers should be aware of it. By convention, WP6 should send the user phone number (i.e. (99)99999-9999).",
required = true
)
@RequestParam String username
) {
userService.sendAdminKeyByEmailCemaden(emailcemaden, username);
}
@PostMapping("/activate")
@PreAuthorize("hasRole('ROLE_INSTITUTION') or hasRole('ROLE_CLIENT')")
@ApiOperation(value = "${UserController.activate}", authorizations = { @Authorization(value="apiKey") })
@ApiOperation(
value = "${UserController.activate}",
authorizations = { @Authorization(value="apiKey") },
notes = "This is the user activation method."
)
@ApiResponses(value = {//
@ApiResponse(code = 400, message = "Something went wrong"), //
@ApiResponse(code = 403, message = "Access denied"), //
@ApiResponse(code = 404, message = "The user doesn't exist"), //
@ApiResponse(code = 500, message = "Expired or invalid JWT token")})
public String activate(@ApiParam("Username") @PathVariable String username, @ApiParam("ActivationKey") @PathVariable String activationkey) {
userService.activate(username, activationkey);
return username;
@ApiResponse(code = 422, message = "User or ActivationKey registration issues"), //
@ApiResponse(code = 500, message = "Expired or invalid JWT token")
}
)
public String activate(
@ApiParam(
name = "username",
type = "String",
value = "username of the user",
example = "This is an unique field, and consumers should be aware of it. By convention, WP6 should send the user phone number (i.e. (99)99999-9999).",
required = true
)
@RequestParam String username, //
@ApiParam(
name = "activationkey",
type = "String",
value = "Activation Key to activate the user",
example = "If user belongs to 'ROLE_INSTITUTION' the key should be collected from the emailcemaden, previously sent by ${UserController.sendadminkeybyemailcemaden}. If the user belongs to 'ROLE_CLIENT' the key should be provided by a 'ROLE_INSTITUTION' valid user.",
required = true
)
@RequestParam String activationkey
) {
userService.activate(username, activationkey);
return username;
}
@GetMapping(value = "/{username}")
@PreAuthorize("hasRole('ROLE_ADMIN')")
@ApiOperation(value = "${UserController.search}", response = UsersResponseDTO.class, authorizations = { @Authorization(value="apiKey") })
@ApiOperation(
value = "${UserController.search}",
response = UsersResponseDTO.class,
authorizations = { @Authorization(value="apiKey") },
notes = "This is the user search method by username."
)
@ApiResponses(value = {//
@ApiResponse(code = 400, message = "Something went wrong"), //
@ApiResponse(code = 403, message = "Access denied"), //
@ApiResponse(code = 404, message = "The user doesn't exist"), //
@ApiResponse(code = 500, message = "Expired or invalid JWT token")})
public UsersResponseDTO search(@ApiParam("Username") @PathVariable String username) {
@ApiResponse(code = 403, message = "Access denied"), //
@ApiResponse(code = 404, message = "The user doesn't exist"), //
@ApiResponse(code = 500, message = "Expired or invalid JWT token")
}
)
public UsersResponseDTO search(
@ApiParam(
name = "username",
type = "String",
value = "username of the user",
example = "This is an unique field, and consumers should be aware of it. By convention, WP6 should send the user phone number (i.e. (99)99999-9999).",
required = true
)
@RequestParam String username
) {
UsersResponseDTO urDTO = CustomMapper.map(userService.search(username), UsersResponseDTO.class);
urDTO.setEduCemadenOrganization(userService.findEduCemadenOrganizationById(urDTO.getId()));
urDTO.setProviderActivationKey(userService.findProviderActivationKeyById(urDTO.getId()));
@ -101,7 +186,12 @@ public class UsersController {
@GetMapping(value = "/me")
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')")
@ApiOperation(value = "${UserController.me}", response = UsersResponseDTO.class, authorizations = { @Authorization(value="apiKey") })
@ApiOperation(
value = "${UserController.me}",
response = UsersResponseDTO.class,
authorizations = { @Authorization(value="apiKey") },
notes = "This is the user search method by token."
)
@ApiResponses(value = {//
@ApiResponse(code = 400, message = "Something went wrong"), //
@ApiResponse(code = 403, message = "Access denied"), //

34
src/main/java/org/waterproofingdata/wpdauth/service/UsersService.java

@ -6,6 +6,7 @@ import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.security.authentication.AuthenticationManager;
@ -66,11 +67,18 @@ public class UsersService {
public String login(String username, String password) {
try {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
return jwtTokenProvider.createToken(username, usersRepository.findByUsername(username).getRoles());
Users u = search(username);
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
return jwtTokenProvider.createToken(username, u.getRoles());
}
catch (AuthenticationException e) {
throw new CustomException("Invalid username/password supplied", HttpStatus.NOT_FOUND);
catch (CustomException ce) {
throw ce;
}
catch (AuthenticationException ae) {
throw new CustomException("Invalid username/password supplied", HttpStatus.NOT_FOUND);
}
catch (Exception e) {
throw new CustomException("Something went wrong", HttpStatus.BAD_REQUEST);
}
}
@ -105,8 +113,13 @@ public class UsersService {
user.setPassword(passwordEncoder.encode(user.getPassword()));
user.setActive(0);
usersRepository.save(user);
return jwtTokenProvider.createToken(user.getUsername(), user.getRoles());
try {
usersRepository.save(user);
return jwtTokenProvider.createToken(user.getUsername(), user.getRoles());
}
catch (Exception e) {
throw new CustomException("Something went wrong", HttpStatus.BAD_REQUEST);
}
}
else {
throw new CustomException("Username is already in use", HttpStatus.UNPROCESSABLE_ENTITY);
@ -126,7 +139,12 @@ public class UsersService {
message.setTo(emailcemaden);
message.setSubject("Envio de código para alteração de senha");
message.setText(String.format("Olá! O usuário '%s' solicitou a ativação dele para ADMIN dessa Instituição, por isso você está recebendo esse código: '%s'. Se estiver correto, informe esse código ao solicitante e peça para entrar no aplicativo para prosseguir.", user.getNickname(), uuid));
mailSender.send(message);
try {
mailSender.send(message);
}
catch (MailException me) {
throw new CustomException("Something went wrong", HttpStatus.BAD_REQUEST);
}
UsersEducemadenOrganizations userEducemadenOrg = new UsersEducemadenOrganizations();
userEducemadenOrg.setUsersid(user.getId());
@ -189,7 +207,7 @@ public class UsersService {
throw new CustomException("Admin users should be activated through database.", HttpStatus.UNPROCESSABLE_ENTITY);
}
else {
throw new CustomException("There is a problem with this User registration and it can not be activated.", HttpStatus.UNPROCESSABLE_ENTITY);
throw new CustomException("There is a problem with this User registration and it can not be activated.", HttpStatus.BAD_REQUEST);
}
}

2
src/test/java/org/waterproofingdata/wpdauth/integrationtest/UsersServiceIntegrationTest.java

@ -57,7 +57,7 @@ public class UsersServiceIntegrationTest {
"Expected usersService.login(xpto, xpto) to throw, but it didn't"
);
assertTrue(thrown.getMessage().contains("Invalid username/password supplied"));
assertTrue(thrown.getMessage().contains("The user doesn't exist"));
assertEquals(HttpStatus.NOT_FOUND, thrown.getHttpStatus());
}

325
swagger.yaml

@ -37,12 +37,12 @@ paths:
- Authorization:
- global
deprecated: false
/forgotpasswords/loginbyemailandanswers:
/forgotpasswords/loginbyusernameandanswers:
post:
tags:
- forgotpasswords
summary: ${ForgotPasswordsController.loginbyemailandanswers}
operationId: loginbyemailandanswersUsingPOST
summary: ${ForgotPasswordsController.loginbyusernameandanswers}
operationId: loginbyusernameandanswersUsingPOST
consumes:
- application/json
produces:
@ -56,9 +56,9 @@ paths:
type: array
items:
$ref: '#/definitions/ForgotPasswordsQuestionsUsersAnswersRequestDTO'
- name: email
- name: username
in: query
description: Email
description: Username
required: false
type: string
allowEmptyValue: false
@ -77,26 +77,26 @@ paths:
- Authorization:
- global
deprecated: false
/forgotpasswords/loginbyemailandkey:
/forgotpasswords/loginbyusernameandkey:
post:
tags:
- forgotpasswords
summary: ${ForgotPasswordsController.loginbyemailandkey}
operationId: loginbyemailandkeyUsingPOST
summary: ${ForgotPasswordsController.loginbyusernameandkey}
operationId: loginbyusernameandkeyUsingPOST
consumes:
- application/json
produces:
- '*/*'
parameters:
- name: email
- name: key
in: query
description: Email
description: Key
required: false
type: string
allowEmptyValue: false
- name: key
- name: username
in: query
description: Key
description: Username
required: false
type: string
allowEmptyValue: false
@ -113,26 +113,26 @@ paths:
- Authorization:
- global
deprecated: false
/forgotpasswords/passwordupdatebyemail:
/forgotpasswords/passwordupdatebyusername:
post:
tags:
- forgotpasswords
summary: ${ForgotPasswordsController.passwordupdatebyemail}
operationId: passwordupdatebyemailUsingPOST
summary: ${ForgotPasswordsController.passwordupdatebyusername}
operationId: passwordupdatebyusernameUsingPOST
consumes:
- application/json
produces:
- '*/*'
parameters:
- name: email
- name: newPassword
in: query
description: Email
description: NewPassword
required: false
type: string
allowEmptyValue: false
- name: newPassword
- name: username
in: query
description: NewPassword
description: Username
required: false
type: string
allowEmptyValue: false
@ -202,6 +202,12 @@ paths:
required: false
type: string
allowEmptyValue: false
- name: username
in: query
description: Username
required: false
type: string
allowEmptyValue: false
responses:
'200':
description: OK
@ -218,6 +224,7 @@ paths:
tags:
- users
summary: ${UserController.activate}
description: This is the user activation method.
operationId: activateUsingPOST
consumes:
- application/json
@ -225,15 +232,19 @@ paths:
- '*/*'
parameters:
- name: activationkey
in: path
description: ActivationKey
required: false
in: query
description: Activation Key to activate the user
required: true
type: string
allowEmptyValue: false
x-example: If user belongs to 'ROLE_INSTITUTION' the key should be collected from the emailcemaden, previously sent by ${UserController.sendadminkeybyemailcemaden}. If the user belongs to 'ROLE_CLIENT' the key should be provided by a 'ROLE_INSTITUTION' valid user.
- name: username
in: path
description: Username
required: false
in: query
description: username of the user
required: true
type: string
allowEmptyValue: false
x-example: This is an unique field, and consumers should be aware of it. By convention, WP6 should send the user phone number (i.e. (99)99999-9999).
responses:
'200':
description: OK
@ -243,8 +254,8 @@ paths:
description: Something went wrong
'403':
description: Access denied
'404':
description: The user doesn't exist
'422':
description: User or ActivationKey registration issues
'500':
description: Expired or invalid JWT token
security:
@ -257,6 +268,7 @@ paths:
tags:
- users
summary: ${UserController.login}
description: From a valid username and password, this method returns the JWT Token to be used in secure methods.
operationId: loginUsingPOST
consumes:
- application/json
@ -265,16 +277,18 @@ paths:
parameters:
- name: password
in: query
description: Password
required: false
description: password of the user
required: true
type: string
allowEmptyValue: false
x-example: i.e. P@s5w0rD
- name: username
in: query
description: Username
required: false
description: username of the user
required: true
type: string
allowEmptyValue: false
x-example: This is an unique field, and consumers should be aware of it. By convention, WP6 should send the user phone number (i.e. (99)99999-9999).
responses:
'200':
description: OK
@ -282,7 +296,7 @@ paths:
type: string
'400':
description: Something went wrong
'422':
'404':
description: Invalid username/password supplied
security:
- Authorization:
@ -293,6 +307,7 @@ paths:
tags:
- users
summary: ${UserController.me}
description: This is the user search method by token.
operationId: whoamiUsingGET
produces:
- '*/*'
@ -329,11 +344,54 @@ paths:
- Authorization:
- global
deprecated: false
/users/sendadminkeybyemailcemaden:
post:
tags:
- users
summary: ${UserController.sendadminkeybyemailcemaden}
description: This method is used for role 'ROLE_INSTITUTION'. To activate these users, a key is sent to the EduCemandenOrg e-mail and the user should inform this key to proceed.
operationId: sendadminkeybyemailcemadenUsingPOST
consumes:
- application/json
produces:
- '*/*'
parameters:
- name: emailcemaden
in: query
description: Emailcemaden associated to the user
required: true
type: string
allowEmptyValue: false
x-example: The Cemaden e-mail registred in the database. The key will be sent to this e-mail, and the user should be inform this key to proceed.
- name: username
in: query
description: username of the user
required: true
type: string
allowEmptyValue: false
x-example: This is an unique field, and consumers should be aware of it. By convention, WP6 should send the user phone number (i.e. (99)99999-9999).
responses:
'200':
description: OK
'400':
description: Something went wrong
'403':
description: Access denied
'404':
description: User or Email Cemaden not found
'500':
description: Expired or invalid JWT token
security:
- Authorization:
- global
- apiKey: []
deprecated: false
/users/signup:
post:
tags:
- users
summary: ${UserController.signup}
description: This the signup method to create new users. By defaul all users are created as inactive. To activate, the method ${UserController.activate} should be invoked.
operationId: signupUsingPOST
consumes:
- application/json
@ -343,7 +401,7 @@ paths:
- in: body
name: user
description: Signup User
required: false
required: true
schema:
$ref: '#/definitions/UsersRequestDTO'
responses:
@ -353,10 +411,8 @@ paths:
type: string
'400':
description: Something went wrong
'403':
description: Access denied
'422':
description: Username is already in use
description: Required parameters should be provided
security:
- Authorization:
- global
@ -366,22 +422,23 @@ paths:
tags:
- users
summary: ${UserController.search}
description: This is the user search method by username.
operationId: searchUsingGET
produces:
- '*/*'
parameters:
- name: username
in: path
description: Username
required: false
in: query
description: username of the user
required: true
type: string
allowEmptyValue: false
x-example: This is an unique field, and consumers should be aware of it. By convention, WP6 should send the user phone number (i.e. (99)99999-9999).
responses:
'200':
description: OK
schema:
$ref: '#/definitions/UsersResponseDTO'
'400':
description: Something went wrong
'403':
description: Access denied
'404':
@ -402,14 +459,14 @@ definitions:
EduCemadenOrganizations:
type: object
properties:
activationkey:
type: string
active:
type: string
address:
type: string
creation_date:
type: string
email:
type: string
id:
type: integer
format: int32
@ -455,49 +512,185 @@ definitions:
answer:
type: string
title: ForgotPasswordsQuestionsUsersAnswersRequestDTO
UsersRequestDTO:
UsersProviderActivationKey:
type: object
properties:
username:
type: string
password:
activationkey:
type: string
title: UsersRequestDTO
UsersResponseDTO:
type: object
properties:
id:
type: integer
format: int32
usersid:
type: integer
format: int32
title: UsersProviderActivationKey
UsersRequestDTO:
type: object
required:
- city
- nickname
- password
- roles
- state
- termsofusage
- username
properties:
username:
type: string
example: This is an unique field, and consumers should be aware of it. By convention, WP6 should send the user phone number (i.e. (99)99999-9999).
description: username of the user.
nickname:
type: string
example: i.e. beth2021. This is an unique field, and consumers should be aware of it.
description: nickname of the user.
password:
type: string
example: i.e. P@s5w0rD.
description: password of the user.
dateofborn:
type: string
format: date
example: i.e. 01/12/1978. Format should be dd/MM/yyyy.
description: Date of Born of the user.
gender:
type: string
example: i.e. M. 'M' stands for Male, 'F' Female, 'N' Not Informed
description: Gender of the user.
enum:
- '{@code M'
- F
- N}
state:
type: string
example: i.e. SP. State should be 2 characteres (UF)
description: state of the user.
city:
type: string
example: i.e. 'Governador Valadares'.
description: city of the user.
institutiontype:
type: string
example: i.e. 'E'. E stands for 'School', D 'Civil Defense', N 'No governamental', O 'others'
description: institution type of the user.
enum:
- '{@code E'
- D
- 'N'
- O}
institution:
type: string
example: i.e. 'Colegio Imaginario'.
description: institution of the user.
securityquestion:
type: string
example: i.e. 'What is my favorite color?'.
description: security question of the user.
securityanswer:
type: string
example: i.e. 'Blue'.
description: security answer of the user.
termsofusage:
type: boolean
example: false
description: terms of usage of the user.
roles:
type: array
example: i.e. ROLE_CLIENT.
description: roles of the user.
items:
type: string
enum:
- ROLE_ADMIN
- ROLE_INSTITUTION
- ROLE_CLIENT
eduCemadenOrganization:
$ref: '#/definitions/EduCemadenOrganizations'
rolesProviderActivationKeys:
type: array
items:
$ref: '#/definitions/UsersRolesproviderActivationKey'
title: UsersResponseDTO
UsersRolesproviderActivationKey:
title: UsersRequestDTO
UsersResponseDTO:
type: object
required:
- active
- city
- id
- nickname
- state
- termsofusage
- username
properties:
activationkey:
type: string
id:
type: integer
format: int32
rolesid:
type: integer
format: int32
usersid:
example: This is a SERIAL and Primary Key field.
description: id of the user.
username:
type: string
example: This is an unique field, and consumers should be aware of it. By convention, WP6 should send the user phone number (i.e. (99)99999-9999).
description: username of the user.
nickname:
type: string
example: i.e. beth2021. This is an unique field, and consumers should be aware of it.
description: nickname of the user.
dateofborn:
type: string
format: date
example: i.e. 01/12/1978. Format should be dd/MM/yyyy.
description: Date of Born of the user.
gender:
type: string
example: i.e. M. 'M' stands for Male, 'F' Female, 'N' Not Informed
description: Gender of the user.
enum:
- '{@code M'
- F
- N}
state:
type: string
example: i.e. SP. State should be 2 characteres (UF)
description: state of the user.
city:
type: string
example: i.e. 'Governador Valadares'.
description: city of the user.
institutiontype:
type: string
example: i.e. 'E'. E stands for 'School', D 'Civil Defense', N 'No governamental', O 'others'
description: institution type of the user.
enum:
- '{@code E'
- D
- 'N'
- O}
institution:
type: string
example: i.e. 'Colegio Imaginario'.
description: institution of the user.
securityquestion:
type: string
example: i.e. 'What is my favorite color?'.
description: security question of the user.
securityanswer:
type: string
example: i.e. 'Blue'.
description: security answer of the user.
termsofusage:
type: boolean
example: false
description: terms of usage of the user.
active:
type: integer
format: int32
title: UsersRolesproviderActivationKey
example: i.e. true.
description: whether user is active or not.
role:
type: string
example: i.e. 'ROLE_ADMIN' means system administrator, 'ROLE_INSTITUTION' means institution administrator, 'ROLE_CLIENT' means regular users
description: institution type of the user.
enum:
- '{@code ROLE_ADMIN'
- ROLE_INSTITUTION
- ROLE_CLIENT}
eduCemadenOrganization:
description: which Educational Cemaden Organization the user belongs.
$ref: '#/definitions/EduCemadenOrganizations'
providerActivationKey:
description: If this user can provide an activation key for other users ('ROLE_INSTITUTION'), this field will store the values.
$ref: '#/definitions/UsersProviderActivationKey'
title: UsersResponseDTO
Loading…
Cancel
Save