package no.niths.application.rest.auth; import no.niths.application.rest.RESTConstants; import no.niths.application.rest.RESTExceptionHandler; import no.niths.application.rest.auth.interfaces.RestDeveloperAccessController; import no.niths.application.rest.exception.BadRequestException; import no.niths.domain.development.Application; import no.niths.domain.development.Developer; import no.niths.security.ApplicationToken; import no.niths.security.DeveloperToken; import no.niths.services.auth.interfaces.AuthenticationService; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.AuthenticationException; import org.springframework.stereotype.Controller; 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.ResponseBody; import org.springframework.web.servlet.ModelAndView; /** * * Handles developers wanting access to the API * <p> * Developers must register with the API to be able to * develop applications that can access the restricted * resources in the API * </p> * <p> * Developers register, then confirms their identity and * then they can register and enable applications * </p> * <p> * See the API webpage for more information * </p> * */ @Controller @RequestMapping("register") public class RestDeveloperAccessControllerImpl extends RESTExceptionHandler implements RestDeveloperAccessController { Logger logger = org.slf4j.LoggerFactory .getLogger(RestDeveloperAccessControllerImpl.class); @Autowired private AuthenticationService service; private final static String VIEW_NAME = "developerConfirmation"; /** * Register a developer and generates a developer token that the developer * uses in future requests * <p> * * <pre> * {@code * How to use: * POST: niths/register/ * * Header: * Content-type: application/xml * Accept: application/xml || application/json * * Body: * <developer> * <email>youremail@mail.com</email> * <name>Your developer name</name> * </developer> * } * </pre> * * @param developer * the developer to persist * @return DeveloperToken an object containing the developer key and a * confirmation message */ @Override @RequestMapping( method = RequestMethod.POST, headers = RESTConstants.ACCEPT_HEADER) @ResponseBody public DeveloperToken requestAccess(@RequestBody Developer developer) { logger.debug("A developer requests access. Email: " + developer.getEmail()); if (developer.getApps() != null) { throw new BadRequestException( "You must register as a developer before registering apps"); } DeveloperToken devToken = service.registerDeveloper(developer); logger.debug("Request success, sending email"); return devToken; } /** * Enables already registred developers. Returns a new developer token to * use in all future requests. * <p> * How to use: Paste the url to the server + * /niths/register/enableDeveloper/<your_key> into your favourite browser * <p> * <p> * A confirmation email will be sendt to the developer * </p> * @param developerKey * the key returned from requestAccess(Developer) * @return a page with confirmation or error message */ @Override @RequestMapping( value = "enableDeveloper/{developerKey:.+}", method = RequestMethod.GET) public ModelAndView enableDeveloper(@PathVariable String developerKey) { logger.debug("Developer wants to be enabled with developer-key: " + developerKey); ModelAndView view = new ModelAndView(VIEW_NAME); try { Developer dev = service.enableDeveloper(developerKey); view.addObject("msg", "Your developer account is enabled!"); // Returns a view with the new token view.addObject("token", "Developer-token: " + dev.getDeveloperToken()); view.addObject("key", "Developer-key: " + dev.getDeveloperKey()); } catch (AuthenticationException e) { view.addObject("error", e.getMessage()); } return view; } /** * Enables a developer * Same as method ModelAndView enableDeveloper(developerKey), * but as a REST service * <p> * If you want to create an application that enables developers, * this is the method you want to use * </p> * <p> * A confirmation email will be sendt to the developer * </p> * @param developerKey the developer key * @return a developertoken with token + key or a error message */ @Override @RequestMapping( value = "enable/developer/{developerKey:.+}", method = RequestMethod.PUT, headers = RESTConstants.ACCEPT_HEADER) @ResponseBody public DeveloperToken enableDeveloperRest(@PathVariable String developerKey){ DeveloperToken token = new DeveloperToken(); try { Developer dev = service.enableDeveloper(developerKey); token.setKey(dev.getDeveloperKey()); token.setToken(dev.getDeveloperToken()); } catch (AuthenticationException e) { token.setMessage(e.getMessage()); } return token; } /** * Registers an application * <p> * Developer must have been authorized for a successful request * </p> * <p> * A confirmation email will be sendt to the developer * </p> * @param app * the application to add * @param developerKey * the developer key * @return an application key to use to enable the application * */ @Override @RequestMapping( value = "addApp/{developerKey}", method = RequestMethod.POST, headers = RESTConstants.ACCEPT_HEADER) @ResponseBody public ApplicationToken addApplicationToDeveloper( @RequestBody Application app, @PathVariable String developerKey) { logger.debug("Developer wants to registrate an application"); ApplicationToken token = new ApplicationToken("Could not register app"); token = service.registerApplication(app, developerKey); return token; } /** * Enables an application * <p> * A confirmation email will be sendt to the developer * </p> * @param applicationKey * @return a view with confirmation */ @Override @RequestMapping( value = "enableApp/{applicationKey:.+}", method = RequestMethod.GET) public ModelAndView enableApplication(@PathVariable String applicationKey) { logger.debug("Application wants to be enabled with application-key: " + applicationKey); ModelAndView view = new ModelAndView(VIEW_NAME); try { Application app = service.enableApplication(applicationKey); view.addObject("msg", "Your app is enabled!"); // Returns a view with the new token view.addObject("token", "Application-token: " + app.getApplicationToken()); view.addObject("key", "Application-key: " + app.getApplicationKey()); } catch (AuthenticationException e) { view.addObject("error", e.getMessage()); } return view; } /** * Enables an application. Same as enableApplication(String applicationKey), * but as a REST service * <p> * If you want to create an application that enables application, * this is the method you want to use * </p> * <p> * A confirmation email will be sendt to the developer * </p> * @param applicationKey * @return a view with confirmation */ @Override @RequestMapping( value = "enable/application/{applicationKey:.+}", method = RequestMethod.PUT, headers = RESTConstants.ACCEPT_HEADER) public ApplicationToken enableApplicationRest(@PathVariable String applicationKey) { logger.debug("Application wants to be enabled with application-key: " + applicationKey); ApplicationToken token = new ApplicationToken(); try { Application app = service.enableApplication(applicationKey); token.setAppKey(app.getApplicationKey()); token.setToken(app.getApplicationToken()); } catch (AuthenticationException e) { token.setMessage(e.getMessage()); } return token; } }