Commit 036e500e by Juho Juopperi

Merge branch 'applicationRestStuff' into 'master'

Application rest stuff

2 new rest stuff

application can create applicationInstance via rest, with username and password enabled one, and without disabled

Application can get user events via rest

See merge request !261
2 parents 1732b012 9289c229
/*
* Copyright Codecrew Ry
*
* All rights reserved.
*
* This license applies to any software containing a notice placed by the
* copyright holder. Such software is herein referred to as the Software.
* This license covers modification, distribution and use of the Software.
*
* Any distribution and use in source and binary forms, with or without
* modification is not permitted without explicit written permission from the
* copyright owner.
*
* A non-exclusive royalty-free right is granted to the copyright owner of the
* Software to use, modify and distribute all modifications to the Software in
* future versions of the Software.
*
*/
package fi.codecrew.moya.beans;
import fi.codecrew.moya.model.ApiApplicationInstance;
import javax.ejb.Local;
@Local
public interface ApiApplicationBeanLocal {
/**
* Creates applicationinstance for currentuser and application specified in application key
* @param applicationKey
* @return
*/
public ApiApplicationInstance createInstance(String applicationKey);
/**
* Creates new enabled applicationinstance for current user
*
* @param applicationkey
* @return
*/
ApiApplicationInstance createApplicationInstance(String applicationkey);
/**
* creates new disabled applicationInstance for specified user
*
* @param applicationkey
* @param username
* @return
*/
ApiApplicationInstance createApplicationInstance(String applicationkey, String username);
}
......@@ -66,4 +66,7 @@ public interface EventBeanLocal {
List<LanEvent> findAllEvents();
List<LanEvent> findAllEventsForCurrentUser();
List<LanEvent> findFutureAndRunningEventsForCurrentUser();
}
/*
* Copyright Codecrew Ry
*
* All rights reserved.
*
* This license applies to any software containing a notice placed by the
* copyright holder. Such software is herein referred to as the Software.
* This license covers modification, distribution and use of the Software.
*
* Any distribution and use in source and binary forms, with or without
* modification is not permitted without explicit written permission from the
* copyright owner.
*
* A non-exclusive royalty-free right is granted to the copyright owner of the
* Software to use, modify and distribute all modifications to the Software in
* future versions of the Software.
*
*/
package fi.codecrew.moya.beans;
import fi.codecrew.moya.facade.ApiApplicationFacade;
import fi.codecrew.moya.facade.ApiApplicationInstanceFacade;
import fi.codecrew.moya.model.ApiApplication;
import fi.codecrew.moya.model.ApiApplicationInstance;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.utilities.PasswordFunctions;
import fi.codecrew.moya.utilities.moyamessage.MoyaEventType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.*;
import java.util.*;
import java.util.Map.Entry;
/**
* Session Bean implementation class RestAuthBean
*/
@Singleton
@LocalBean
public class ApiApplicationBean implements ApiApplicationBeanLocal {
@EJB
ApiApplicationFacade applicationFacade;
@EJB
PermissionBean permissionBean;
@EJB
ApiApplicationInstanceFacade instanceFacade;
@EJB
EventBean eventBean;
@EJB
LoggingBeanLocal loggingBean;
@EJB
UserBean userBean;
/**
* Default constructor.
*/
public ApiApplicationBean() {
// TODO Auto-generated constructor stub
}
@Override
public ApiApplicationInstance createInstance(String applicationKey) {
return null;
}
@Override
public ApiApplicationInstance createApplicationInstance(String applicationkey) {
ApiApplication application = applicationFacade.findByAppid(applicationkey);
if(application == null)
return null;
// we do not liek anonymous
if(permissionBean.getCurrentUser().isAnonymous())
throw new EJBAccessException("Anonmous cannot login application to software, sorry!.");
// ugly as shit sanitation for eventName, sorry
String eventName = eventBean.getCurrentEvent().getName().replace(" ","_").replace("ä", "a").replace("ö","o").replace("Ä","A").replace("Ö","O").replace("å","a").replace("Å","A");
String authname = permissionBean.getCurrentUser().getLogin()+"_"+application.getName()+"_"+eventName;
while(instanceFacade.findInstance(application, authname) != null) {
authname += "_";
}
ApiApplicationInstance instance = new ApiApplicationInstance();
instance.setApplication(application);
instance.setAuthname(authname);
instance.setName(application.getName() + " for user: "+permissionBean.getCurrentUser().getLogin());
instance.setCreated(Calendar.getInstance().getTime());
instance.setEnabled(true);
instance.setEventuser(permissionBean.getCurrentUser());
instance.setSecretKey(PasswordFunctions.generateRandomString(30));
instanceFacade.create(instance);
loggingBean.sendMessage(MoyaEventType.APPLICATION_INSTANCE_CREATED, "New applicationinstance created for software: ", application);
return instance;
}
@Override
public ApiApplicationInstance createApplicationInstance(String applicationkey, String username) {
ApiApplication application = applicationFacade.findByAppid(applicationkey);
if(application == null)
return null;
EventUser user = userBean.findEventuserByLoginUnsecure(username);
if(user == null)
return null;
// ugly as shit sanitation for eventName, sorry
String eventName = eventBean.getCurrentEvent().getName().replace(" ","_").replace("ä", "a").replace("ö","o").replace("Ä","A").replace("Ö","O").replace("å","a").replace("Å","A");
String authname = user.getLogin()+"_"+application.getName()+"_"+eventName;
while(instanceFacade.findInstance(application, authname) != null) {
authname += "_";
}
ApiApplicationInstance instance = new ApiApplicationInstance();
instance.setApplication(application);
instance.setAuthname(authname);
instance.setName(application.getName() + " for user: "+user.getLogin());
instance.setCreated(Calendar.getInstance().getTime());
instance.setEnabled(false);
instance.setEventuser(user);
instance.setSecretKey(PasswordFunctions.generateRandomString(30));
instanceFacade.create(instance);
loggingBean.sendMessage(MoyaEventType.APPLICATION_INSTANCE_CREATED, "New applicationinstance created for software: ", application, " user: ", username);
return instance;
}
}
......@@ -19,6 +19,8 @@
package fi.codecrew.moya.beans;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.annotation.security.DeclareRoles;
......@@ -333,4 +335,37 @@ public class EventBean implements EventBeanLocal {
return eventFacade.findAll();
}
@Override
public List<LanEvent> findAllEventsForCurrentUser() {
return eventFacade.findAll(permbean.getCurrentUser().getUser());
}
@Override
public List<LanEvent> findFutureAndRunningEventsForCurrentUser() {
List<LanEvent> events = findAllEventsForCurrentUser();
List<LanEvent> retlist = new ArrayList<>();
Calendar tmp = Calendar.getInstance();
tmp.add(Calendar.DAY_OF_MONTH, -5);
Date compareDate = tmp.getTime();
for(LanEvent event : events) {
if(event.getEndTime() == null) {
retlist.add(event);
continue;
}
if(event.getEndTime().compareTo(compareDate) > 0) {
retlist.add(event);
}
}
return retlist;
}
}
......@@ -1128,6 +1128,12 @@ public class UserBean implements UserBeanLocal {
return null;
}
@PermitAll
public EventUser findEventuserByLoginUnsecure(String username) {
return eventUserFacade.findByLogin(username);
}
@Override
@RolesAllowed(EventPermission.S_MANAGE_EVENT)
......
......@@ -26,9 +26,9 @@ import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Subquery;
import fi.codecrew.moya.model.LanEvent;
import fi.codecrew.moya.model.LanEvent_;
import fi.codecrew.moya.model.*;
@Stateless
@LocalBean
......@@ -77,4 +77,29 @@ public class EventFacade extends IntegerPkGenericFacade<LanEvent> {
return q.getResultList();
}
public List<LanEvent> findAll(User user) {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<LanEvent> cq = cb.createQuery(LanEvent.class);
Root<LanEvent> root = cq.from(LanEvent.class);
// subquery
Subquery<Integer> subcq = cq.subquery(Integer.class);
Root<EventUser> subroot = subcq.from(EventUser.class);
subcq.select(subroot.get(EventUser_.event).get(LanEvent_.id));
subcq.where(
cb.equal(subroot.get(EventUser_.user), user)
);
cq.where(
root.get(LanEvent_.id).in(subcq)
);
List<LanEvent> events = getEm().createQuery(cq).getResultList();
return events;
}
}
package fi.codecrew.moya.rest.pojo.appconfig.v1;
import javax.xml.bind.annotation.XmlElement;
/**
* Created by tuukka on 28.3.2015.
*/
public class ApplicationInstancePojo {
private String authname;
private String secretKey;
private String name;
@XmlElement()
public String getAuthname() {
return authname;
}
public void setAuthname(String authname) {
this.authname = authname;
}
@XmlElement()
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
@XmlElement()
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package fi.codecrew.moya.rest.pojo.appconfig.v1;
import com.wordnik.swagger.annotations.ApiModel;
import javax.xml.bind.annotation.XmlElement;
import java.util.List;
/**
* Created by tuukka on 28.3.2015.
*/
@ApiModel
public class EventPojo {
private Integer lanEventId;
private String name;
private List<String> urls;
@XmlElement
public Integer getLanEventId() {
return lanEventId;
}
public void setLanEventId(Integer lanEventId) {
this.lanEventId = lanEventId;
}
@XmlElement
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlElement
public List<String> getUrls() {
return urls;
}
public void setUrls(List<String> urls) {
this.urls = urls;
}
}
package fi.codecrew.moya.rest.pojo.appconfig.v1;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
/**
* Created by tuukka on 28.3.2015.
*/
@XmlRootElement
public class EventRoot {
private List<EventPojo> events;
public List<EventPojo> getEvents() {
return events;
}
public void setEvents(List<EventPojo> events) {
this.events = events;
}
}
......@@ -3,6 +3,7 @@ package fi.codecrew.moya.utilities.moyamessage;
public enum MoyaEventType {
LOGIN_FAILED(MoyaEventSource.USER),
USER_CREATED(MoyaEventSource.USER),
APPLICATION_INSTANCE_CREATED(MoyaEventSource.USER),
USER_INSUFFICIENT_PERMISSIONS(MoyaEventSource.USER),
BILL_CREATED(MoyaEventSource.SHOP),
BILL_PAID(MoyaEventSource.SHOP),
......
......@@ -6,14 +6,10 @@ import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import fi.codecrew.moya.model.EventMap;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.GroupMembership;
import fi.codecrew.moya.model.Place;
import fi.codecrew.moya.model.PrintedCard;
import fi.codecrew.moya.model.Product;
import fi.codecrew.moya.model.Reader;
import fi.codecrew.moya.model.ReaderEvent;
import fi.codecrew.moya.model.*;
import fi.codecrew.moya.rest.pojo.appconfig.v1.ApplicationInstancePojo;
import fi.codecrew.moya.rest.pojo.appconfig.v1.EventPojo;
import fi.codecrew.moya.rest.pojo.appconfig.v1.EventRoot;
import fi.codecrew.moya.rest.pojo.map.v1.MapPojo;
import fi.codecrew.moya.rest.pojo.map.v1.MapRoot;
import fi.codecrew.moya.rest.pojo.map.v1.PlacePojo;
......@@ -312,10 +308,46 @@ public class PojoUtils {
return ur;
}
public static EventRoot parseEvents(List<LanEvent> events) {
EventRoot root = new EventRoot();
ArrayList<EventPojo> eventPojos = new ArrayList<>();
for(LanEvent event : events) {
ArrayList<String> urls = new ArrayList<>();
for(LanEventDomain domain : event.getDomains()) {
urls.add(domain.getDomain());
}
EventPojo pojo = new EventPojo();
pojo.setName(event.getName());
pojo.setLanEventId(event.getId());
pojo.setUrls(urls);
eventPojos.add(pojo);
}
root.setEvents(eventPojos);
return root;
}
public static ApplicationInstancePojo parseApplicationInstance(ApiApplicationInstance instance) {
ApplicationInstancePojo pojo = new ApplicationInstancePojo();
pojo.setName(instance.getName());
pojo.setAuthname(instance.getAuthname());
pojo.setSecretKey(instance.getSecretKey());
return pojo;
}
public static ErrorRoot initErrorPojo(String errorMessage) {
ErrorRoot errorRoot = new ErrorRoot();
errorRoot.setError(errorMessage);
return errorRoot;
}
}
package fi.codecrew.moya.rest.appconfig.v1;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiResponse;
import fi.codecrew.moya.beans.EventBeanLocal;
import fi.codecrew.moya.beans.PermissionBeanLocal;
import fi.codecrew.moya.beans.SessionMgmtBeanLocal;
import fi.codecrew.moya.beans.UserBeanLocal;
import fi.codecrew.moya.model.LanEvent;
import fi.codecrew.moya.rest.PojoUtils;
import fi.codecrew.moya.rest.pojo.appconfig.v1.EventRoot;
import fi.codecrew.moya.rest.pojo.map.v1.MapRoot;
import javax.ejb.EJB;
import javax.ejb.SessionBean;
import javax.enterprise.context.RequestScoped;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
/**
* Created by tuukka on 28.3.2015.
*/
@RequestScoped
@Path("/appconfig/v1/eventinfo")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON + "; charset=UTF-8" })
@Api(value="/appconfig/v1/eventinfo", description = "Event information for application")
public class EventInfoV1 {
@EJB
PermissionBeanLocal permissionBean;
@EJB
EventBeanLocal eventBean;
@GET
@Path("/listevents/")
@ApiOperation(value = "Get all events for current user", response = EventRoot.class)
@ApiResponse(code = 200, message = "Return events for current user")
public Response getEventsForCurrentUser() {
if(permissionBean.getCurrentUser().isAnonymous()) {
return Response.status(Response.Status.FORBIDDEN).build();
}
return Response.ok(PojoUtils.parseEvents(eventBean.findFutureAndRunningEventsForCurrentUser())).build();
}
}
package fi.codecrew.moya.rest.appconfig.v1;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiResponse;
import fi.codecrew.moya.beans.ApiApplicationBeanLocal;
import fi.codecrew.moya.beans.EventBeanLocal;
import fi.codecrew.moya.beans.PermissionBeanLocal;
import fi.codecrew.moya.model.ApiApplicationInstance;
import fi.codecrew.moya.rest.PojoUtils;
import fi.codecrew.moya.rest.pojo.appconfig.v1.ApplicationInstancePojo;
import fi.codecrew.moya.rest.pojo.map.v1.MapRoot;
import org.primefaces.push.PrimeAtmosphereHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.security.Principal;
/**
* Created by tuukka on 28.3.2015.
*/
@RequestScoped
@Path("/appconfig/v1/instances")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON + "; charset=UTF-8"})
@Api(value = "/appconfig/v1/instances", description = "Application instances")
public class InstancesV1 {
@EJB
PermissionBeanLocal permissionBean;
@EJB
ApiApplicationBeanLocal applicationBean;
private static final Logger logger = LoggerFactory.getLogger(InstancesV1.class);
@Context
private HttpServletRequest servletRequest;
@POST
@Path("/create/")
@ApiOperation(value = "Creates new unauthorized application instance for user to enable", response = ApplicationInstancePojo.class)
@ApiResponse(code = 200, message = "Returns instance-object, which includes keys etc.")
@Consumes({MediaType.APPLICATION_FORM_URLENCODED})
public Response createApplicationInstance(@FormParam("appkey") String applicationkey,
@FormParam("username") String username) {
ApiApplicationInstance instance = applicationBean.createApplicationInstance(applicationkey, username);
if (instance == null)
return Response.status(Response.Status.BAD_REQUEST).build();
return Response.ok(PojoUtils.parseApplicationInstance(instance)).build();
}
@POST
@Path("/createAuthorized/")
@ApiOperation(value = "Creates new authorized application instance for user. Only for trusted applications. TODO: also way to create disabled applicationinstance for user to enable", response = ApplicationInstancePojo.class)
@ApiResponse(code = 200, message = "Returns instance-object, which includes keys etc.")
@Consumes({MediaType.APPLICATION_FORM_URLENCODED})
public Response createApplicationInstance(@FormParam("appkey") String applicationkey,
@FormParam("username") String username,
@FormParam("password") String password) {
// Copypasta from user / auth -restview
logger.info("Tried to login with rest {} , {}", username, password);
try {
Principal principal = servletRequest.getUserPrincipal();
if (principal != null) {
logger.info("Current username {}", principal.getName());
if (principal.getName() != null && !principal.getName().equals(username)) {
logger.info("Trying to logout from user {}", principal.getName());
servletRequest.logout();
}
}
if (principal == null || principal.getName() == null || !principal.getName().equals(username)) {
servletRequest.getSession(true);
servletRequest.login(username, password);
}
} catch (ServletException e) {
logger.info("Rest login failed");
}
// end of copypasta
if (permissionBean.getCurrentUser().isAnonymous()) {
return Response.status(Response.Status.FORBIDDEN).build();
}
ApiApplicationInstance instance = applicationBean.createApplicationInstance(applicationkey);
if (instance == null)
return Response.status(Response.Status.BAD_REQUEST).build();
return Response.ok(PojoUtils.parseApplicationInstance(instance)).build();
}
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!