source: DASISH/t5.6/backend/annotator-backend/trunk/annotator-backend/src/main/java/eu/dasish/annotation/backend/rest/PrincipalResource.java @ 5266

Last change on this file since 5266 was 5266, checked in by olhsha@mpi.nl, 10 years ago

Fixing automatic generation of a shibbolized user record and fixing update principals (both bugs appeared after refactoring). Fixing dynamic logout link. Fixing jsp page.

File size: 17.9 KB
Line 
1/*
2 * Copyright (C) 2013 DASISH
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17 */
18package eu.dasish.annotation.backend.rest;
19
20import eu.dasish.annotation.backend.NotInDataBaseException;
21import eu.dasish.annotation.backend.PrincipalCannotBeDeleted;
22import eu.dasish.annotation.backend.PrincipalExists;
23import eu.dasish.annotation.backend.Resource;
24import eu.dasish.annotation.backend.dao.ILambda;
25import eu.dasish.annotation.backend.dao.ILambdaPrincipal;
26import eu.dasish.annotation.schema.CurrentPrincipalInfo;
27import eu.dasish.annotation.schema.ObjectFactory;
28import eu.dasish.annotation.schema.Principal;
29import java.io.IOException;
30import java.sql.SQLException;
31import java.util.HashMap;
32import java.util.Map;
33import java.util.UUID;
34import javax.servlet.http.HttpServletRequest;
35import javax.servlet.http.HttpServletResponse;
36import javax.ws.rs.Consumes;
37import javax.ws.rs.DELETE;
38import javax.ws.rs.FormParam;
39import javax.ws.rs.GET;
40import javax.ws.rs.POST;
41import javax.ws.rs.PUT;
42import javax.ws.rs.Path;
43import javax.ws.rs.PathParam;
44import javax.ws.rs.Produces;
45import javax.ws.rs.QueryParam;
46import javax.ws.rs.core.MediaType;
47import javax.xml.bind.JAXBElement;
48import javax.xml.parsers.ParserConfigurationException;
49import org.springframework.dao.DuplicateKeyException;
50import org.springframework.stereotype.Component;
51import org.springframework.transaction.annotation.Transactional;
52
53/**
54 *
55 * @author olhsha
56 */
57@Component
58@Path("/principals")
59@Transactional(rollbackFor = {Exception.class, SQLException.class, IOException.class, ParserConfigurationException.class})
60public class PrincipalResource extends ResourceResource {
61
62    int shaStrength = 512;
63
64    public void setHttpRequest(HttpServletRequest request) {
65        this.httpServletRequest = request;
66    }
67
68    public PrincipalResource() {
69    }
70
71    @GET
72    @Produces(MediaType.TEXT_XML)
73    @Path("{principalid}")
74    @Transactional(readOnly = true)
75    public JAXBElement<Principal> getPrincipal(@PathParam("principalid") String externalIdentifier) throws IOException {
76        Map params = new HashMap<String, String>();
77        params.put("externalId", externalIdentifier);
78        Principal result = (Principal) (new RequestWrappers(this)).wrapRequestResource(params, new GetPrincipal());
79        return (result != null) ? (new ObjectFactory().createPrincipal(result)) : (new ObjectFactory().createPrincipal(new Principal()));
80    }
81
82    private class GetPrincipal implements ILambda<Map, Principal> {
83
84        @Override
85        public Principal apply(Map params) throws NotInDataBaseException {
86            final Number principalID = dbDispatcher.getResourceInternalIdentifier(UUID.fromString((String) params.get("externalId")), Resource.PRINCIPAL);
87            return dbDispatcher.getPrincipal(principalID);
88        }
89    }
90
91    /////////////////////////////////
92    @GET
93    @Produces(MediaType.TEXT_PLAIN)
94    @Path("admin")
95    @Transactional(readOnly = true)
96    public String getAdmin() throws IOException {
97        Number remotePrincipalID = this.getPrincipalID();
98        if (remotePrincipalID == null) {
99            return " ";
100        }
101        return "The admin of the server database " + dbDispatcher.getDataBaseAdmin().getDisplayName() + " is availiable via e-mail " + dbDispatcher.getDataBaseAdmin().getEMail();
102    }
103
104    /////////////////////////////////////////
105    @GET
106    @Produces(MediaType.TEXT_XML)
107    @Path("info")
108    @Transactional(readOnly = true)
109    public JAXBElement<Principal> getPrincipalByInfo(@QueryParam("email") String email) throws IOException {
110        Map params = new HashMap<String, String>();
111        params.put("email", email);
112        Principal result = (Principal) (new RequestWrappers(this)).wrapRequestResource(params, new GetPrincipalByInfo());
113        return (result != null) ? (new ObjectFactory().createPrincipal(result)) : (new ObjectFactory().createPrincipal(new Principal()));
114    }
115
116    private class GetPrincipalByInfo implements ILambda<Map, Principal> {
117
118        @Override
119        public Principal apply(Map params) throws NotInDataBaseException {
120            return dbDispatcher.getPrincipalByInfo((String) params.get("email"));
121        }
122    }
123
124    ////////////////////////////////////////
125    @GET
126    @Produces(MediaType.TEXT_XML)
127    @Path("{principalid}/current")
128    @Transactional(readOnly = true)
129    public JAXBElement<CurrentPrincipalInfo> getCurrentPrincipalInfo(@PathParam("principalid") String externalIdentifier) throws IOException {
130        Map params = new HashMap<String, String>();
131        params.put("externalId", externalIdentifier);
132        params.put("resource", this);
133        CurrentPrincipalInfo result = (CurrentPrincipalInfo) (new RequestWrappers(this)).wrapRequestResource(params, new GetCurrentPrincipalInfo());
134        return (result != null) ? (new ObjectFactory().createCurrentPrincipalInfo(result)) : (new ObjectFactory().createCurrentPrincipalInfo(new CurrentPrincipalInfo()));
135    }
136
137    private class GetCurrentPrincipalInfo implements ILambda<Map, CurrentPrincipalInfo> {
138
139        @Override
140        public CurrentPrincipalInfo apply(Map params) throws NotInDataBaseException {
141            final Number principalID = dbDispatcher.getResourceInternalIdentifier(UUID.fromString((String) params.get("externalId")), Resource.PRINCIPAL);
142            final CurrentPrincipalInfo principalInfo = new CurrentPrincipalInfo();
143            principalInfo.setRef(dbDispatcher.getResourceURI(principalID, Resource.PRINCIPAL));
144            principalInfo.setCurrentPrincipal(((PrincipalResource) params.get("resource")).ifLoggedIn(principalID));
145            return principalInfo;
146        }
147    }
148    //////////////////////////////
149
150    @POST
151    @Produces(MediaType.TEXT_PLAIN)
152    @Path("create/{remoteId}/{password}")
153    public String createSpringAuthenticationRecord(@PathParam("remoteId") String remoteId, @PathParam("password") String password) throws IOException {
154        Number remotePrincipalID = this.getPrincipalID();
155        if (remotePrincipalID == null) {
156            return "Logged in principal is null or anonymous.";
157        }
158
159        if (dbDispatcher.getTypeOfPrincipalAccount(remotePrincipalID).equals(admin)) {
160            try {
161                int result = dbDispatcher.addSpringUser(remoteId, password, shaStrength, remoteId);
162                return result + " record(s) has been added. Must be 2: 1 record for the principal, another for the authorities table.";
163            } catch (DuplicateKeyException e) {
164                loggerServer.error(e.toString());
165                httpServletResponse.sendError(HttpServletResponse.SC_BAD_REQUEST);
166                return e.toString();
167            }
168        } else {
169            this.ADMIN_RIGHTS_EXPECTED();
170            httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
171            return "Nothing is added.";
172        }
173
174    }
175
176    ///////////////////////////////////////
177    @POST
178    @Consumes(MediaType.APPLICATION_XML)
179    @Produces(MediaType.APPLICATION_XML)
180    @Path("{remoteId}")
181    public JAXBElement<Principal> addPrincipal(@PathParam("remoteId") String remoteId, Principal principal) throws IOException {
182
183        Number remotePrincipalID = this.getPrincipalID();
184        if (remotePrincipalID == null) {
185            return new ObjectFactory().createPrincipal(new Principal());
186        }
187
188        Map params = new HashMap<String, Object>();
189        params.put("remoteId", remoteId);
190        params.put("newPrincipal", principal);
191
192        if (dbDispatcher.getTypeOfPrincipalAccount(remotePrincipalID).equals(admin)) {
193            return (new RequestWrappers(this)).wrapAddPrincipalRequest(params, new AddPrincipal());
194        } else {
195            this.ADMIN_RIGHTS_EXPECTED();
196            httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
197            return new ObjectFactory().createPrincipal(new Principal());
198        }
199
200    }
201
202    private class AddPrincipal implements ILambdaPrincipal<Map, Principal> {
203
204        @Override
205        public Principal apply(Map params) throws NotInDataBaseException, PrincipalExists {
206            final Number principalID = dbDispatcher.addPrincipal((Principal) params.get("newPrincipal"), (String) params.get("remoteId"));
207            return dbDispatcher.getPrincipal(principalID);
208        }
209    }
210
211    /////////////////////////////////////
212    @POST
213    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
214    @Produces(MediaType.APPLICATION_XML)
215    @Path("register/nonshibboleth")
216    public JAXBElement<Principal> registerNonShibbolizedPrincipal(@FormParam("name") String name,
217            @FormParam("remoteId") String remoteId, @FormParam("password") String password, @FormParam("email") String email)
218            throws IOException {
219        Principal newPrincipal = new Principal();
220        newPrincipal.setDisplayName(name);
221        newPrincipal.setEMail(email);
222
223        Map params = new HashMap<String, Object>();
224        params.put("remoteId", remoteId);
225        params.put("password", password);
226        params.put("shaStrength", shaStrength);
227        params.put("newPrincipal", newPrincipal);
228
229        dbDispatcher.setServiceURI(uriInfo.getBaseUri().toString());
230        return (new RequestWrappers(this)).wrapAddPrincipalRequest(params, new RegisterNonShibbolizedPrincipal());
231    }
232
233    private class RegisterNonShibbolizedPrincipal implements ILambdaPrincipal<Map, Principal> {
234
235        @Override
236        public Principal apply(Map params) throws NotInDataBaseException, PrincipalExists {
237            try {
238                final int updatedSpringTables = dbDispatcher.addSpringUser((String) params.get("remoteId"), (String) params.get("password"), (Integer) params.get("shaStrength"), (String) params.get("remoteId"));
239                final Number principalID = dbDispatcher.addPrincipal((Principal) params.get("newPrincipal"), (String) params.get("remoteId"));
240                return dbDispatcher.getPrincipal(principalID);
241            } catch (DuplicateKeyException e) {
242                throw new PrincipalExists(e);
243            }
244        }
245    }
246
247    ///////////////////////////////////////////////
248    @POST
249    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
250    @Produces(MediaType.APPLICATION_XML)
251    @Path("register/shibboleth")
252    public JAXBElement<Principal> registerShibbolizedPrincipal(@FormParam("name") String name,
253            @FormParam("remoteId") String remoteId, @FormParam("email") String email)
254            throws IOException {
255        dbDispatcher.setServiceURI(uriInfo.getBaseUri().toString());
256        Principal newPrincipal = new Principal();
257        newPrincipal.setDisplayName(name);
258        newPrincipal.setEMail(email);
259        Map params = new HashMap<String, Object>();
260        params.put("remoteId", remoteId);
261        params.put("newPrincipal", newPrincipal);
262
263        dbDispatcher.setServiceURI(uriInfo.getBaseUri().toString());
264        return (new RequestWrappers(this)).wrapAddPrincipalRequest(params, new AddPrincipal());
265    }
266
267    ///////////////////////////////////////////////////
268    @POST
269    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
270    @Produces(MediaType.TEXT_PLAIN)
271    @Path("register/shibbolethasnonshibboleth")
272    public String registerShibbolizedPrincipalAsNonShibb(@FormParam("remoteId") String remoteId, @FormParam("password") String password)
273            throws IOException {
274        try {
275            int result = dbDispatcher.addSpringUser(remoteId, password, shaStrength, remoteId);
276            return result + " record(s) has been added. Must be 2: 1 record for the principal, another for the authorities table.";
277        } catch (DuplicateKeyException e) {
278            loggerServer.error(e.toString());
279            httpServletResponse.sendError(HttpServletResponse.SC_BAD_REQUEST);
280            return e.toString();
281        }
282    }
283
284    @PUT
285    @Consumes(MediaType.APPLICATION_XML)
286    @Produces(MediaType.APPLICATION_XML)
287    @Path("")
288    public JAXBElement<Principal> updatePrincipal(Principal principal) throws IOException {
289        Number remotePrincipalID = this.getPrincipalID();
290        if (remotePrincipalID == null) {
291            return new ObjectFactory().createPrincipal(new Principal());
292        }
293        if (dbDispatcher.getTypeOfPrincipalAccount(remotePrincipalID).equals(admin)) {
294            Map params = new HashMap<String, Object>();
295            params.put("newPrincipal", principal);
296            Principal result = (Principal) (new RequestWrappers(this)).wrapRequestResource(params, new UpdatePrincipal());
297            return (result != null) ? (new ObjectFactory().createPrincipal(result)) : (new ObjectFactory().createPrincipal(new Principal()));
298
299        } else {
300            this.ADMIN_RIGHTS_EXPECTED();
301            httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
302            return new ObjectFactory().createPrincipal(new Principal());
303        }
304    }
305    ///////////////////////////////////
306
307    @POST
308    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
309    @Produces(MediaType.APPLICATION_XML)
310    @Path("updateme")
311    public JAXBElement<Principal> updatePrincipalFromForm(@FormParam("name") String name, @FormParam("email") String email)
312            throws IOException {
313       
314        Principal newPrincipal = new Principal();
315        newPrincipal.setDisplayName(name);
316        newPrincipal.setEMail(email);
317        Map params = new HashMap<String, Object>();
318        params.put("newPrincipal", newPrincipal);
319        Principal result = (Principal) (new RequestWrappers(this)).wrapRequestResource(params, new UpdatePrincipal());
320        return (result != null) ? (new ObjectFactory().createPrincipal(result)) : (new ObjectFactory().createPrincipal(new Principal()));
321    }
322
323    private class UpdatePrincipal implements ILambda<Map, Principal> {
324
325        @Override
326        public Principal apply(Map params) throws NotInDataBaseException {
327            Principal principal = (Principal) params.get("newPrincipal");
328            Number principalID = (Number) params.get("principalID");
329            String principalURI = dbDispatcher.getResourceURI(principalID, Resource.PRINCIPAL);
330            principal.setURI(principalURI);
331            Number principalIDupd = dbDispatcher.updatePrincipal(principal);           
332            return dbDispatcher.getPrincipal(principalIDupd);
333        }
334    }
335
336    //////////////////////////////////////
337    @PUT
338    @Produces(MediaType.TEXT_PLAIN)
339    @Path("{externalId}/account/{accountType}")
340    public String updatePrincipalAccount(@PathParam("externalId") String externalId, @PathParam("accountType") String accountType) throws IOException {
341        Number remotePrincipalID = this.getPrincipalID();
342        if (remotePrincipalID == null) {
343            return "Nothing is updated.";
344        }
345        if (dbDispatcher.getTypeOfPrincipalAccount(remotePrincipalID).equals(admin)) {
346            try {
347                final boolean updated = dbDispatcher.updateAccount(UUID.fromString(externalId), accountType);
348                if (updated) {
349                    return "The account was updated to " + dbDispatcher.getTypeOfPrincipalAccount(dbDispatcher.getResourceInternalIdentifier(UUID.fromString(externalId), Resource.PRINCIPAL));
350                } else {
351                    loggerServer.debug("The account is not updated.");
352                    httpServletResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Account is not updated.");
353                    return "Account is not updated.";
354                }
355            } catch (NotInDataBaseException e) {
356                loggerServer.debug(e.toString());;
357                httpServletResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString());
358                return "Account is updated.";
359            }
360        } else {
361            this.ADMIN_RIGHTS_EXPECTED();
362            httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
363            return "Account is not updated.";
364        }
365
366    }
367
368    @DELETE
369    @Path("{principalId}")
370    public String deletePrincipal(@PathParam("principalId") String externalIdentifier) throws IOException {
371        Number remotePrincipalID = this.getPrincipalID();
372        if (remotePrincipalID == null) {
373            return "Nothings is deleted.";
374        }
375        if (dbDispatcher.getTypeOfPrincipalAccount(remotePrincipalID).equals(admin)) {
376            try {
377                final Number principalID = dbDispatcher.getResourceInternalIdentifier(UUID.fromString(externalIdentifier), Resource.PRINCIPAL);
378                try {
379                    final int result = dbDispatcher.deletePrincipal(principalID);
380                    return "There is " + result + " row deleted";
381                } catch (PrincipalCannotBeDeleted e2) {
382                    loggerServer.debug(e2.toString());;
383                    httpServletResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e2.toString());
384                    return "Nothing is deleted.";
385                }
386            } catch (NotInDataBaseException e) {
387                loggerServer.debug(e.toString());;
388                httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND, e.toString());
389                return "Nothing is deleted.";
390            }
391        } else {
392            this.ADMIN_RIGHTS_EXPECTED();
393            httpServletResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
394            return "Account is not updated.";
395        }
396
397    }
398
399    // silly because it is trivial. harvest all logged in users via shibboleth!!
400    private boolean ifLoggedIn(Number principalID) {
401        return (httpServletRequest.getRemoteUser()).equals(dbDispatcher.getPrincipalRemoteID(principalID));
402    }
403}
Note: See TracBrowser for help on using the repository browser.