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
100
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
132
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 }