blob: 79ba584c7198dddb8b3105cea9235caf6095051a [file] [log] [blame]
margaretha0866a532019-01-22 17:52:40 +01001package de.ids_mannheim.korap.web.controller;
2
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.HashSet;
6import java.util.Iterator;
7import java.util.List;
8import java.util.Locale;
9import java.util.Map;
10import java.util.Set;
11
12import javax.ws.rs.Consumes;
13import javax.ws.rs.DELETE;
14import javax.ws.rs.GET;
15import javax.ws.rs.POST;
16import javax.ws.rs.Path;
17import javax.ws.rs.Produces;
18import javax.ws.rs.QueryParam;
19import javax.ws.rs.core.Context;
20import javax.ws.rs.core.MediaType;
21import javax.ws.rs.core.Response;
22import javax.ws.rs.core.SecurityContext;
23import javax.ws.rs.core.UriInfo;
24
25import org.apache.logging.log4j.LogManager;
26import org.apache.logging.log4j.Logger;
27import org.springframework.beans.factory.annotation.Autowired;
28import org.springframework.stereotype.Controller;
29
30import com.fasterxml.jackson.databind.JsonNode;
31import com.sun.jersey.spi.container.ResourceFilters;
32
33import de.ids_mannheim.korap.authentication.AuthenticationManager;
34import de.ids_mannheim.korap.config.Attributes;
35import de.ids_mannheim.korap.config.Scopes;
36import de.ids_mannheim.korap.exceptions.KustvaktException;
37import de.ids_mannheim.korap.security.context.TokenContext;
38import de.ids_mannheim.korap.user.KorAPUser;
39import de.ids_mannheim.korap.user.User;
40import de.ids_mannheim.korap.user.UserDetails;
41import de.ids_mannheim.korap.user.UserQuery;
margaretha0bcde4c2019-01-23 19:08:51 +010042import de.ids_mannheim.korap.user.UserSettingProcessor;
margaretha0866a532019-01-22 17:52:40 +010043import de.ids_mannheim.korap.user.Userdata;
44import de.ids_mannheim.korap.utils.JsonUtils;
45import de.ids_mannheim.korap.utils.StringUtils;
46import de.ids_mannheim.korap.web.KustvaktResponseHandler;
47import de.ids_mannheim.korap.web.filter.APIVersionFilter;
48import de.ids_mannheim.korap.web.filter.AuthenticationFilter;
49import de.ids_mannheim.korap.web.filter.BlockingFilter;
50import de.ids_mannheim.korap.web.filter.DemoUserFilter;
51import de.ids_mannheim.korap.web.filter.PiwikFilter;
52
53/**
54 *
55 * @author hanl, margaretha
56 */
57@Controller
58@Path("{version}/shibboleth/user")
59@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
60@ResourceFilters({APIVersionFilter.class, PiwikFilter.class })
61public class ShibbolethUserController {
62
63 @Autowired
64 private KustvaktResponseHandler kustvaktResponseHandler;
65
66 private static Logger jlog = LogManager.getLogger(ShibbolethUserController.class);
67 @Autowired
68 private AuthenticationManager controller;
69
70 private @Context UriInfo info;
71
72 // EM: may be used for managing shib users
73 //todo: password update in special function? --> password reset only!
74 @POST
75 @Path("update")
76 @Consumes(MediaType.APPLICATION_JSON)
77 @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
78 BlockingFilter.class })
79 public Response updateAccount (@Context SecurityContext ctx, String json) {
80 TokenContext context = (TokenContext) ctx.getUserPrincipal();
81 try {
82 User user = controller.getUser(context.getUsername());
83
84 JsonNode node = JsonUtils.readTree(json);
85 KorAPUser ident = (KorAPUser) user;
86 KorAPUser values = User.UserFactory.toUser(json);
87 // user = controller
88 // .checkPasswordAllowance(ident, values.getPassword(),
89 // node.path("new_password").asText());
90 // controller.updateAccount(user);
91 }
92 catch (KustvaktException e) {
93 throw kustvaktResponseHandler.throwit(e);
94 }
95 return Response.ok().build();
96 }
97
98 // todo: refactor and make something out of if --> needs to give some sort of feedback!
99 @GET
100 @Path("info")
101 @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
102 BlockingFilter.class })
103 public Response getStatus (@Context SecurityContext context,
104 @QueryParam("scopes") String scopes) {
105 TokenContext ctx = (TokenContext) context.getUserPrincipal();
106 Scopes m;
107 try {
108 User user = controller.getUser(ctx.getUsername());
109 Userdata data = controller.getUserData(user, UserDetails.class);
110
111 Set<String> base_scope = StringUtils.toSet(scopes, " ");
112 if (scopes != null) base_scope.retainAll(StringUtils.toSet(scopes));
113 scopes = StringUtils.toString(base_scope);
114 m = Scopes.mapScopes(scopes, data);
115 return Response.ok(m.toEntity()).build();
116 }
117 catch (KustvaktException e) {
118 throw kustvaktResponseHandler.throwit(e);
119 }
120 }
121
122
123 @GET
124 @Path("settings")
125 @ResourceFilters({ AuthenticationFilter.class, DemoUserFilter.class,
126 PiwikFilter.class, BlockingFilter.class })
127 public Response getUserSettings (@Context SecurityContext context,
128 @Context Locale locale) {
129 TokenContext ctx = (TokenContext) context.getUserPrincipal();
130 String result;
131 try {
132 User user = controller.getUser(ctx.getUsername());
margaretha0bcde4c2019-01-23 19:08:51 +0100133 Userdata data = controller.getUserData(user, UserSettingProcessor.class);
margaretha0866a532019-01-22 17:52:40 +0100134 data.setField(Attributes.USERNAME, ctx.getUsername());
135 result = data.serialize();
136 }
137 catch (KustvaktException e) {
138 jlog.error("Exception encountered!", e);
139 throw kustvaktResponseHandler.throwit(e);
140 }
141 return Response.ok(result).build();
142 }
143
144
145 @Deprecated
146 @POST
147 @Path("settings")
148 @Consumes({ MediaType.APPLICATION_JSON })
149 @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
150 BlockingFilter.class })
151 public Response updateSettings (@Context SecurityContext context,
152 @Context Locale locale, Map settings) {
153 TokenContext ctx = (TokenContext) context.getUserPrincipal();
154
155 if (settings == null) return Response.notModified().build();
156
157 try {
158 User user = controller.getUser(ctx.getUsername());
159 if (User.UserFactory.isDemo(ctx.getUsername()))
160 return Response.notModified().build();
161
margaretha0bcde4c2019-01-23 19:08:51 +0100162 Userdata data = controller.getUserData(user, UserSettingProcessor.class);
margaretha0866a532019-01-22 17:52:40 +0100163 // todo: check setting only within the scope of user settings permissions; not foundry range. Latter is part of
164 // frontend which only displays available foundries and
165 // SecurityManager.findbyId(us.getDefaultConstfoundry(), user, Foundry.class);
166 // SecurityManager.findbyId(us.getDefaultLemmafoundry(), user, Foundry.class);
167 // SecurityManager.findbyId(us.getDefaultPOSfoundry(), user, Foundry.class);
168 // SecurityManager.findbyId(us.getDefaultRelfoundry(), user, Foundry.class);
margaretha0bcde4c2019-01-23 19:08:51 +0100169 Userdata new_data = new UserSettingProcessor(user.getId());
margaretha0866a532019-01-22 17:52:40 +0100170 new_data.readQuietly((Map<String, Object>) settings, false);
171 data.update(new_data);
172 controller.updateUserData(data);
173 }
174 catch (KustvaktException e) {
175 jlog.error("Exception encountered!", e);
176 throw kustvaktResponseHandler.throwit(e);
177 }
178
179 return Response.ok().build();
180 }
181
182 @GET
183 @Path("details")
184 @ResourceFilters({ AuthenticationFilter.class, DemoUserFilter.class,
185 PiwikFilter.class, BlockingFilter.class })
186 public Response getDetails (@Context SecurityContext context,
187 @Context Locale locale, @QueryParam("pointer") String pointer) {
188 TokenContext ctx = (TokenContext) context.getUserPrincipal();
189 String result;
190 try {
191 User user = controller.getUser(ctx.getUsername());
192 Userdata data = controller.getUserData(user, UserDetails.class);
193 data.setField(Attributes.USERNAME, ctx.getUsername());
194 if (pointer != null)
195 result = data.get(pointer).toString();
196 else
197 result = data.serialize();
198 }
199 catch (KustvaktException e) {
200 jlog.error("Exception encountered: "+ e.string());
201 throw kustvaktResponseHandler.throwit(e);
202 }
203 return Response.ok(result).build();
204 }
205
206
207 // EM: may be used for managing shib users
208 @POST
209 @Path("details")
210 @Consumes({ MediaType.APPLICATION_JSON })
211 @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
212 BlockingFilter.class })
213 public Response updateDetails (@Context SecurityContext context,
214 @Context Locale locale, Map details) {
215 TokenContext ctx = (TokenContext) context.getUserPrincipal();
216
217 if (details == null) return Response.notModified().build();
218
219 try {
220 User user = controller.getUser(ctx.getUsername());
221 if (User.UserFactory.isDemo(ctx.getUsername()))
222 return Response.notModified().build();
223
224 UserDetails new_data = new UserDetails(user.getId());
225 new_data.readQuietly((Map<String, Object>) details, false);
226
227 UserDetails det = controller.getUserData(user, UserDetails.class);
228 det.update(new_data);
229 controller.updateUserData(det);
230 }
231 catch (KustvaktException e) {
232 jlog.error("Exception encountered!", e);
233 throw kustvaktResponseHandler.throwit(e);
234 }
235 return Response.ok().build();
236 }
237
238
239 //fixme: if policy allows, foreign user might be allowed to change search!
240 @POST
241 @Path("queries")
242 @Consumes(MediaType.APPLICATION_JSON)
243 @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
244 BlockingFilter.class })
245 public Response updateQueries (@Context SecurityContext context,
246 String json) {
247 TokenContext ctx = (TokenContext) context.getUserPrincipal();
248 Collection<UserQuery> add = new HashSet<>();
249 try {
250 User user = controller.getUser(ctx.getUsername());
251 List<UserQuery> userQuieres = new ArrayList<>();
252 JsonNode nodes = JsonUtils.readTree(json);
253 Iterator<JsonNode> node = nodes.elements();
254 while (node.hasNext()) {
255 JsonNode cursor = node.next();
256 UserQuery query =
257 new UserQuery(cursor.path("id").asInt(), user.getId());
258 query.setQueryLanguage(cursor.path("queryLanguage").asText());
259 query.setQuery(cursor.path("query").asText());
260 query.setDescription(cursor.path("description").asText());
261 userQuieres.add(query);
262 }
263
264 //1: add all that are new, update all that are retained, delete the rest
265 // Set<UserQuery> resources = ResourceFinder
266 // .search(user, UserQuery.class);
267 //
268 // add.addAll(userQuieres);
269 // add.removeAll(resources);
270 // Collection<UserQuery> update = new HashSet<>(userQuieres);
271 // update.retainAll(resources);
272 // resources.removeAll(userQuieres);
273 //
274 // if (!update.isEmpty()) {
275 // resourceHandler.updateResources(user,
276 // update.toArray(new UserQuery[update.size()]));
277 // }
278 // if (!add.isEmpty()) {
279 // resourceHandler.storeResources(user,
280 // add.toArray(new UserQuery[add.size()]));
281 // }
282 // if (!resources.isEmpty()) {
283 // resourceHandler.deleteResources(user,
284 // resources.toArray(new UserQuery[resources.size()]));
285 // }
286 }
287 catch (KustvaktException e) {
288 jlog.error("Exception encountered!", e);
289 throw kustvaktResponseHandler.throwit(e);
290 }
291 try {
292 return Response.ok(JsonUtils.toJSON(add)).build();
293 }
294 catch (KustvaktException e) {
295 throw kustvaktResponseHandler.throwit(e);
296 }
297 }
298
299 // EM: may be used for managing shib users
300 @DELETE
301 @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
302 BlockingFilter.class })
303 public Response deleteUser (@Context SecurityContext context) {
304 TokenContext ctx = (TokenContext) context.getUserPrincipal();
305 try {
306 User user = controller.getUser(ctx.getUsername());
307 //todo: test that demo user cannot be deleted!
308 controller.deleteAccount(user);
309 }
310 catch (KustvaktException e) {
311 jlog.error("Exception encountered!", e);
312 throw kustvaktResponseHandler.throwit(e);
313 }
314 return Response.ok().build();
315 }
316
317
318 @GET
319 @Path("queries")
320 @ResourceFilters({ AuthenticationFilter.class, DemoUserFilter.class,
321 PiwikFilter.class, BlockingFilter.class })
322 public Response getQueries (@Context SecurityContext context,
323 @Context Locale locale) {
324 TokenContext ctx = (TokenContext) context.getUserPrincipal();
325 String queryStr;
326 try {
327 User user = controller.getUser(ctx.getUsername());
328 // Set<UserQuery> queries = ResourceFinder
329 // .search(user, UserQuery.class);
330 // queryStr = JsonUtils.toJSON(queries);
331 //todo:
332 queryStr = "";
333 }
334 catch (KustvaktException e) {
335 jlog.error("Exception encountered!", e);
336 throw kustvaktResponseHandler.throwit(e);
337 }
338 return Response.ok(queryStr).build();
339 }
340}