I have the following controller:
RestApiController.java
package com.spring.ocr.rest.restconsume.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriComponentsBuilder;
import com.spring.ocr.rest.restconsume.model.User;
import com.spring.ocr.rest.restconsume.service.UserService;
import com.spring.ocr.rest.restconsume.util.CustomErrorType;
#RestController
#RequestMapping("/api")
public class RestApiController {
#Autowired
UserService userService;
#RequestMapping(method = RequestMethod.GET, value = "/user/")
public ResponseEntity<List<User>> listAllUsers() {
final List<User> users = userService.findAllUsers();
if(users.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<List<User>>(users, HttpStatus.OK);
}
#RequestMapping(method = RequestMethod.GET, value = "/user/{id}")
public ResponseEntity<?> getUser(#PathVariable("id") long id) {
final User user = userService.findUserById(id);
if(user == null) {
return new ResponseEntity<>(new CustomErrorType(String.format("User with id %s not found", id)), HttpStatus.NOT_FOUND);
}
return new ResponseEntity<User>(user, HttpStatus.OK);
}
#RequestMapping(method = RequestMethod.POST, value = "/user/")
public ResponseEntity<?> createUser(#RequestBody User user, UriComponentsBuilder ucBuilder) {
if(userService.doesUserExist(user)) {
return new ResponseEntity<>(new CustomErrorType(String.format("Unable to create, user %s already exists", user.getName())), HttpStatus.CONFLICT);
}
userService.createUser(user);
final HttpHeaders headers = new HttpHeaders();
headers.setLocation(ucBuilder.path("/api/user/{id}").buildAndExpand(user.getId()).toUri());
return new ResponseEntity<String>(headers, HttpStatus.CREATED);
}
#RequestMapping(method = RequestMethod.PUT, value = "/user/{id}")
public ResponseEntity<?> updateUser(#PathVariable("id") long id,#RequestBody User user) {
User currentUser = userService.findUserById(id);
if(currentUser == null) {
return new ResponseEntity<>(new CustomErrorType(String.format("Unable to create update, User with id %s not found", user.getId())), HttpStatus.NOT_FOUND);
}
currentUser.setName(user.getName());
currentUser.setAge(user.getAge());
currentUser.setSalary(user.getSalary());
userService.updateUser(currentUser);
return new ResponseEntity<User>(currentUser, HttpStatus.OK);
}
#RequestMapping(method = RequestMethod.DELETE, value = "/user/{id}")
public ResponseEntity<?> deleteUser(#PathVariable("id") long id) {
User user = userService.findUserById(id);
if(user == null) {
return new ResponseEntity<>(new CustomErrorType(String.format("Unable to delete user, user with id %s not found", id)), HttpStatus.NOT_FOUND);
}
userService.deleteUserById(id);
return new ResponseEntity<User>(HttpStatus.NO_CONTENT);
}
#RequestMapping(method = RequestMethod.DELETE, value = "/user/")
public ResponseEntity<User> deleteAllUsers() {
userService.deleteAllUsers();
return new ResponseEntity<User>(HttpStatus.NO_CONTENT);
}
}
And I've set up a test of the web layer using mockMvc, with the user service bean mocked out as is standard:
RestApiControllerUnitTest.java
package com.spring.ocr.rest.restconsume.controller;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.ArrayList;
import java.util.List;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.spring.ocr.rest.restconsume.model.User;
import com.spring.ocr.rest.restconsume.service.UserService;
#RunWith(SpringRunner.class)
#WebMvcTest(RestApiController.class)
public class RestApiControllerUnitTest {
#Autowired
private MockMvc mockMvc;
#MockBean
UserService userService;
#Autowired
ObjectMapper objectMapper;
private final List<User> dummyUserList = getDummyUserList();
private final User dummyUser = new User((long)1, "Dave", (short)30, (double)30000);
private final User dummyUpdatedUser = new User((long)1, "David", (short)31, (double)35000);
#Test
public void test_listAllUsers_userListSizeIs4_returnsListSizeOf4AndOkStatus() throws Exception {
when(userService.findAllUsers()).thenReturn(dummyUserList);
this.mockMvc.perform(get("/api/user/"))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(4)));
}
#Test
public void test_listAllUsers_userListIsEmpty_returnsNoContentStatus() throws Exception {
when(userService.findAllUsers()).thenReturn(new ArrayList<User>());
this.mockMvc.perform(get("/api/user/"))
.andDo(print())
.andExpect(status().isNoContent());
}
#Test
public void test_getUser_userExists_returnsUser() throws Exception {
when(userService.findUserById(dummyUser.getId())).thenReturn(dummyUser);
this.mockMvc.perform(get("/api/user/" + dummyUser.getId()))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.id",is((int)dummyUser.getId())))
.andExpect(jsonPath("$.name", is(dummyUser.getName())))
.andExpect(jsonPath("$.age", is((int)dummyUser.getAge())))
.andExpect(jsonPath("$.salary", is(dummyUser.getSalary())));
}
#Test
public void test_getUser_userDoesntExist_returnsNotFoundStatusAndCustomErrorString() throws Exception {
when(userService.findUserById(dummyUser.getId())).thenReturn(null);
this.mockMvc.perform(get("/api/user/"+dummyUser.getId()))
.andDo(print())
.andExpect(status().isNotFound())
.andExpect(content().string(containsString("User with id 1 not found")));
}
#Test
public void test_createUser_userDoesNotExist_userCreated() throws Exception {
final String dummyUserJson = objectMapper.writeValueAsString(dummyUser);
when(userService.doesUserExist(dummyUser)).thenReturn(false);
MvcResult result = this.mockMvc.perform(post("/api/user/")
.contentType(MediaType.APPLICATION_JSON)
.content(dummyUserJson))
.andDo(print())
.andExpect(status().isCreated())
.andReturn();
final String header = result.getResponse().getHeader("Location");
assertThat(header, is("http://localhost/api/user/1"));
}
#Test
public void test_createUser_userExists_returnsNotFoundStatusAndCustomErrorMessage() throws Exception {
final String dummyUserJson = objectMapper.writeValueAsString(dummyUser);
final String expectedContent = String.format("Unable to create, user %s already exists", dummyUser.getName());
when(userService.doesUserExist(anyObject())).thenReturn(true);
this.mockMvc.perform(post("/api/user/")
.contentType(MediaType.APPLICATION_JSON)
.content(dummyUserJson))
.andDo(print())
.andExpect(status().isConflict())
.andExpect(jsonPath("$.errorMessage", is(expectedContent)));
}
#Test
public void test_updateUser_userExists_returnsOkStatusAndUpdatedUser() throws Exception {
final String dummyUpdatedUserJson = objectMapper.writeValueAsString(dummyUpdatedUser);
when(userService.findUserById(dummyUser.getId())).thenReturn(dummyUser);
doNothing().when(userService).updateUser(dummyUser);
this.mockMvc.perform(put("api/user/" + dummyUser.getId())
.contentType(MediaType.APPLICATION_JSON)
.content(dummyUpdatedUserJson))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.age", is(dummyUpdatedUser.getAge())))
.andExpect(jsonPath("$.name", is(dummyUpdatedUser.getName())))
.andExpect(jsonPath("$.salary", is(dummyUpdatedUser.getSalary())));
}
#Test
public void test_deleteUser_userExists_returnNoContentStatus() throws Exception {
when(userService.findUserById(dummyUser.getId())).thenReturn(dummyUser);
this.mockMvc.perform(delete("api/user/" + dummyUser.getId()))
.andDo(print())
.andExpect(status().isNotFound());
}
#Test
public void test_deleteUser_userDoesntExist_returnsNotFoundStatusAndCustomErrorMessage () throws Exception {
when(userService.findUserById(dummyUser.getId())).thenReturn(null);
final String expectedContent = String.format("Unable to create update, User with id %s not found", dummyUser.getName());
this.mockMvc.perform(delete("api/user/"+dummyUser.getId()))
.andDo(print())
.andExpect(status().isNotFound())
.andExpect(jsonPath("$.errorMessage", is(expectedContent)));
}
#Test
public void test_deleteAllUsers_usersListPopulated_returnNoContentStatus() throws Exception {
this.mockMvc.perform(delete("api/user/").contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isNotFound());
}
private List<User> getDummyUserList() {
final List<User> dummyUserList = new ArrayList<>();
dummyUserList.add(new User((long)1, "Dave", (short)30, (double)30000));
dummyUserList.add(new User((long)2, "Jess", (short)20, (double)20000));
dummyUserList.add(new User((long)3, "Mike", (short)40, (double)40000));
dummyUserList.add(new User((long)4, "Molly", (short)50, (double)50000));
return dummyUserList;
}
}
The test test_updateUser_userExists_returnsOkStatusAndUpdatedUser is returning a 404 rather than a 200 status and test_deleteUser_userDoesntExist_returnsNotFoundStatusAndCustomErrorMessage is not returning the error message in the body, which alludes to the 404 not being a "genuine" 404(its not returned because the correct response is coming back, its returning it for some other reason). Im also thinking that some of the other 404 statuses may be returned under the same context.
Issue was due to missing "/" on the controller methods used in the failing tests.
Related
When I run the SpringBoot REST API it works fine, authentication is implemented properly and everything is successful, however, when I try to run any of my unit tests I am getting the following error:
APPLICATION FAILED TO START
Description:
Parameter 0 of constructor in com.out.e.config.ApplicationSecurityConfig required a bean of type 'com.out.e.dao.auth.UserRepository' that could not be found.
Action:
Consider defining a bean of type 'com.out.e.dao.auth.UserRepository' in your configuration.
I have no idea what to do as it seems nonsensical to me that it would function correctly when running properly but not when being tested?
Security Config:
import com.out.e.dao.auth.UserRepository;
import com.out.e.filter.JwtTokenFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {
private final UserRepository userRepository;
private final JwtTokenFilter jwtTokenFilter;
public ApplicationSecurityConfig(final UserRepository userRepository, final JwtTokenFilter jwtTokenFilter) {
this.userRepository = userRepository;
this.jwtTokenFilter = jwtTokenFilter;
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(username -> userRepository.findByEmail(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found with email: " + username))
);
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(final HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable();
httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
httpSecurity.exceptionHandling().authenticationEntryPoint(
(request, response, authException) -> {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
authException.getMessage());
}
);
httpSecurity.authorizeRequests()
.antMatchers("/api/v1/auth/**").permitAll()
.anyRequest().authenticated();
httpSecurity.addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class);
httpSecurity.cors();
}
}
Token filter:
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
#Component
public class JwtTokenFilter extends OncePerRequestFilter {
private final JwtTokenUtil jwtTokenUtil;
public JwtTokenFilter(final JwtTokenUtil jwtTokenUtil) {
this.jwtTokenUtil = jwtTokenUtil;
}
#Override
protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, final FilterChain filterChain) throws ServletException, IOException {
if (!hasAuthorisationHeader(request)) {
filterChain.doFilter(request, response);
return;
}
String accessToken = getAccessToken(request);
if (!jwtTokenUtil.verifyAccessToken(accessToken)) {
filterChain.doFilter(request, response);
return;
}
setAuthenticationContext(accessToken, request);
filterChain.doFilter(request, response);
}
private void setAuthenticationContext(String accessToken, HttpServletRequest request) {
UserDetails userDetails = getUserDetails(accessToken);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, null);
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
private UserDetails getUserDetails(String accessToken) {
User userDetails = new User();
//Subject was split into userId and email by a comma so split the comma.
String[] subjects = jwtTokenUtil.getSubject(accessToken).split(",");
userDetails.setUserID(Long.valueOf(subjects[0]));
userDetails.setEmail(subjects[1]);
return userDetails;
}
private boolean hasAuthorisationHeader(HttpServletRequest httpServletRequest) {
String authorizationHeader = httpServletRequest.getHeader("Authorization");
if (ObjectUtils.isEmpty(authorizationHeader) || !authorizationHeader.startsWith("Bearer")) {
return false;
}
return true;
}
private String getAccessToken(HttpServletRequest httpServletRequest) {
String authorizationHeader = httpServletRequest.getHeader("Authorization");
String accessToken = authorizationHeader.split(" ")[1].trim();
System.out.println("Access token: " + accessToken);
return accessToken;
}
}
JWT token util:
import com.out.e.model.auth.User;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.SignatureException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Date;
#Component
public class JwtTokenUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(JwtTokenUtil.class);
//24Hours
private static final long EXPIRATION_DURATION = 24 * 60 * 60 * 1000;
#Value("${application.jwt.secretKey}")
private String secretKey;
public String generateAccessToken(User user) {
return Jwts.builder()
.setSubject(user.getUserID() + "," + user.getEmail())
.setIssuer("e")
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_DURATION))
.signWith(SignatureAlgorithm.HS512, secretKey)
.compact();
}
public boolean verifyAccessToken(String accessToken) {
try {
Jwts.parser().setSigningKey(secretKey).parseClaimsJws(accessToken);
return true;
} catch (ExpiredJwtException e) {
LOGGER.error("JWT Access token is expired.", e);
} catch (IllegalArgumentException e) {
LOGGER.error("JWT Access token is null or empty.", e);
} catch (UnsupportedJwtException e) {
LOGGER.error("JWT Access token is not supported.", e);
} catch (SignatureException e) {
LOGGER.error("Failure occurred while during signature process.", e);
}
return false;
}
public String getSubject(String accessToken) {
return parseClaims(accessToken).getSubject();
}
private Claims parseClaims(String accessToken) {
return Jwts.parserBuilder()
.setSigningKey(secretKey)
.build()
.parseClaimsJws(accessToken)
.getBody();
}
}
Repositroy:
import com.out.e.model.auth.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
import java.util.Optional;
public interface UserRepository extends JpaRepository<User, Long> {
/**
* Finds a user by email.
* #param email email.
* #return the user.
*/
Optional<User> findByEmail(final String email);
}
An example test class just in case:
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.doReturn;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
#AutoConfigureMockMvc
#WebMvcTest(controllers = AuthController.class)
public class AuthControllerTests {
#Autowired
private MockMvc mockMvc;
#Autowired
private ObjectMapper objectMapper;
#MockBean
private AuthService authService;
#MockBean
private UserService userService;
#Test
public void givenAUserDoesNotExistSignUpSuccessfully() throws Exception {
SignUpRequest signUpRequest = new SignUpRequest("tim#outlook.com", "Password-1", "Tim", "Nook", "London", 3000);
MsgResponse msgResponse = new MsgResponse("A new user has been successfully registered.");
doReturn(msgResponse).when(authService).signUpUser(signUpRequest);
String json = objectMapper.writeValueAsString(signUpRequest);
MvcResult mvcResult = mockMvc.perform(post("/api/v1/auth/login")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(status().isOk())
.andReturn();
String response = mvcResult.getResponse().getContentAsString();
assertEquals("A new user has been successfully registered.", response);
}
}
Any help would be greatly appreciated, thanks!
Edit: Add error full:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'applicationSecurityConfig' defined in file [H:\classes\java\main\com\out\e\config\ApplicationSecurityConfig.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.out.e.dao.auth.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
' Hello,
I have 2 problems with this code now.
In auth Controller, the JWT token generator is empty just showing this {}. It should show
{"username ": "string " , "password" : "string" }
Once is registered through auth controller and checked in Database in Role it is generating a row and id =0 and name= null but it suppose to assign either Normal/Admin right. Also when I try to register 2nd time it gets an error as Internal server error, please help me with this. '
package com.mohammedkhadeer.blog.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.mohammedkhadeer.blog.exceptions.ApiException;
import com.mohammedkhadeer.blog.payloads.JwtAuthRequest;
import com.mohammedkhadeer.blog.payloads.JwtAuthResponse;
import com.mohammedkhadeer.blog.payloads.UserDto;
import com.mohammedkhadeer.blog.security.JwtTokenHelper;
import com.mohammedkhadeer.blog.services.UserService;
#RestController
#RequestMapping("/api/v1/auth/")
public class AuthController {
#Autowired
private JwtTokenHelper jwtTokenHelper;
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private UserService userService;
#PostMapping("/login")
public ResponseEntity<JwtAuthResponse> createToken(#RequestBody JwtAuthRequest request) throws Exception {
this.authenticate(request.getUsername(), request.getPassword());
UserDetails userDetails = this.userDetailsService.loadUserByUsername(request.getUsername());
String token = this.jwtTokenHelper.generateToken(userDetails);
JwtAuthResponse response = new JwtAuthResponse();
response.setToken(token);
return new ResponseEntity<JwtAuthResponse>(response, HttpStatus.OK);
}
private void authenticate(String username, String password) throws Exception {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username,
password);
try {
this.authenticationManager.authenticate(authenticationToken);
} catch (BadCredentialsException e) {
System.out.println("Invalid Detials !!");
throw new ApiException("Invalid username or password !!");
}
}
// register new user api
#PostMapping("/register")
public ResponseEntity<UserDto> registerUser(#RequestBody UserDto userDto) {
UserDto registeredUser = this.userService.registerNewUser(userDto);
return new ResponseEntity<UserDto>(registeredUser, HttpStatus.CREATED);
}
}
package com.mohammedkhadeer.blog.security;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
#Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private JwtTokenHelper jwtTokenHelper;
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// 1. get token
String requestToken = request.getHeader("Authorization");
// Bearer 2352523sdgsg
System.out.println(requestToken);
String username = null;
String token = null;
if (requestToken != null && requestToken.startsWith("Bearer")) {
token = requestToken.substring(7);
try {
username = this.jwtTokenHelper.getUsernameFromToken(token);
} catch (IllegalArgumentException e) {
System.out.println("Unable to get Jwt token");
} catch (ExpiredJwtException e) {
System.out.println("Jwt token has expired");
} catch (MalformedJwtException e) {
System.out.println("invalid jwt");
}
} else {
System.out.println("Jwt token does not begin with Bearer");
}
// once we get the token , now validate
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (this.jwtTokenHelper.validateToken(token, userDetails)) {
// shi chal rha hai
// authentication karna hai
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
} else {
System.out.println("Invalid jwt token");
}
} else {
System.out.println("username is null or context is not null");
}
filterChain.doFilter(request, response);
}
}
package com.mohammedkhadeer.blog;
import java.util.List;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import com.mohammedkhadeer.blog.config.AppConstants;
import com.mohammedkhadeer.blog.entities.Role;
import com.mohammedkhadeer.blog.repositories.RoleRepo;
#SpringBootApplication
public class BlogAppApisApplication implements CommandLineRunner {
#Autowired
private PasswordEncoder passwordEncoder;
#Autowired
private RoleRepo roleRepo;
public static void main(String[] args) {
SpringApplication.run(BlogAppApisApplication.class, args);
}
#Bean
public ModelMapper modelMapper() {
return new ModelMapper();
}
#Override
public void run(String... args) throws Exception {
System.out.println(this.passwordEncoder.encode("xyz"));
try {
Role role = new Role();
role.setId(AppConstants.ADMIN_USER);
role.setName("ROLE_ADMIN");
Role role1 = new Role();
role1.setId(AppConstants.NORMAL_USER);
role1.setName("ROLE_NORMAL");
List<Role> roles = List.of(role, role1);
List<Role> result = this.roleRepo.saveAll(roles);
result.forEach(r -> {
System.out.println(r.getName());
});
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
I'm running unit tests with Spring Boot and Mockito and I'm testing RESTful services. When I try to test the GET method it works successfully but when I try to test the POST method it fails. What should I do to resolve this problem? Thanks in advance!
This is the code for the REST Controller:
package com.dgs.restfultesting.controller;
import java.net.URI;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import com.dgs.restfultesting.business.ItemBusinessService;
import com.dgs.restfultesting.model.Item;
#RestController
public class ItemController {
#Autowired
private ItemBusinessService businessService;
#GetMapping("/all-items-from-database")
public List<Item> retrieveAllItems() {
return businessService.retrieveAllItems();
}
#PostMapping("/items")
public Item addItem(#RequestBody Item item) {
Item savedItem = businessService.addAnItem(item);
return savedItem;
}
}
Business Layer:
package com.dgs.restfultesting.business;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.dgs.restfultesting.data.ItemRepository;
import com.dgs.restfultesting.model.Item;
#Component
public class ItemBusinessService {
#Autowired
private ItemRepository repository;
public Item retrieveHardcodedItem() {
return new Item(1, "Book", 10, 100);
}
public List<Item> retrieveAllItems() {
List<Item> items = repository.findAll();
for (Item item : items) {
item.setValue(item.getPrice() * item.getQuantity());
}
return items;
}
public Item addAnItem(Item item) {
return repository.save(item);
}
}
ItemControllerTest:
package com.dgs.restfultesting.controller;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.Arrays;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import com.dgs.restfultesting.business.ItemBusinessService;
import com.dgs.restfultesting.model.Item;
#RunWith(SpringRunner.class)
#WebMvcTest(ItemController.class)
public class ItemControllerTest {
#Autowired
private MockMvc mockMvc;
#MockBean
private ItemBusinessService businessService;
#Test
public void retrieveAllItems_basic() throws Exception {
when(businessService.retrieveAllItems()).thenReturn(
Arrays.asList(new Item(2, "iPhone", 1000, 10),
new Item(3, "Huawei", 500, 17)));
RequestBuilder request = MockMvcRequestBuilders
.get("/all-items-from-database")
.accept(MediaType.APPLICATION_JSON);
MvcResult result = mockMvc.perform(request)
.andExpect(status().isOk())
.andExpect(content().json("[{id:2, name:iPhone, price:1000}, {id:3, name:Huawei, price:500}]")) // This will return an array back, so this data should be within an array
.andReturn();
}
#Test
public void createItem() throws Exception {
RequestBuilder request = MockMvcRequestBuilders
.post("/items")
.accept(MediaType.APPLICATION_JSON)
.content("{\"id\":1,\"name\":\"Book\",\"price\":10,\"quantity\":100}")
.contentType(MediaType.APPLICATION_JSON);
MvcResult result = mockMvc.perform(request)
.andExpect(status().isCreated())
.andExpect(header().string("location", containsString("/item/")))
.andReturn();
}
}
There is no problem to test the retrieveAllItems_basic() method, but when I try to run a JUnit test for createItem() method, it doesn't work and I get this: java.lang.AssertionError: Status expected:<201> but was:<200>
And this is what I receive in the Console:
MockHttpServletRequest:
HTTP Method = POST
Request URI = /items
Parameters = {}
Headers = {Content-Type=[application/json], Accept=[application/json]}
Body = <no character encoding set>
Session Attrs = {}
Handler:
Type = com.dgs.restfultesting.controller.ItemController
Method = public com.dgs.restfultesting.model.Item com.dgs.restfultesting.controller.ItemController.addItem(com.dgs.restfultesting.model.Item)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = {}
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
2018-10-07 17:53:51.457 INFO 55300 --- [ Thread-3] o.s.w.c.s.GenericWebApplicationContext : Closing org.springframework.web.context.support.GenericWebApplicationContext#71075444: startup date [Sun Oct 07 17:53:48 EEST 2018]; root of context hierarchy
Update -----------------------------
I try to set the location like this: item/id.
This is the code for the controller:
#PostMapping("/items")
public ResponseEntity<Object> addItem(#RequestBody Item item) {
Item savedItem = businessService.addAnItem(item);
HttpHeaders httpHeaders = new HttpHeaders();
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.newInstance();
UriComponents uriComponents =
uriComponentsBuilder.path("/item/{id}").buildAndExpand(savedItem.getId());
httpHeaders.setLocation(uriComponents.toUri());
return new ResponseEntity<>(savedItem, httpHeaders, HttpStatus.CREATED);
}
This is the code for test:
#Test
public void createItem() throws Exception {
RequestBuilder request = MockMvcRequestBuilders
.post("/items")
.accept(MediaType.APPLICATION_JSON)
.content("{\"id\":1,\"name\":\"Book\",\"price\":10,\"quantity\":100}")
.contentType(MediaType.APPLICATION_JSON);
MvcResult result = mockMvc.perform(request)
.andExpect(status().isCreated())
.andExpect(header().string("location", containsString("/item/1")))
.andReturn();
}
When I run the JUnit test for createItem() method I get this error: org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
Return 201 from your controller: As your assertion test is expecting 201 by using created status but your controller is returning 200(OK).
#PostMapping("/items")
public ResponseEntity<?> addItem(#RequestBody Item item) {
Item savedItem = itemBusinessService.addAnItem(item);
return new ResponseEntity<>(savedItem, HttpStatus.CREATED);
}
Or modify your test to check status OK(200). Update your test if you don't want to assert "location".
#Test
public void createItem() throws Exception {
RequestBuilder request = MockMvcRequestBuilders
.post("/items")
.accept(MediaType.APPLICATION_JSON)
.content("{\"id\":1,\"name\":\"Book\",\"price\":10,\"quantity\":100}")
.contentType(MediaType.APPLICATION_JSON);
MvcResult result = mockMvc.perform(request)
.andExpect(status().isOk()).andReturn();
}
UPDATE--Allow location header in response
If you want "location" to return from header, then modify your controller and test case below to check location too in header.
STEP 1: In your controller's add item method, add location uri and return.
#PostMapping("/items")
public ResponseEntity<?> addItem(#RequestBody Item item) {
Item savedItem = businessService.addAnItem(item);
HttpHeaders httpHeaders = new HttpHeaders();
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.newInstance();
UriComponents uriComponents =
uriComponentsBuilder.path("/item/").buildAndExpand("/item/");
httpHeaders.setLocation(uriComponents.toUri());
return new ResponseEntity<>(savedItem, httpHeaders, HttpStatus.CREATED);
}
STEP 2: Now your test will assert "location" as you expected.
#Test
public void createItem() throws Exception {
RequestBuilder request = MockMvcRequestBuilders
.post("/items")
.accept(MediaType.APPLICATION_JSON)
.content("{\"id\":1,\"name\":\"Book\",\"price\":10,\"quantity\":100}")
.contentType(MediaType.APPLICATION_JSON);
MvcResult result = mockMvc.perform(request)
.andExpect(status().isCreated())
.andExpect(header().string("location", containsString("/item/")))
.andReturn();
}
first of all I do not see in your createItem test the mock program part let's say
Item item = new Item();
Item newItem = new Item();
when(businessService.addAnItem(item)).thenReturn(newItem);
and in your controller I do not see the Location header. Probably a code like below should be better:
#PostMapping("/items")
public ResponseEntity<?> addItem(#RequestBody Item item) {
Item savedItem = itemBusinessService.addAnItem(item);
return ResponseEntity.created(UriComponentsBuilder.fromHttpUrl("http://yourserver/item"));
}
I hope that this can help you
I am trying to setup authentication using JWT using Angular as my front end and Spring as backend. I have the following AuthenticationFilter class for setting up JWT filter:
package com.atlas.config;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureException;
public class AuthenticationFilter implements Filter {
#Override
public void destroy() {
// TODO Auto-generated method stub
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//System.out.println("filter");
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String authHeader = ((HttpServletRequest) request).getHeader("Authorizatoin");
//System.out.println(authHeader);
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
throw new ServletException("Missing or invalid Authorization header.");
}
String token = authHeader.substring(7);
try
{
//security key needs to be changed before deployment
Claims claims = Jwts.parser().setSigningKey("feb1atlaskey").parseClaimsJws(token).getBody();
req.setAttribute("claims", claims);
}
catch(SignatureException e)
{
throw new ServletException("Not a valid token");
}
chain.doFilter(req,res);
}
#Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
This is my UserController class where the login check and setting Auth header happens:
package com.atlas.controller;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.atlas.entity.User;
import com.atlas.service.UserService;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
#RestController
#RequestMapping("/users")
public class UserController {
private final Map<String, List<String>> userDb = new HashMap<>();
public UserController() {
userDb.put("tom", Arrays.asList("user"));
userDb.put("sally", Arrays.asList("user", "admin"));
}
#RequestMapping(value = "login", method = RequestMethod.POST)
public LoginResponse login(#RequestBody final UserLogin login)
throws ServletException {
System.out.println("In user controller");
if (login.name == null || !userDb.containsKey(login.name)) {
throw new ServletException("Invalid login");
}
return new LoginResponse(Jwts.builder().setSubject(login.name)
.claim("roles", userDb.get(login.name)).setIssuedAt(new Date())
.signWith(SignatureAlgorithm.HS256, "secretkey").compact());
}
#Autowired
private UserService userService;
#RequestMapping(method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE,
consumes = MediaType.APPLICATION_JSON_VALUE)
public void addUser(#RequestBody User u) {
this.userService.addUser(u);
}
private static class UserLogin {
public String name;
public String password;
}
private static class LoginResponse {
public String token;
public LoginResponse(final String token) {
this.token = token;
}
}
}
Now, when I do a login using simple form and make a POST request using Angular, its not reaching UserController. Its hitting the filter and throwing Servlet Exception as "Missing or invalid Authorization header".
I have also configured my app to add this filter in the chain as below:
package com.atlas.config;
import javax.servlet.Filter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class AppInit extends AbstractAnnotationConfigDispatcherServletInitializer{
#Override
protected Class<?>[] getRootConfigClasses() {
// TODO Auto-generated method stub
return new Class[]{AppConfig.class,SwaggerConfig.class,AuthenticationFilter.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
// TODO Auto-generated method stub
return null;
}
#Override
protected String[] getServletMappings() {
// TODO Auto-generated method stub
return new String[] {"/api/*"};
}
#Override
protected Filter[] getServletFilters() {
Filter [] singleton = { new CORSFilter(), new AuthenticationFilter() };
return singleton;
}
}
Am I missing some config here or making some terrible mistake.
Any help much appreciated!
The "Authorization" header is mispelled:
Replace from:
String authHeader = ((HttpServletRequest) request).getHeader("Authorizatoin");
To:
String authHeader = ((HttpServletRequest) request).getHeader("Authorization");
You may consider using Spring Framework constants for http headers to avoid such issues:
String authHeader = ((HttpServletRequest) request).getHeader(org.springframework.http.HttpHeaders.AUTHORIZATION);
I am working on a company internal web based application which need to use Spring Boot. The user will authenticate using windows credentials.
The application need to have a user profile page which will fetch the user details like below:
Display Name |
Email |
authorities |
Workphoto
Until now I am able to fetch the first three details and trying to fetch to workphoto from active directory which needs to be displayed on the user profile page.
The "InetOrgPerson" does not have the function to getWorkPhoto from user details populated from ldap. Pointers to some existing solutions would be much appreciated.
Below is my code:
1. SecurityConfiguration.java
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.event.LoggerListener;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider;
import org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
#Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private static Log logger = LogFactory.getLog(SecurityConfiguration.class);
#Override
public void configure(WebSecurity web) throws Exception {
logger.info("inside1");
web.ignoring().antMatchers("/resources/**", "/static/**","/sb-admin/**");
}
#Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
logger.info("inside2");
httpSecurity.authorizeRequests().antMatchers("/resources/static/**/*").permitAll()
.anyRequest().authenticated();
httpSecurity.formLogin().failureUrl("/login?error").loginPage("/login")
.permitAll().defaultSuccessUrl("/").permitAll().and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login").permitAll();
}
#Bean
public LoggerListener loggerListener() {
return new LoggerListener();
}
#Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
// auth.inMemoryAuthentication().withUser("user").password("password").roles("USER");
auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider());
}
#Bean
public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider(
"XXXXX.COM", "ldap://XXXXcorp.com:389/",
"OU=Users,DC=XXXX,DC=com");
provider.setConvertSubErrorCodesToExceptions(true);
provider.setUseAuthenticationRequestCredentials(true);
provider.setAuthoritiesMapper(new SimpleAuthorityMapper());
provider.setSearchFilter("(&(objectCategory=person)(objectClass=user)(|(sAMAccountName={0})(userPrincipalName={0})))");
provider.setUseAuthenticationRequestCredentials(true);
logger.info("provider ::: " + provider);
provider.setUserDetailsContextMapper(inetOrgPersonContextMapper());
return provider;
}
#Bean
public InetOrgPersonContextMapper inetOrgPersonContextMapper() {
return new InetOrgPersonContextMapper();
}
}
Below is controller code:
1. Controller.java
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.ldap.userdetails.InetOrgPerson;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import com.mongodb.gridfs.GridFSDBFile;
#RestController
public class MainController {
private static Log logger = LogFactory.getLog(MainController.class);
private String username;
/*
* #RequestMapping(value = "/home", method = RequestMethod.GET) public
* String home() { return "site.homepage"; }
*/
#RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView printWelcome(final ModelMap model) {
logger.info("inside printWelcome");
return new ModelAndView("site.homepage", "model", model);
}
#RequestMapping(value = "/user-profile", method = RequestMethod.GET)
public ModelAndView showUserProfile(final ModelMap model) {
logger.info("inside showUserProfile");
Object principal = SecurityContextHolder.getContext()
.getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
this.username = ((UserDetails) principal).getUsername();
} else {
this.username = principal.toString();
}
model.addAttribute("username", username);
model.addAttribute("roomNumber",
((InetOrgPerson) principal).getRoomNumber());
model.addAttribute("emailAddress",
((InetOrgPerson) principal).getMail());
model.addAttribute("displayName",
((InetOrgPerson) principal).getDisplayName());
model.addAttribute("employeeNumber",
((InetOrgPerson) principal).getEmployeeNumber());
model.addAttribute("authorities", ((InetOrgPerson) principal)
.getAuthorities().toString());
model.addAttribute("otherDetails", ((InetOrgPerson) principal).getUid());
return new ModelAndView("site.userprofile", "model", model);
}
#RequestMapping(value = "/login", method = RequestMethod.GET)
public ModelAndView login(final ModelMap model) {
logger.info("inside login");
ModelAndView modelview = new ModelAndView();
modelview.setViewName("site.login");
return modelview;
}
}