View Javadoc
1   package net.avcompris.examples.users3.web;
2   
3   import static com.google.common.base.Preconditions.checkNotNull;
4   import static net.avcompris.examples.users3.web.Application.API;
5   import static org.springframework.web.bind.annotation.RequestMethod.GET;
6   import static org.springframework.web.bind.annotation.RequestMethod.POST;
7   
8   import javax.servlet.http.HttpServletRequest;
9   import javax.servlet.http.HttpServletResponse;
10  
11  import org.springframework.beans.factory.annotation.Autowired;
12  import org.springframework.http.HttpHeaders;
13  import org.springframework.http.HttpStatus;
14  import org.springframework.http.ResponseEntity;
15  import org.springframework.web.bind.annotation.CookieValue;
16  import org.springframework.web.bind.annotation.PathVariable;
17  import org.springframework.web.bind.annotation.RequestBody;
18  import org.springframework.web.bind.annotation.RequestHeader;
19  import org.springframework.web.bind.annotation.RequestMapping;
20  import org.springframework.web.bind.annotation.RequestParam;
21  import org.springframework.web.bind.annotation.RestController;
22  
23  import net.avcompris.commons3.api.EntitiesQueryRaw;
24  import net.avcompris.commons3.api.User;
25  import net.avcompris.commons3.api.UserSession;
26  import net.avcompris.commons3.api.UserSessions;
27  import net.avcompris.commons3.api.UserSessionsQuery;
28  import net.avcompris.commons3.api.exception.ServiceException;
29  import net.avcompris.commons3.api.exception.UnauthenticatedException;
30  import net.avcompris.commons3.client.SessionPropagator;
31  import net.avcompris.commons3.core.AuthService;
32  import net.avcompris.commons3.core.CorrelationService;
33  import net.avcompris.commons3.utils.Clock;
34  import net.avcompris.examples.users3.api.Credentials;
35  import net.avcompris.examples.users3.api.UserInfo;
36  import net.avcompris.examples.users3.query.UserFiltering;
37  
38  @RestController
39  public final class AuthController extends MyAbstractController {
40  
41  	private final AuthService authService;
42  
43  	@Autowired
44  	public AuthController(final CorrelationService correlationService, final AuthService authService,
45  			final SessionPropagator sessionPropagator, final Clock clock) {
46  
47  		super(correlationService, sessionPropagator, clock);
48  
49  		this.authService = checkNotNull(authService, "authService");
50  	}
51  
52  	@RequestMapping(value = API + "/auth", method = POST)
53  	public ResponseEntity<UserSession> authenticateUser(final HttpServletRequest request, //
54  			final HttpServletResponse response, //
55  			@RequestBody(required = true) final Credentials credentials //
56  	) throws ServiceException {
57  
58  		return wrapNonAuthenticated(request, (correlationId) -> {
59  
60  			final String username = credentials.getUsername();
61  			final String password = credentials.getPassword();
62  
63  			final UserSession userSession = authService.authenticate(correlationId, username, password);
64  
65  			if (userSession != null) {
66  				setUserSessionCookie(response, userSession.getUserSessionId());
67  			}
68  
69  			return ResponseEntity.status(userSession != null //
70  					? HttpStatus.OK //
71  					: HttpStatus.NO_CONTENT) //
72  					.body(userSession);
73  		});
74  	}
75  
76  	@RequestMapping(value = API + "/logout", method = { GET, POST })
77  	public ResponseEntity<UserSession> logout(final HttpServletRequest request, //
78  			final HttpServletResponse response //
79  	) throws ServiceException {
80  
81  		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
82  
83  			final Object userSessionId = request.getAttribute(USER_SESSION_ID_ATTRIBUTE_NAME);
84  
85  			if (userSessionId == null) {
86  
87  				throw new UnauthenticatedException();
88  			}
89  
90  			final UserSession userSession = authService.terminateMySession(correlationId, user,
91  					userSessionId.toString());
92  
93  			return ResponseEntity.status(HttpStatus.OK) //
94  					.body(userSession);
95  		});
96  	}
97  
98  	/**
99  	 * Return {@link User}, not {@link UserInfo}, because otherwise it cannot work
100 	 * with superadmin auth.
101 	 */
102 	@RequestMapping(value = API + "/auth", method = GET)
103 	public ResponseEntity<User> getAuthenticatedUser(final HttpServletRequest request, //
104 			@RequestHeader(required = false, name = HttpHeaders.AUTHORIZATION) final String authorizationHeader, //
105 			@CookieValue(required = false, value = "user_session_id") final String userSessionIdCookie,
106 			@RequestHeader(required = false, value = "user_session_id") final String userSessionIdHeader //
107 	) throws ServiceException {
108 
109 		return wrapNonAuthenticated(request, (correlationId) -> {
110 
111 			final String authorization = authorizationHeader;
112 
113 			final String userSessionId = userSessionIdHeader != null //
114 					? userSessionIdHeader //
115 					: userSessionIdCookie;
116 
117 			final User user = authService.getAuthenticatedUser(authorization, userSessionId);
118 
119 			if (user == null) {
120 
121 				return ResponseEntity.status(HttpStatus.NO_CONTENT) //
122 						.body(null);
123 			}
124 
125 			return ResponseEntity.status(HttpStatus.OK) //
126 					.body(user);
127 		});
128 	}
129 
130 	/**
131 	 * Return {@link User}, not {@link UserInfo}, because otherwise it cannot work
132 	 * with superadmin auth.
133 	 */
134 	@RequestMapping(value = API + "/active", method = POST)
135 	public ResponseEntity<User> setActive( //
136 			final HttpServletRequest request, //
137 			final HttpServletResponse response //
138 	) throws ServiceException {
139 
140 		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
141 
142 			authService.setLastActiveAt(correlationId, user);
143 
144 			return ResponseEntity.status(HttpStatus.OK) //
145 					.body(user);
146 		});
147 	}
148 
149 	@RequestMapping(value = API + "/sessions", method = GET)
150 	public ResponseEntity<UserSessions> getSessions(final HttpServletRequest request, //
151 			final HttpServletResponse response, //
152 			@RequestParam(name = "q", required = false) final String q, //
153 			@RequestParam(name = "sort", required = false) final String sort, //
154 			@RequestParam(name = "start", required = false) final Integer start, //
155 			@RequestParam(name = "limit", required = false) final Integer limit, //
156 			@RequestParam(name = "expand", required = false) final String expand //
157 	) throws ServiceException {
158 
159 		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
160 
161 			final UserSessionsQuery query = authService.validateUserSessionsQuery(correlationId, user, q, sort, start,
162 					limit, expand);
163 
164 			final UserSessions sessions = authService.getUserSessions(correlationId, user, query);
165 
166 			return ResponseEntity.status(HttpStatus.OK) //
167 					.body(sessions);
168 		});
169 	}
170 
171 	@RequestMapping(value = API + "/sessions", method = POST)
172 	public ResponseEntity<UserSessions> getSessions(final HttpServletRequest request, //
173 			final HttpServletResponse response, //
174 			@RequestBody(required = true) final EntitiesQueryRaw<UserFiltering, UserFiltering.Field> raw //
175 	) throws ServiceException {
176 
177 		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
178 
179 			final UserSessionsQuery query = authService.validateUserSessionsQuery(correlationId, user, raw.getQ(),
180 					raw.getSort(), raw.getStart(), raw.getLimit(), raw.getExpand());
181 
182 			final UserSessions sessions = authService.getUserSessions(correlationId, user, query);
183 
184 			return ResponseEntity.status(HttpStatus.OK) //
185 					.body(sessions);
186 		});
187 	}
188 
189 	@RequestMapping(value = API + "/sessions/{userSessionId}", method = GET)
190 	public ResponseEntity<UserSession> getUserSession(final HttpServletRequest request, //
191 			final HttpServletResponse response, //
192 			@PathVariable(name = "userSessionId", required = true) final String userSessionId //
193 	) throws ServiceException {
194 
195 		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
196 
197 			final UserSession userSession = authService.getUserSession(correlationId, user, userSessionId);
198 
199 			return ResponseEntity.status(HttpStatus.OK) //
200 					.body(userSession);
201 		});
202 	}
203 
204 	@RequestMapping(value = API + "/sessions/{userSessionId}/terminate", method = POST)
205 	public ResponseEntity<UserSession> terminateUserSession(final HttpServletRequest request, //
206 			final HttpServletResponse response, //
207 			@PathVariable(name = "userSessionId", required = true) final String userSessionId //
208 	) throws ServiceException {
209 
210 		return wrapAuthenticated(request, response, authService, (correlationId, user) -> {
211 
212 			final UserSession userSession = authService.terminateUserSession(correlationId, user, userSessionId);
213 
214 			return ResponseEntity.status(HttpStatus.OK) //
215 					.body(userSession);
216 		});
217 	}
218 }