Skip to content

Commit

Permalink
Merge pull request #35 from PEC-CSS/user/me
Browse files Browse the repository at this point in the history
Fixing user/me api and email verification url
  • Loading branch information
harshjohar authored Aug 18, 2023
2 parents b92d4e4 + 6335aa6 commit b7e6b2a
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 20 deletions.
10 changes: 10 additions & 0 deletions src/main/java/com/pecacm/backend/controllers/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

Expand Down Expand Up @@ -55,6 +57,14 @@ public ResponseEntity<AuthenticationResponse> registerUser(@RequestBody User use
return ResponseEntity.status(HttpStatus.CREATED).body(new AuthenticationResponse(jwtToken, newUser));
}

@GetMapping
@PreAuthorize(Constants.HAS_ROLE_MEMBER_AND_ABOVE)
public ResponseEntity<User> getUserInfo() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String email = (String) authentication.getPrincipal();
return ResponseEntity.ok(userService.getUserByEmail(email));
}

@PostMapping("/login")
@PreAuthorize(Constants.HAS_ANY_ROLE)
public ResponseEntity<AuthenticationResponse> loginUser(@RequestBody AuthenticationRequest request) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public void sendVerificationEmail(User user) {
mailMessage.setTo(user.getEmail());
mailMessage.setSubject("Email verification");
mailMessage.setText(
"Click on the link to verify your email: " + hostname + "v1/user/verify?token=" + token.getToken()
"Click on the link to verify your email: " + hostname + "verify?token=" + token.getToken()
);
javaMailSender.send(mailMessage);
}
Expand Down
40 changes: 33 additions & 7 deletions src/main/java/com/pecacm/backend/services/JwtService.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.pecacm.backend.services;

import com.pecacm.backend.exception.AcmException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;

Expand All @@ -28,28 +30,52 @@ public String generateToken(UserDetails userDetails) {
}

public boolean validateToken(String token, UserDetails userDetails) {
return extractUsername(token).equals(userDetails.getUsername()) && !isTokenExpired(token);
try {
return extractUsername(token).equals(userDetails.getUsername()) && !isTokenExpired(token);
} catch (Exception ex) {
throw new AcmException("Token is invalid", HttpStatus.BAD_REQUEST);
}
}

public boolean isTokenExpired(String token) {
return extractExpiration(token).before(new Date());
try {
return extractExpiration(token).before(new Date());
} catch (Exception ex) {
throw new AcmException("Token is invalid", HttpStatus.BAD_REQUEST);
}
}

public Date extractExpiration(String token) {
return extractClaim(token, Claims::getExpiration);
try {
return extractClaim(token, Claims::getExpiration);
} catch (Exception ex) {
throw new AcmException("Token is invalid", HttpStatus.BAD_REQUEST);
}
}

public String extractUsername(String token) {
return extractClaim(token, Claims::getSubject);
try {
return extractClaim(token, Claims::getSubject);
} catch (Exception ex) {
throw new AcmException("Token is invalid", HttpStatus.BAD_REQUEST);
}
}

public <T> T extractClaim(String token, Function<Claims, T> claim) {
Claims claims = extractAllClaims(token);
return claim.apply(claims);
try {
Claims claims = extractAllClaims(token);
return claim.apply(claims);
} catch (Exception ex) {
throw new AcmException("Token is invalid", HttpStatus.BAD_REQUEST);
}
}

private Claims extractAllClaims(String token) {
return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
try {
return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
} catch (Exception ex) {
throw new AcmException("Token is invalid", HttpStatus.BAD_REQUEST);
}
}

}
26 changes: 16 additions & 10 deletions src/main/java/com/pecacm/backend/services/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ public UserService(UserRepository userRepository, VerificationTokenRepository ve
}

public User addUser(User user, PasswordEncoder passwordEncoder) {
if(userRepository.existsByEmailOrSid(user.getEmail(), user.getSid())) {
if (userRepository.existsByEmailOrSid(user.getEmail(), user.getSid())) {
throw new AcmException("User with given email or SID already exists", HttpStatus.BAD_REQUEST);
}
if(Strings.isBlank(user.getEmail()) || Strings.isBlank(user.getPassword()) || user.getSid() == null ||
Strings.isBlank(user.getBranch())
if (Strings.isBlank(user.getEmail()) || Strings.isBlank(user.getPassword()) || user.getSid() == null ||
Strings.isBlank(user.getBranch())
) {
throw new AcmException("One or more required fields are empty", HttpStatus.BAD_REQUEST);
}
Expand All @@ -56,7 +56,7 @@ public User loadUserByUsername(String email) {

public User verifyUser(UUID tokenId) {
VerificationToken token = verificationTokenRepository.findById(tokenId).orElseThrow(() ->
new AcmException("Verification token not found", HttpStatus.NOT_FOUND)
new AcmException("Verification token not found", HttpStatus.NOT_FOUND)
);
// TODO: check token expiration
User user = token.getUser();
Expand All @@ -69,9 +69,9 @@ public User verifyUser(UUID tokenId) {
public String changeRole(AssignRoleRequest assignRoleRequest) {
String userEmail = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
Role requesterRole = userRepository.findRoleByEmail(userEmail)
.orElseThrow(() ->
new AcmException(ErrorConstants.USER_NOT_FOUND, HttpStatus.NOT_FOUND)
);
.orElseThrow(() ->
new AcmException(ErrorConstants.USER_NOT_FOUND, HttpStatus.NOT_FOUND)
);

Role requestUserRole = userRepository.findRoleByEmail(assignRoleRequest.getEmail())
.orElseThrow(() ->
Expand All @@ -82,22 +82,28 @@ public String changeRole(AssignRoleRequest assignRoleRequest) {
Boolean isUserAuthorizedToChangeRole = requesterRole.equals(Role.Core) || requesterRole.equals(Role.Admin);
Boolean isRequestUserRoleLessThanRequester = requestUserRole.compareTo(requesterRole) < 0;

if (isNewRoleLessThanUserRole && isUserAuthorizedToChangeRole && isRequestUserRoleLessThanRequester)
{
if (isNewRoleLessThanUserRole && isUserAuthorizedToChangeRole && isRequestUserRoleLessThanRequester) {
userRepository.updateRoleByEmail(assignRoleRequest.getEmail(), assignRoleRequest.getNewRole());
return Constants.UPDATE_SUCCESS;
}

throw new AcmException(ErrorConstants.USER_UNAUTHORIZED, HttpStatus.UNAUTHORIZED);
}

public User getUserById(Integer userId){
public User getUserById(Integer userId) {
return userRepository.findById(userId)
.orElseThrow(() ->
new AcmException(ErrorConstants.USER_NOT_FOUND, HttpStatus.NOT_FOUND)
);
}

public User getUserByEmail(String email) {
return userRepository.findByEmail(email)
.orElseThrow(() ->
new AcmException(ErrorConstants.USER_NOT_FOUND, HttpStatus.NOT_FOUND)
);
}

public Long getRank(Integer score) {
return userRepository.countByXpGreaterThan(score) + 1;
}
Expand Down
7 changes: 6 additions & 1 deletion src/main/resources/application-local.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
server:
port: 8080
spring:
datasource:
url: jdbc:postgresql://localhost:5432/acm
Expand All @@ -23,4 +25,7 @@ spring:
smtp:
auth: true
starttls:
enable: true
enable: true
verify:
base:
frontend: http://localhost:3000/
2 changes: 1 addition & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,4 @@ jwt:
secret: nyanpasu
verify:
base:
frontend: http://localhost:8080/
frontend: https://pecacm.vercel.app/

0 comments on commit b7e6b2a

Please sign in to comment.