Commit 7ac50927 by Tuomas Riihimäki

Oho.. tais tulla taas vähän iso.. Tänään puljattu tietokantaa ja korjattu kuvan lähetys

1 parent 47e28be6
Showing with 1293 additions and 986 deletions
......@@ -106,13 +106,13 @@ public class BortalLoginModule extends AppservPasswordLoginModule {
throw new LoginException(
(new StringBuilder())
.append("An InvalidOperationException was thrown "
).append(" while calling getGroupNames() on the SampleRealm ")
).append(" while calling getGroupNames() on the SampleRealm ")
.append(invalidoperationexception).toString());
} catch (NoSuchUserException nosuchuserexception) {
throw new LoginException(
(new StringBuilder())
.append("A NoSuchUserException was thrown "
).append(" while calling getGroupNames() on the SampleRealm ")
).append(" while calling getGroupNames() on the SampleRealm ")
.append(nosuchuserexception).toString());
}
ArrayList<String> authenticatedGroups = new ArrayList<String>();
......@@ -125,10 +125,10 @@ public class BortalLoginModule extends AppservPasswordLoginModule {
// Call commitUserAuthentication with the groupNames the user belongs to
String[] groups = authenticatedGroups.toArray(new String[authenticatedGroups.size()]);
System.out.println("groups: " + groups.length);
for (String str : groups) {
System.out.println("Str " + str);
}
// System.out.println("groups: " + groups.length);
// for (String str : groups) {
// System.out.println("Str " + str);
// }
commitUserAuthentication(groups);
}
......
/**
* Generated by Gas3 v2.2.0 (Granite Data Services).
*
* WARNING: DO NOT CHANGE THIS FILE. IT MAY BE OVERWRITTEN EACH TIME YOU USE
* THE GENERATOR.
*/
package fi.insomnia.bortal {
public interface RealmBeanRemote {
}
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 EJB 3.0//EN" "http://www.sun.com/software/appserver/dtds/sun-ejb-jar_3_0-0.dtd">
<sun-ejb-jar>
<security-role-mapping>
<role-name>USER/READ_ROLES</role-name>
<group-name>USER/READ_ROLES</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>USER/WRITE_ROLES</role-name>
<group-name>USER/WRITE_ROLES</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>USER/VIEW_ALL</role-name>
<group-name>USER/VIEW_ALL</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>USER/VIEW_SELF</role-name>
<group-name>USER/VIEW_SELF</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>USER/CREATE_NEW</role-name>
<group-name>USER/CREATE_NEW</group-name>
<principal-name>ANONYMOUS</principal-name>
</security-role-mapping>
<security-role-mapping>
<role-name>USER/MODIFY</role-name>
<group-name>USER/MODIFY</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>SUPERADMIN</role-name>
<group-name>SUPERADMIN</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>BILL/WRITE_ALL</role-name>
<group-name>BILL/WRITE_ALL</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>POLL/ANSWER</role-name>
<group-name>POLL/ANSWER</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>POLL/ANSWER</role-name>
<group-name>POLL/ANSWER</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>POLL/VIEW_RESULTS</role-name>
<group-name>POLL/VIEW_RESULTS</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>POLL/CREATE</role-name>
<group-name>POLL/CREATE</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>BILL/READ_ALL</role-name>
<group-name>BILL/READ_ALL</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>BILL/CREATE_BILL</role-name>
<group-name>BILL/CREATE_BILL</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>LOGIN/LOGOUT</role-name>
<group-name>LOGIN/LOGOUT</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>LOGIN/LOGIN</role-name>
<group-name>LOGIN/LOGIN</group-name>
<principal-name>ANONUMOUS</principal-name>
</security-role-mapping>
<security-role-mapping>
<role-name>MAP/MANAGE_OTHERS</role-name>
<group-name>MAP/MANAGE_OTHERS</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>MAP/BUY_PLACES</role-name>
<group-name>MAP/BUY_PLACES</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>MAP/VIEW</role-name>
<group-name>MAP/VIEW</group-name>
<principal-name>ANONUMOUS</principal-name>
</security-role-mapping>
<security-role-mapping>
<role-name>MAP/MANAGE_MAPS</role-name>
<group-name>MAP/MANAGE_MAPS</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>SHOP/LIST_ALL_PRODUCTS</role-name>
<group-name>SHOP/LIST_ALL_PRODUCTS</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>SHOP/MANAGE_PRODUCTS</role-name>
<group-name>SHOP/MANAGE_PRODUCTS</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>ROLE_MANAGEMENT/WRITE</role-name>
<group-name>ROLE_MANAGEMENT/WRITE</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>SHOP/SHOP_PRODUCTS</role-name>
<group-name>SHOP/SHOP_PRODUCTS</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>SHOP/LIST_USERPRODUCTS</role-name>
<group-name>SHOP/LIST_USERPRODUCTS</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>USER</role-name>
<group-name>USER</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>USER/LOGIN</role-name>
<group-name>USER/LOGIN</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>MAP/READ</role-name>
<group-name>MAP/READ</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>SHOP/SHOP_TO_OTHERS</role-name>
<group-name>SHOP/SHOP_TO_OTHERS</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>ANONYMOUS</role-name>
<group-name>ANONYMOUS</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>ANONYMOUS</role-name>
<group-name>ANONYMOUS</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>ANONYMOUS</role-name>
<group-name>ANONYMOUS</group-name>
</security-role-mapping>
<enterprise-beans/>
</sun-ejb-jar>
......@@ -10,7 +10,6 @@ import org.slf4j.LoggerFactory;
import fi.insomnia.bortal.facade.EventMapFacade;
import fi.insomnia.bortal.model.EventMap;
import fi.insomnia.bortal.model.EventPk;
import fi.insomnia.bortal.model.LanEvent;
/**
......@@ -50,8 +49,7 @@ public class EventMapBean implements EventMapBeanLocal {
@Override
@RolesAllowed("MAP/MANAGE_MAPS")
public void sendImage(int destId, byte[] imagedata) {
LanEvent event = eventbean.getCurrentEvent();
EventMap map = eventmapfacade.find(event, destId);
EventMap map = eventmapfacade.find(destId);
logger.debug("Setting mapdata for map {}", map);
if (map != null) {
map.setMapData(imagedata);
......@@ -62,6 +60,6 @@ public class EventMapBean implements EventMapBeanLocal {
@Override
@RolesAllowed("MAP/MANAGE_MAPS")
public EventMap find(Integer mapId) {
return eventmapfacade.find(new EventPk(eventbean.getCurrentEvent(), mapId));
return eventmapfacade.find(mapId);
}
}
......@@ -11,9 +11,9 @@ import javax.ejb.Stateless;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fi.insomnia.bortal.enums.BeanRole;
import fi.insomnia.bortal.enums.BortalApplication;
import fi.insomnia.bortal.enums.apps.IAppPermission;
import fi.insomnia.bortal.enums.apps.SpecialPermission;
import fi.insomnia.bortal.facade.UserFacade;
import fi.insomnia.bortal.model.ApplicationPermission;
import fi.insomnia.bortal.model.LanEvent;
......@@ -76,19 +76,22 @@ public class JaasBean implements JaasBeanLocal, JaasBeanRemote {
HashSet<String> roleset = new HashSet<String>();
if (usr == null) {
usr = permbean.getAnonUser();
roleset.add(SpecialPermission.ANONYMOUS.name());
}
if (usr != null && !usr.isAnonymous()) {
roleset.add("USER");
roleset.add(SpecialPermission.USER.name());
}
// TODO: EI NÄIN!!!!! Superadmin ei saa kaikkia oikkia!!
if (usr.isSuperadmin()) {
if (usr != null && usr.isSuperadmin()) {
for (BortalApplication app : BortalApplication.values()) {
for (IAppPermission perm : app.getPermissions()) {
roleset.add(perm.getFullName());
}
}
roleset.add(BeanRole.SUPERADMIN.name());
roleset.add(SpecialPermission.SUPERADMIN.name());
} else {
List<Role> usrroles = userbean.localFindUsersRoles(usr);
for (Role role : usrroles) {
for (ApplicationPermission apperm : role.getPermissions()) {
......
......@@ -15,6 +15,7 @@ import fi.insomnia.bortal.enums.apps.BillPermission;
import fi.insomnia.bortal.enums.apps.IAppPermission;
import fi.insomnia.bortal.enums.apps.MapPermission;
import fi.insomnia.bortal.enums.apps.ShopPermission;
import fi.insomnia.bortal.enums.apps.SpecialPermission;
import fi.insomnia.bortal.enums.apps.UserPermission;
import fi.insomnia.bortal.facade.UserFacade;
import fi.insomnia.bortal.model.User;
......@@ -26,11 +27,11 @@ import fi.insomnia.bortal.model.User;
UserPermission.S_LOGOUT,
UserPermission.S_MODIFY,
UserPermission.S_MODIFY_ACCOUNTEVENTS,
UserPermission.S_READ_ROLES,
UserPermission.S_VIEW_ACCOUNTEVENTS,
UserPermission.S_VIEW_ALL,
UserPermission.S_VIEW_SELF,
UserPermission.S_WRITE_ROLES,
UserPermission.S_READ_ROLES,
MapPermission.S_VIEW,
MapPermission.S_MANAGE_MAPS,
......@@ -46,8 +47,12 @@ import fi.insomnia.bortal.model.User;
BillPermission.S_CREATE_BILL,
BillPermission.S_READ_ALL,
BillPermission.S_WRITE_ALL,
BillPermission.S_VIEW_OWN,
"ANONYMOUS", "SUPERADMIN", "USER" })
SpecialPermission.S_SUPERADMIN,
SpecialPermission.S_USER,
SpecialPermission.S_ANONYMOUS,
})
public class PermissionBean implements PermissionBeanLocal {
private static final Logger logger = LoggerFactory.getLogger(PermissionBean.class);
......@@ -61,8 +66,6 @@ public class PermissionBean implements PermissionBeanLocal {
@EJB
private UserFacade userfacade;
private UserBean userbean;
//
// @Override
// public boolean hasPermission(String perm) {
......@@ -72,8 +75,11 @@ public class PermissionBean implements PermissionBeanLocal {
@Override
public boolean hasPermission(IAppPermission perm) {
return getCurrentUser().isSuperadmin()
|| context.isCallerInRole(perm.getFullName());
if (perm == null)
{
return true;
}
return perm == null || context.isCallerInRole(perm.getFullName());
}
......
......@@ -144,12 +144,8 @@ public class PlaceBean implements PlaceBeanLocal {
// TODO: Kantakysely tähän!
@Override
public Place findPlace(EventMap e, int x, int y) {
for (Place place : e.getPlaces()) {
if (place.isCoordinateInPlace(x, y)) {
return placeFacade.find(place.getId());
}
}
return null;
return placeFacade.find(e, x, y);
}
......@@ -195,16 +191,19 @@ public class PlaceBean implements PlaceBeanLocal {
placeFacade.timeoutPlaces();
}
@Override
public void releaseUsersPlaces(User user) throws PermissionDeniedException {
if (user == null) {
user = permbean.getCurrentUser();
} else if (!permbean.isCurrentUser(user)) {
permbean.fatalPermission(MapPermission.MANAGE_OTHERS, "Not enough rights to release users ", user, " places");
}
logger.debug("timeouting places");
placeFacade.releasePlaces(permbean.getCurrentUser());
}
//
// @Override
// public void releaseUsersPlaces(User user) throws
// PermissionDeniedException {
// if (user == null) {
// user = permbean.getCurrentUser();
// } else if (!permbean.isCurrentUser(user)) {
// permbean.fatalPermission(MapPermission.MANAGE_OTHERS,
// "Not enough rights to release users ", user, " places");
// }
// logger.debug("timeouting places");
// placeFacade.releasePlaces(permbean.getCurrentUser());
// }
@Override
@RolesAllowed(MapPermission.S_BUY_PLACES)
......@@ -224,17 +223,16 @@ public class PlaceBean implements PlaceBeanLocal {
return null;
}
for (Entry<Product, Integer> line : getPlaceProductcount(places).entrySet()) {
productBean.createAccountEvent(line.getKey(), new BigDecimal(line.getValue()), user);
}
// PlaceGroup pg = pgbean.createPlaceGroup(user);
BigDecimal totalprice = totalReservationPrice(user, null);
BigDecimal balance = user.getAccountBalance();
if (balance.compareTo(totalprice) < 0) {
logger.debug("User {} Could not buy things because account balance is too low!", user);
return null;
logger.info("User {} Could not buy things because account balance {} is too low for purchase {}", new Object[] { user, balance, totalprice });
}
for (Entry<Product, Integer> line : getPlaceProductcount(places).entrySet()) {
productBean.createAccountEvent(line.getKey(), new BigDecimal(line.getValue()), user);
}
PlaceGroup pg = new PlaceGroup(event, Calendar.getInstance(), Calendar.getInstance(), true);
......@@ -251,7 +249,7 @@ public class PlaceBean implements PlaceBeanLocal {
}
// adding account event does funny stuff. evicting helps...
userfacade.evict(user);
userfacade.evict();
return pg;
}
......@@ -303,7 +301,7 @@ public class PlaceBean implements PlaceBeanLocal {
// Current user temporarily used at place reservation. When buying
// release field for its original use ( show who is sitting here ).
p.setCurrentUser(null);
GroupMembership membership = new GroupMembership(p.getEvent(), pg, p, gmemfacade.createInviteToken(p.getEvent()));
GroupMembership membership = new GroupMembership(pg, p, gmemfacade.createInviteToken());
pg.getMembers().add(membership);
p.setPlaceReserver(membership);
......@@ -413,7 +411,7 @@ public class PlaceBean implements PlaceBeanLocal {
@Override
@RolesAllowed(MapPermission.S_MANAGE_MAPS)
public Place find(int placeId) {
return placeFacade.find(eventBean.getCurrentEvent(), placeId);
return placeFacade.find(placeId);
}
@Override
......
......@@ -69,14 +69,14 @@ public class PlaceGroupBean implements PlaceGroupBeanLocal {
@Override
@RolesAllowed("USER")
public List<GroupMembership> getMembershipsAndCreations(User user) {
List<GroupMembership> ret = gmemfacade.findMemberOrCreator(eventbean.getCurrentEvent(), user);
List<GroupMembership> ret = gmemfacade.findMemberOrCreator(user);
return ret;
}
@Override
@RolesAllowed("USER")
public List<GroupMembership> getMemberships(User user) {
List<GroupMembership> ret = gmemfacade.findMemberships(eventbean.getCurrentEvent(), user);
List<GroupMembership> ret = gmemfacade.findMemberships(user);
return ret;
}
......@@ -162,11 +162,10 @@ public class PlaceGroupBean implements PlaceGroupBeanLocal {
@Override
public void releaseAndGenerateToken(GroupMembership gmem) throws PermissionDeniedException {
gmem = gmemfacade.find(gmem.getId());
if (!permbean.getCurrentUser().getId().equals(gmem.getPlaceGroup().getCreator().getId()) ||
!permbean.hasPermission(MapPermission.MANAGE_OTHERS)) {
if (!(permbean.getCurrentUser().getId().equals(gmem.getPlaceGroup().getCreator().getId()) || permbean.hasPermission(MapPermission.MANAGE_OTHERS))) {
throw new PermissionDeniedException(loggingbean, permbean.getCurrentUser(), "User tried to release and generate group membership: " + gmem);
}
gmem.setUser(null);
gmem.setInviteToken(gmemfacade.createInviteToken(eventbean.getCurrentEvent()));
gmem.setInviteToken(gmemfacade.createInviteToken());
}
}
......@@ -31,11 +31,16 @@ public class PlaceMapBean implements PlaceMapBeanLocal {
@Override
public Long selectablePlaceCount(EventMap map) {
return placeFacade.countSelectable(map);
return eventMapFacade.countSelectable(map);
}
@Override
public EventMap findMap(Integer mapId) {
return eventMapFacade.find(eventbean.getCurrentEvent().getId(), mapId);
return eventMapFacade.find(mapId);
}
@Override
public Long availablePlaceCount(EventMap map) {
return eventMapFacade.countAvailable(map);
}
}
......@@ -117,7 +117,7 @@ public class PollBean implements PollBeanLocal {
@Override
public PossibleAnswer findPossibleAnwerById(int id) {
PossibleAnswer ans = possibleAnswerFacade.find(eventBean.getCurrentEvent().getId(), new Integer(id));
PossibleAnswer ans = possibleAnswerFacade.find(eventBean.getCurrentEvent().getId(), Integer.valueOf(id));
logger.debug("Searching from facade {} found {}", id, ans.getId().getId());
return ans;
}
......
......@@ -72,7 +72,7 @@ public class ProductBean implements ProductBeanLocal {
@Override
@RolesAllowed("SHOP/LIST_ALL_PRODUCTS")
public List<Product> getProducts() {
return productFacade.findAll(eventBean.getCurrentEvent());
return productFacade.findAll();
}
@Override
......@@ -152,13 +152,13 @@ public class ProductBean implements ProductBeanLocal {
@Override
public Product findById(int id) {
return productFacade.find(eventBean.getCurrentEvent().getId(), id);
return productFacade.find(id);
}
@Override
@RolesAllowed("SHOP/LIST_ALL_PRODUCTS")
public List<Product> findForStaffshop() {
return productFacade.findAll(eventBean.getCurrentEvent());
return productFacade.findAll();
}
@RolesAllowed("SHOP/MANAGE_PRODUCTS")
......
......@@ -69,25 +69,25 @@ public class TestDataBean implements TestDataBeanLocal {
}
@Override
public void writeMap(byte[] bytes) {
EventMap map = new EventMap(eventBean.getCurrentEvent());
map.setName("test" + bytes);
// StringBuilder sb = new StringBuilder();
// for (int i = 0; i < bytes; ++i) {
//
// sb.append((char) (33 + i % 92));
// }
map.setMapData(bytes);
eventMapFacade.create(map);
}
@Override
public EventMap readMap(long bytes) {
return eventMapFacade.findByName("test" + bytes);
// @Override
// public void writeMap(byte[] bytes) {
// EventMap map = new EventMap(eventBean.getCurrentEvent());
// map.setName("test" + bytes);
// // StringBuilder sb = new StringBuilder();
// // for (int i = 0; i < bytes; ++i) {
// //
// // sb.append((char) (33 + i % 92));
// // }
// map.setMapData(bytes);
// eventMapFacade.create(map);
// }
}
// @Override
// public EventMap readMap(long bytes) {
//
// return eventMapFacade.findByName("test" + bytes);
//
// }
/**
* Default constructor.
......@@ -203,11 +203,13 @@ public class TestDataBean implements TestDataBeanLocal {
@Override
public EventMap generateTestMap() {
LanEvent event = eventBean.getCurrentEvent();
InputStream stream = null;
try {
logger.info("Generating Test Map for event: " + event);
EventMap map = new EventMap(event);
InputStream stream = getClass().getResourceAsStream(TEST_MAP_IMAGE_NAME);
stream = getClass().getResourceAsStream(TEST_MAP_IMAGE_NAME);
File file = new File(getClass().getResource(TEST_MAP_IMAGE_NAME).toURI());
long length = file.length();
......@@ -227,8 +229,6 @@ public class TestDataBean implements TestDataBeanLocal {
throw new IOException("Could not completely read file " + file.getName());
}
stream.close();
map.setMapData(bytes);
map.setName("test0");
eventMapFacade.create(map);
......@@ -239,6 +239,17 @@ public class TestDataBean implements TestDataBeanLocal {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} finally
{
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
// ignore at this point
}
}
}
return null;
}
......@@ -264,11 +275,11 @@ public class TestDataBean implements TestDataBeanLocal {
@Override
public void printPlacesInfo() {
logger.debug("Fetching places");
List<Place> places = placeFacade.findAll(eventBean.getCurrentEvent());
List<Place> places = placeFacade.findAll();
logger.debug("Got places: {}", places);
logger.info("Printing info from places");
for (Place place : places) {
logger.info("Place id: {}. Event Map id: {}.", place.getId().getId(), place.getMap().getId().getId());
logger.info("Place id: {}. Event Map id: {}.", place.getId(), place.getMap().getId());
}
}
......
......@@ -18,6 +18,7 @@ import javax.persistence.PersistenceContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fi.insomnia.bortal.enums.apps.SpecialPermission;
import fi.insomnia.bortal.enums.apps.UserPermission;
import fi.insomnia.bortal.facade.GroupMembershipFacade;
import fi.insomnia.bortal.facade.UserFacade;
......@@ -38,7 +39,7 @@ import fi.insomnia.bortal.utilities.SearchResult;
*/
@LocalBean
@Stateless
@DeclareRoles({ "USER/EXECUTE", "USER/VIEW_ALL", "USER" })
@DeclareRoles({ UserPermission.S_VIEW_ALL, SpecialPermission.S_USER })
public class UserBean implements UserBeanLocal {
private static final Logger logger = LoggerFactory.getLogger(UserBean.class);
......@@ -75,7 +76,7 @@ public class UserBean implements UserBeanLocal {
private GroupMembershipFacade gmfacade;
@Override
@RolesAllowed("USER/VIEW_ALL")
@RolesAllowed(UserPermission.S_VIEW_ALL)
public List<User> getUsers() {
List<User> ret = userFacade.findAll();
......@@ -83,6 +84,7 @@ public class UserBean implements UserBeanLocal {
}
@Override
@RolesAllowed(SpecialPermission.S_USER)
public User mergeChanges(User user) throws PermissionDeniedException {
if (!permbean.isCurrentUser(user)) {
......@@ -113,20 +115,23 @@ public class UserBean implements UserBeanLocal {
public List<Role> localFindUsersRoles(User u) {
Set<Role> checkedRoles = new HashSet<Role>();
addRecursive(checkedRoles, u.getRoles());
if (u != null)
{
addRecursive(checkedRoles, u.getRoles());
if (permbean.isLoggedIn()) {
if (permbean.isLoggedIn()) {
LanEvent event = eventBean.getCurrentEvent();
// add roles from events default role.
addRecursive(checkedRoles, event.getDefaultRole());
LanEvent event = eventBean.getCurrentEvent();
// add roles from events default role.
addRecursive(checkedRoles, event.getDefaultRole());
// add roles from accountEvents of the user
addRecursive(checkedRoles, acbean.getRolesFromAccountEvents(u));
// add roles from accountEvents of the user
addRecursive(checkedRoles, acbean.getRolesFromAccountEvents(u));
for (GroupMembership member : groupMembershipFacade.findMemberships(event, u)) {
addRecursive(checkedRoles, member.getPlaceReservation().getProvidesRole());
for (GroupMembership member : groupMembershipFacade.findMemberships(u)) {
addRecursive(checkedRoles, member.getPlaceReservation().getProvidesRole());
}
}
}
return new ArrayList<Role>(checkedRoles);
......@@ -150,7 +155,7 @@ public class UserBean implements UserBeanLocal {
}
@Override
@RolesAllowed("USER")
@RolesAllowed(SpecialPermission.S_USER)
public UserImage uploadImage(Integer userid, String contentType, byte[] image, String filename, String description) throws PermissionDeniedException {
User user = permbean.getCurrentUser();
logger.debug("uploading image to userid {}", userid);
......@@ -158,7 +163,7 @@ public class UserBean implements UserBeanLocal {
userid = user.getId();
}
if (!permbean.getCurrentUser().getId().equals(userid)) {
if (!user.getId().equals(userid)) {
permbean.fatalPermission(UserPermission.MODIFY, "usert tried to save picture to userid " + userid + " without sufficient permissions!");
user = userFacade.find(userid);
}
......@@ -167,13 +172,11 @@ public class UserBean implements UserBeanLocal {
userimage.setImageData(image);
userimage.setName(filename);
userimage.setDescription(description);
userimagefacade.create(userimage);
// setting uploaded image as the default.
user.setCurrentImage(userimage);
user.getUserImageList().add(userimage);
userFacade.merge(user);
// setting uploaded image as the default.
user.setCurrentImage(userimage);
return userimage;
}
......@@ -236,7 +239,7 @@ public class UserBean implements UserBeanLocal {
@Override
public User initPasswordReset(User user, String hash, String mailpath) {
if (hash == null || hash.length() < 20 || user == null || user.getEmail() == null || user.getEmail().length() <= 5) {
logger.info("Not sending email with params {} {} {}", new Object[] { user, user.getEmail(), hash });
logger.info("Not sending email with params {} {}", new Object[] { user, hash });
return null;
}
logger.info("sending mail! user {} hash {} path {}", new Object[] { user, hash, mailpath });
......@@ -283,7 +286,7 @@ public class UserBean implements UserBeanLocal {
pg.setCreator(creator);
pg.setName("Invitebean");
String token = PasswordFunctions.generateRandomString(30, PasswordFunctions.ALL_CHARS);
pg.getMembers().add(new GroupMembership(ev, pg, null, token));
pg.getMembers().add(new GroupMembership(pg, null, token));
creator.getPlaceGroups().add(pg);
return true;
......@@ -291,7 +294,7 @@ public class UserBean implements UserBeanLocal {
@Override
public GroupMembership findToken(String token) {
return gmfacade.findToken(token);
return gmfacade.findByToken(token);
}
@Override
......
package fi.insomnia.bortal.facade;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import fi.insomnia.bortal.model.EventMap;
import fi.insomnia.bortal.model.Place;
import fi.insomnia.bortal.model.Place_;
@Stateless
@LocalBean
public class EventMapFacade extends EventChildGenericFacade<EventMap> {
public class EventMapFacade extends GenericFacade<Integer, EventMap> {
@PersistenceContext
private EntityManager em;
@PersistenceContext
private EntityManager em;
@EJB
private EventMapFacade mapfacade;
public EventMapFacade() {
super(EventMap.class);
}
public EventMapFacade() {
super(EventMap.class);
}
@Override
protected EntityManager getEm() {
return em;
}
protected EntityManager getEm() {
return em;
}
public Long countAvailable(EventMap map) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Long> cq = cb.createQuery(Long.class);
public EventMap getMapById(Integer eventId, Integer id) {
return mapfacade.find(eventId, id);
}
Root<Place> root = cq.from(Place.class);
public EventMap findByName(String name) {
TypedQuery<EventMap> q = em.createNamedQuery("EventMap.findByName", EventMap.class);
q.setParameter("name", name);
return getSingleNullableResult(q);
}
cq.select(cb.count(root));
cq.where(
cb.equal(root.get(Place_.map), map),
cb.isFalse(root.get(Place_.disabled))
);
return getSingleNullableResult(em.createQuery(cq));
}
public Long countSelectable(EventMap map) {
if (map == null) {
return null;
}
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<Long> cq = cb.createQuery(Long.class);
Root<Place> root = cq.from(Place.class);
cq.select(cb.count(root));
cq.where(
cb.equal(root.get(Place_.map), map),
cb.isNull(root.get(Place_.releaseTime)),
cb.isNull(root.get(Place_.group)),
cb.isFalse(root.get(Place_.disabled))
);
return getSingleNullableResult(em.createQuery(cq));
}
}
......@@ -182,8 +182,8 @@ public abstract class GenericFacade<I extends Serializable, C extends ModelInter
}
private Root<C> searchCallbacks(CriteriaQuery<?> cq, List<FacadeCallback<C>> list) {
Root<C> root = cq.from(getEntityClass());
CriteriaBuilder cb = getEm().getCriteriaBuilder();
Root<C> root = cq.from(getEntityClass());
ArrayList<Predicate> predicates = new ArrayList<Predicate>();
for (FacadeCallback<C> fc : list) {
......
......@@ -2,28 +2,39 @@ package fi.insomnia.bortal.facade;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fi.insomnia.bortal.beans.EventBeanLocal;
import fi.insomnia.bortal.model.GroupMembership;
import fi.insomnia.bortal.model.LanEvent;
import fi.insomnia.bortal.model.GroupMembership_;
import fi.insomnia.bortal.model.PlaceGroup;
import fi.insomnia.bortal.model.PlaceGroup_;
import fi.insomnia.bortal.model.Place_;
import fi.insomnia.bortal.model.User;
import fi.insomnia.bortal.utilities.PasswordFunctions;
@Stateless
@LocalBean
public class GroupMembershipFacade extends EventChildGenericFacade<GroupMembership> {
public class GroupMembershipFacade extends GenericFacade<Integer, GroupMembership> {
private static final Logger logger = LoggerFactory.getLogger(GroupMembershipFacade.class);
@PersistenceContext
private EntityManager em;
@EJB
private EventBeanLocal eventbean;
public GroupMembershipFacade() {
super(GroupMembership.class);
}
......@@ -33,14 +44,14 @@ public class GroupMembershipFacade extends EventChildGenericFacade<GroupMembersh
return em;
}
public String createInviteToken(LanEvent event) {
public String createInviteToken() {
String token = null;
GroupMembership gm = null;
do {
if (token != null) {
logger.info("Generated token {} found from GoupMembership: {} Generating new!", token, gm);
}
token = event.getId().toString();
token = eventbean.getCurrentEvent().getId().toString();
token += PasswordFunctions.generateRandomString(15);
gm = findByToken(token);
} while (gm != null);
......@@ -48,30 +59,59 @@ public class GroupMembershipFacade extends EventChildGenericFacade<GroupMembersh
}
public GroupMembership findByToken(String token) {
TypedQuery<GroupMembership> q = em.createQuery("Select gm from GroupMembership gm where gm.inviteToken = :token ", GroupMembership.class);
q.setParameter("token", token);
return getSingleNullableResult(q);
}
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<GroupMembership> cq = cb.createQuery(GroupMembership.class);
Root<GroupMembership> root = cq.from(GroupMembership.class);
cq.where(cb.equal(root.get(GroupMembership_.inviteToken), token),
cb.equal(root.get(GroupMembership_.placeGroup).get(PlaceGroup_.event), eventbean.getCurrentEvent())
);
public List<GroupMembership> findMemberOrCreator(LanEvent event, User user) {
TypedQuery<GroupMembership> p = em.createQuery("select gm from GroupMembership gm where gm.id.eventId = :eventid and (gm.placeGroup.creator = :user or gm.user = :user) order by gm.placeReservation.name", GroupMembership.class);
p.setParameter("eventid", event.getId());
p.setParameter("user", user);
return p.getResultList();
// TypedQuery<GroupMembership> q =
// em.createQuery("Select gm from GroupMembership gm where gm.inviteToken = :token ",
// GroupMembership.class);
// q.setParameter("token", token);
return getSingleNullableResult(em.createQuery(cq));
}
public List<GroupMembership> findMemberships(LanEvent event, User user) {
TypedQuery<GroupMembership> p = em.createQuery("select gm from GroupMembership gm where gm.id.eventId = :eventid and gm.user = :user", GroupMembership.class);
p.setParameter("eventid", event.getId());
p.setParameter("user", user);
return p.getResultList();
public List<GroupMembership> findMemberOrCreator(User user) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<GroupMembership> cq = cb.createQuery(GroupMembership.class);
Root<GroupMembership> root = cq.from(GroupMembership.class);
Path<PlaceGroup> pg = root.get(GroupMembership_.placeGroup);
cq.where(cb.or(cb.equal(root.get(GroupMembership_.user), user),
cb.equal(pg.get(PlaceGroup_.creator), user)
),
cb.equal(pg.get(PlaceGroup_.event), eventbean.getCurrentEvent())
);
cq.orderBy(cb.asc(root.get(GroupMembership_.placeReservation).get(Place_.name)));
// TypedQuery<GroupMembership> p =
// em.createQuery("select gm from GroupMembership gm where gm.id.eventId = :eventid and (gm.placeGroup.creator = :user or gm.user = :user) order by gm.placeReservation.name",
// GroupMembership.class);
// p.setParameter("eventid", event.getId());
// p.setParameter("user", user);
return em.createQuery(cq).getResultList();
}
public GroupMembership findToken(String token) {
TypedQuery<GroupMembership> q = em.createQuery("select gm from GroupMembership gm where gm.inviteEmail = :mail", GroupMembership.class);
q.setParameter("mail", token);
public List<GroupMembership> findMemberships(User user) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<GroupMembership> cq = cb.createQuery(GroupMembership.class);
Root<GroupMembership> root = cq.from(GroupMembership.class);
Path<PlaceGroup> pg = root.get(GroupMembership_.placeGroup);
cq.where(cb.equal(root.get(GroupMembership_.user), user),
cb.equal(pg.get(PlaceGroup_.event), eventbean.getCurrentEvent())
);
return em.createQuery(cq).getResultList();
return getSingleNullableResult(q);
// TypedQuery<GroupMembership> p =
// em.createQuery("select gm from GroupMembership gm where gm.id.eventId = :eventid and gm.user = :user",
// GroupMembership.class);
// p.setParameter("eventid", event.getId());
// p.setParameter("user", user);
// return p.getResultList();
}
}
......@@ -7,16 +7,17 @@ import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fi.insomnia.bortal.model.EventMap;
import fi.insomnia.bortal.model.EventMap_;
import fi.insomnia.bortal.model.LanEvent;
import fi.insomnia.bortal.model.Place;
import fi.insomnia.bortal.model.Place_;
......@@ -24,7 +25,7 @@ import fi.insomnia.bortal.model.User;
@Stateless
@LocalBean
public class PlaceFacade extends EventChildGenericFacade<Place> {
public class PlaceFacade extends GenericFacade<Integer, Place> {
private static final Logger logger = LoggerFactory.getLogger(PlaceFacade.class);
@PersistenceContext
......@@ -39,27 +40,6 @@ public class PlaceFacade extends EventChildGenericFacade<Place> {
return em;
}
//
// public boolean reservePlace(Place p, User reserver) {
// boolean ret = p.reserve(reserver);
// merge(p);
// return ret;
// }
//
// public List<Place> find(LanEvent event, List<Integer> placeIds) {
// if (placeIds == null || placeIds.size() <= 0) {
// return new ArrayList<Place>();
// }
//
// TypedQuery<Place> q =
// em.createQuery("Select p from Place p where p.id.eventId = :eventid and p.id.id IN :places",
// Place.class);
// q.setParameter("eventid", event.getId());
// q.setParameter("places", placeIds);
// return q.getResultList();
// }
public void timeoutPlaces() {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<Place> cq = cb.createQuery(Place.class);
......@@ -67,57 +47,22 @@ public class PlaceFacade extends EventChildGenericFacade<Place> {
Root<Place> root = cq.from(Place.class);
cq.select(root);
cq.where(cb.lessThan(root.get(Place_.releaseTime), Calendar.getInstance()));
cq.where(cb.lessThan(root.get(Place_.releaseTime), Calendar.getInstance()),
cb.isNull(root.get(Place_.group)));
TypedQuery<Place> q = getEm().createQuery(cq);
int updated = timeoutPlaces(q.getResultList(), true);
if (updated > 0) {
logger.info("{} places released for sale after release time exceeded.", updated);
}
}
private int timeoutPlaces(List<Place> places, boolean checkFromEntity) {
int updated = 0;
for (Place p : places) {
for (Place p : q.getResultList()) {
logger.debug("Releasing place {} at automagic timed place check.", p);
if (!checkFromEntity || p.checkReleased()) {
if (p.checkReleased()) {
++updated;
merge(p);
}
}
// logger.debug("Checking timeouted places took: {} ms",
// Calendar.getInstance().getTimeInMillis()-begin.getTimeInMillis());
return updated;
}
public Long countSelectable(EventMap map) {
if (map == null) {
return null;
}
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<Place> cq = cb.createQuery(Place.class);
Root<Place> root = cq.from(Place.class);
cq.select(root);
cq.where(
cb.and(
cb.equal(root.get(Place_.map), map),
cb.isNull(root.get(Place_.releaseTime))
));
TypedQuery<Place> q = getEm().createQuery(cq);
long count = 0;
for (Place p : q.getResultList()) {
if (p.getGroup() == null) {
++count;
}
if (updated > 0) {
logger.info("{} places released for sale after release time exceeded.", updated);
}
return count;
}
public List<Place> findUsersReservations(LanEvent event, User user) {
......@@ -129,7 +74,7 @@ public class PlaceFacade extends EventChildGenericFacade<Place> {
cq.select(root);
cq.where(
cb.and(
cb.equal(root.get(Place_.event), event),
cb.equal(root.get(Place_.map).get(EventMap_.event), event),
cb.equal(root.get(Place_.currentUser), user)
));
TypedQuery<Place> q = getEm().createQuery(cq);
......@@ -137,34 +82,52 @@ public class PlaceFacade extends EventChildGenericFacade<Place> {
return q.getResultList();
}
public void releasePlaces(User user) {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
public int setBuyable(EventMap map, String like, boolean b) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Place> cq = cb.createQuery(Place.class);
Root<Place> root = cq.from(Place.class);
cq.select(root);
cq.where(
cb.and(
cb.lessThan(root.get(Place_.releaseTime), Calendar.getInstance()),
cb.equal(root.get(Place_.currentUser), user)
));
TypedQuery<Place> q = getEm().createQuery(cq);
cb.like(root.get(Place_.name), like),
cb.equal(root.get(Place_.map), map)
);
List<Place> list = em.createQuery(cq).getResultList();
for (Place p : list) {
p.setBuyable(b);
}
// Query q =
// em.createQuery("UPDATE Place p set p.buyable = :b where p.name like :like");
// q.setParameter("b", b);
// q.setParameter("like", like);
return list.size();
int updated = timeoutPlaces(q.getResultList(), false);
logger.debug("Released {} places from user {}", updated, user);
}
public int setBuyable(EventMap map, String like, boolean b) {
// public boolean isCoordinateInPlace(int x, int y) {
// if (x > mapX
// && x < (mapX + width)
// && y > mapY
// && y < (mapY + height)) {
// return true;
// }
//
// return false;
// }
public Place find(EventMap map, int x, int y) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Place> cq = cb.createQuery(Place.class);
Root<Place> root = cq.from(Place.class);
Query q = em.createQuery("UPDATE Place p set p.buyable = :b where p.name like :like");
q.setParameter("b", b);
q.setParameter("like", like);
return q.executeUpdate();
Path<Integer> xObj = root.get(Place_.mapX);
Path<Integer> yObj = root.get(Place_.mapY);
cq.where(cb.equal(root.get(Place_.map), map),
cb.lessThan(xObj, x),
cb.greaterThan(cb.sum(xObj, root.get(Place_.width)), x),
cb.lessThan(yObj, y),
cb.greaterThan(cb.sum(yObj, root.get(Place_.height)), y),
cb.isFalse(root.get(Place_.disabled))
);
return getSingleNullableResult(em.createQuery(cq));
}
}
......@@ -4,21 +4,23 @@ import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import fi.insomnia.bortal.model.PlaceGroup;
@Stateless
@LocalBean
public class PlaceGroupFacade extends EventChildGenericFacade<PlaceGroup> {
public class PlaceGroupFacade extends GenericFacade<Integer, PlaceGroup> {
@PersistenceContext
private EntityManager em;
@PersistenceContext
private EntityManager em;
public PlaceGroupFacade() {
super(PlaceGroup.class);
}
public PlaceGroupFacade() {
super(PlaceGroup.class);
}
protected EntityManager getEm() {
return em;
}
@Override
protected EntityManager getEm() {
return em;
}
}
......@@ -18,7 +18,7 @@ import fi.insomnia.bortal.model.Product_;
@Stateless
@LocalBean
public class ProductFacade extends EventChildGenericFacade<Product> {
public class ProductFacade extends GenericFacade<Integer, Product> {
@PersistenceContext
private EntityManager em;
......
package fi.insomnia.bortal.facade;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.ejb.LocalBean;
......@@ -15,7 +17,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fi.insomnia.bortal.facade.callbacks.OrderCallback;
import fi.insomnia.bortal.facade.callbacks.StringPredicateField;
import fi.insomnia.bortal.facade.callbacks.StringSearchPredicateCreator;
import fi.insomnia.bortal.model.User;
import fi.insomnia.bortal.model.User_;
......@@ -27,18 +28,32 @@ public class UserFacade extends GenericFacade<Integer, User> {
private static final Logger logger = LoggerFactory.getLogger(UserFacade.class);
private enum Userfields implements StringPredicateField<User> {
nick(User_.nick), login(User_.login), firstnames(User_.firstnames), lastname(User_.lastname), email(User_.email);
private SingularAttribute<User, String> field;
Userfields(SingularAttribute<User, String> f) {
field = f;
}
// private enum Userfields implements StringPredicateField<User> {
// nick(User_.nick), login(User_.login), firstnames(User_.firstnames),
// lastname(User_.lastname), email(User_.email);
// private SingularAttribute<User, String> field;
//
// Userfields(SingularAttribute<User, String> f) {
// field = f;
// }
//
// @Override
// public SingularAttribute<User, String> getField() {
// return field;
// }
// }
@Override
public SingularAttribute<User, String> getField() {
return field;
}
private static final List<SingularAttribute<User, String>> SEARCHATTRS;
static {
ArrayList<SingularAttribute<User, String>> buildAttrs = new ArrayList<SingularAttribute<User, String>>();
buildAttrs.add(User_.nick);
buildAttrs.add(User_.login);
buildAttrs.add(User_.firstnames);
buildAttrs.add(User_.lastname);
buildAttrs.add(User_.email);
buildAttrs.add(User_.phone);
SEARCHATTRS = Collections.unmodifiableList(buildAttrs);
}
// final String[] NAMEFIELDS = { "nick", "login", "firstnames", "lastname",
......@@ -103,7 +118,7 @@ public class UserFacade extends GenericFacade<Integer, User> {
}
return super.searcher(page, pagesize,
new StringSearchPredicateCreator<User>(search, Userfields.values()),
new StringSearchPredicateCreator<User>(search, SEARCHATTRS),
new OrderCallback<User>(true, sort)
);
......@@ -128,4 +143,8 @@ public class UserFacade extends GenericFacade<Integer, User> {
return em.createQuery(cq).getResultList();
}
public void evict() {
em.getEntityManagerFactory().getCache().evictAll();
}
}
......@@ -31,6 +31,7 @@ public class OrderCallback<T extends ModelInterface<?>> implements FacadeCallbac
@Override
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Root<T> root, List<Predicate> predicates) {
Expression<?> path = null;
if (sort == null) {
if (sortstr == null) {
......@@ -44,7 +45,6 @@ public class OrderCallback<T extends ModelInterface<?>> implements FacadeCallbac
} else {
path = root.get(sort);
}
if (path == null) {
return;
}
......
package fi.insomnia.bortal.facade.callbacks;
import java.util.Collections;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
......@@ -8,30 +9,26 @@ import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.metamodel.SingularAttribute;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fi.insomnia.bortal.utilities.jpa.ModelInterface;
public class StringSearchPredicateCreator<T extends ModelInterface<?>> implements FacadeCallback<T> {
private static final String WILDCARD = "%";
private String searchstr = null;
private StringPredicateField<T>[] attributes = null;
private SingularAttribute<T, String> attr;
// public StringSearchPredicateCreator(String search,
// List<SingularAttribute<T, String>> attrs) {
// if (addSearch(search)) {
// attributes = attrs.;
// }
// }
private List<SingularAttribute<T, String>> attributes = null;
private static final Logger logger = LoggerFactory.getLogger(StringSearchPredicateCreator.class);
public StringSearchPredicateCreator(String search, SingularAttribute<T, String> from) {
public StringSearchPredicateCreator(String search, List<SingularAttribute<T, String>> attrs) {
if (addSearch(search)) {
from = attr;
attributes = attrs;
}
}
public StringSearchPredicateCreator(String name, StringPredicateField<T>[] values) {
if (addSearch(name)) {
attributes = values;
public StringSearchPredicateCreator(String search, SingularAttribute<T, String> from) {
if (addSearch(search)) {
attributes = Collections.singletonList(from);
}
}
......@@ -50,18 +47,16 @@ public class StringSearchPredicateCreator<T extends ModelInterface<?>> implement
@Override
public void exec(CriteriaBuilder cb, CriteriaQuery<?> cq, Root<T> root, List<Predicate> predicates) {
if (searchstr == null || (attr == null && (attributes == null || attributes.length == 0))) {
if (searchstr == null || attributes == null || attributes.isEmpty()) {
return;
}
if (attr == null) {
predicates.add(cb.equal(root.get(attr), searchstr));
} else {
Predicate[] preds = new Predicate[attributes.length];
int i = 0;
for (StringPredicateField<T> attr : attributes) {
preds[i++] = cb.equal(root.get(attr.getField()), searchstr);
}
predicates.add(cb.and(preds));
Predicate[] preds = new Predicate[attributes.size()];
int i = 0;
for (SingularAttribute<T, String> attr : attributes) {
logger.info("Equalling {} to {}", attr.getName(), searchstr);
preds[i++] = cb.like(root.get(attr), searchstr);
}
predicates.add(cb.or(preds));
}
}
......@@ -18,6 +18,8 @@ public interface PermissionBeanLocal {
boolean fatalPermission(IAppPermission perm, Object... failmessage) throws PermissionDeniedException;
// throws PermissionDeniedException;
void fatalNotLoggedIn() throws PermissionDeniedException;
User getAnonUser();
......
......@@ -39,7 +39,7 @@ public interface PlaceBeanLocal {
BigDecimal totalReservationPrice(User user, Place newPlace) throws PermissionDeniedException;
void releaseUsersPlaces(User user) throws PermissionDeniedException;
// void releaseUsersPlaces(User user) throws PermissionDeniedException;
Place find(int placeId);
......
......@@ -7,14 +7,17 @@ import fi.insomnia.bortal.model.EventMap;
@Local
public interface PlaceMapBeanLocal {
// public String getSelectPlaceMapUrl(EventMap activeMap, List<Place> selectedPlaces, User user);
// public String getSelectPlaceMapUrl(EventMap activeMap, List<Place>
// selectedPlaces, User user);
public Long selectablePlaceCount(EventMap activeMap);
public Long selectablePlaceCount(EventMap activeMap);
public EventMap findMap(Integer mapId);
public EventMap findMap(Integer mapId);
// public List<Place> findSelectedPlaces(EventMap map);
public Long availablePlaceCount(EventMap activeMap);
// public List<Place> findSelectedPlaces(EventMap map);
// public EventMap findMap(int i);
// public EventMap findMap(int i);
}
......@@ -9,27 +9,23 @@ import fi.insomnia.bortal.model.User;
@Local
public interface TestDataBeanLocal {
EventMap generateTestMap();
EventMap generateTestMap();
void generateTestPlaces(EventMap map);
void generateTestPlaces(EventMap map);
Bill createBill(User u);
Bill createBill(User u);
User createUser();
public void printPlacesInfo();
User createUser();
void generateTestCompos();
User createAdmin();
public void printPlacesInfo();
// EventMap readMap(long bytes);
void generateTestCompos();
// void writeMap(byte[] bytes);
User createAdmin();
EventMap readMap(long bytes);
void writeMap(byte[] bytes);
void flushMaps();
void flushMaps();
}
......@@ -2,11 +2,6 @@
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/>
<classpathentry kind="con" path="eclipse.fproj.jdt.libprov.osgi/jpt.jpa">
<attributes>
<attribute name="org.eclipse.jst.component.dependency" value="../"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jst.server.core.container/com.sun.enterprise.jst.server.runtimeTarget/GlassFish 3.1">
<attributes>
<attribute name="owner.project.facets" value="jst.utility"/>
......
#Thu Oct 28 16:55:14 EEST 2010
#Sat Sep 24 03:09:23 EEST 2011
eclipse.preferences.version=1
org.eclipse.jpt.core.discoverAnnotatedClasses=true
org.eclipse.jpt.core.metamodelSourceFolderName=src
org.eclipse.jpt.core.platform=eclipselink2_1
org.eclipse.jpt.core.platform=eclipselink2_3
<root>
<facet id="jpt.jpa">
<node name="libprov">
<attribute name="provider-id" value="eclipselink-210-osgi-bundles-library-provider"/>
</node>
<node name="osgi-bundles-container">
<attribute name="bundles" value="javax.persistence:[2.0.0,2.1.0);org.eclipse.persistence.core:[2.1.0,2.2.0);org.eclipse.persistence.jpa:[2.1.0,2.2.0);org.eclipse.persistence.asm:[2.1.0,2.2.0);org.eclipse.persistence.antlr:[2.1.0,2.2.0)"/>
<attribute name="label" value="EclipseLink 2.1.x"/>
<attribute name="provider-id" value="jpa-no-op-library-provider"/>
</node>
<node name="osgi-bundles-container"/>
</facet>
</root>
......@@ -16,8 +16,6 @@ import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
......@@ -31,17 +29,19 @@ import javax.persistence.TemporalType;
@Entity
@Table(name = "account_events")
@NamedQueries({
@NamedQuery(name = "AccountEvent.findAll", query = "SELECT a FROM AccountEvent a"),
@NamedQuery(name = "AccountEvent.findByUnitPrice", query = "SELECT a FROM AccountEvent a WHERE a.unitPrice = :unitPrice"),
@NamedQuery(name = "AccountEvent.findByQuantity", query = "SELECT a FROM AccountEvent a WHERE a.quantity = :units"),
@NamedQuery(name = "AccountEvent.findByEventTime", query = "SELECT a FROM AccountEvent a WHERE a.eventTime = :eventTime"),
@NamedQuery(name = "AccountEvent.findByDelivered", query = "SELECT a FROM AccountEvent a WHERE a.delivered = :delivered") })
// @NamedQueries({
// @NamedQuery(name = "AccountEvent.findAll", query =
// "SELECT a FROM AccountEvent a"),
// @NamedQuery(name = "AccountEvent.findByUnitPrice", query =
// "SELECT a FROM AccountEvent a WHERE a.unitPrice = :unitPrice"),
// @NamedQuery(name = "AccountEvent.findByQuantity", query =
// "SELECT a FROM AccountEvent a WHERE a.quantity = :units"),
// @NamedQuery(name = "AccountEvent.findByEventTime", query =
// "SELECT a FROM AccountEvent a WHERE a.eventTime = :eventTime"),
// @NamedQuery(name = "AccountEvent.findByDelivered", query =
// "SELECT a FROM AccountEvent a WHERE a.delivered = :delivered") })
public class AccountEvent extends GenericEventChild {
/**
*
*/
private static final long serialVersionUID = 2588419823225148100L;
@Column(name = "cash", nullable = false)
......
......@@ -76,9 +76,7 @@ public class BillLine extends GenericEventChild {
@ManyToOne
private Bill bill;
@JoinColumns({
@JoinColumn(name = "lineProduct_id", referencedColumnName = "id", nullable = true, updatable = false),
@JoinColumn(name = "event_id", referencedColumnName = "event_id", nullable = false, updatable = false, insertable = false) })
@JoinColumn(name = "lineProduct_id", referencedColumnName = "id", nullable = true, updatable = false)
@OneToOne
@OrderBy("id.id")
private Product lineProduct;
......
......@@ -36,7 +36,7 @@ public abstract class EntityEquals {
private Integer getRndid() {
if (rndid == null) {
Random rng = new Random(new Date().getTime());
rndid = new Integer(rng.nextInt());
rndid = Integer.valueOf(rng.nextInt());
}
return rndid;
}
......
......@@ -11,8 +11,7 @@ import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Lob;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
......@@ -22,16 +21,28 @@ import javax.persistence.Table;
*/
@Entity
@Table(name = "maps")
@NamedQueries({
@NamedQuery(name = "EventMap.findAll", query = "SELECT e FROM EventMap e"),
@NamedQuery(name = "EventMap.findByName", query = "SELECT e FROM EventMap e WHERE e.name = :name") })
public class EventMap extends GenericEventChild {
// @NamedQueries({
// @NamedQuery(name = "EventMap.findAll", query = "SELECT e FROM EventMap e"),
// @NamedQuery(name = "EventMap.findByName", query =
// "SELECT e FROM EventMap e WHERE e.name = :name") })
public class EventMap extends GenericEntity {
/**
*
*/
private static final long serialVersionUID = 3411450245513673619L;
@ManyToOne()
private LanEvent event;
public LanEvent getEvent() {
return event;
}
public void setEvent(LanEvent event) {
this.event = event;
}
@Lob
@Column(name = "map_data")
private byte[] mapData;
......@@ -58,7 +69,8 @@ public class EventMap extends GenericEventChild {
}
public EventMap(LanEvent event) {
super(event);
super();
this.event = event;
}
public String getName() {
......
......@@ -75,7 +75,7 @@ public class EventPk implements Serializable {
return false;
}
EventPk pk = (EventPk) obj;
return pk.id == this.id && pk.getEventId() == this.getEventId();
return pk.id.equals(this.id) && pk.getEventId().equals(this.getEventId());
}
@Override
......
......@@ -56,10 +56,10 @@ public class FoodWave extends GenericEventChild {
@OneToMany(mappedBy = "foodWave")
private List<AccountEvent> accountEvents;
@ManyToOne
@JoinColumns({
@JoinColumn(name = "template_id", referencedColumnName = "id", nullable = false),
@JoinColumn(name = "event_id", referencedColumnName = "event_id", nullable = false, updatable = false, insertable = false) })
@ManyToOne
private FoodWaveTemplate template;
public FoodWave() {
......
......@@ -15,13 +15,13 @@ public abstract class GenericEventChild extends EntityEquals implements ModelInt
private static final long serialVersionUID = -9041737052951021560L;
public static final String ID_COLUMN = "id";
public static final String EVENT_ID_COLUMN = "event_id";
@EmbeddedId
private EventPk id;
@Version
@Column(nullable = false)
private int jpaVersionField = 0;
public static final String EVENT_ID_COLUMN = "event_id";
@ManyToOne()
@JoinColumn(name = EVENT_ID_COLUMN, insertable = false, updatable = false)
private LanEvent event;
......
......@@ -11,10 +11,7 @@ import java.util.Calendar;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
......@@ -27,13 +24,17 @@ import javax.persistence.UniqueConstraint;
@Entity
@Table(name = "group_memberships", uniqueConstraints = { @UniqueConstraint(columnNames = {
"user_id", "group_id" }) })
@NamedQueries({
@NamedQuery(name = "GroupMembership.findAll", query = "SELECT g FROM GroupMembership g"),
@NamedQuery(name = "GroupMembership.findByInviteAccepted", query = "SELECT g FROM GroupMembership g WHERE g.inviteAccepted = :inviteAccepted"),
@NamedQuery(name = "GroupMembership.findByInviteEmail", query = "SELECT g FROM GroupMembership g WHERE g.inviteEmail = :inviteEmail"),
@NamedQuery(name = "GroupMembership.findByInviteName", query = "SELECT g FROM GroupMembership g WHERE g.inviteName = :inviteName") })
public class GroupMembership extends GenericEventChild {
// @NamedQueries({
// @NamedQuery(name = "GroupMembership.findAll", query =
// "SELECT g FROM GroupMembership g"),
//
// @NamedQuery(name = "GroupMembership.findByInviteAccepted", query =
// "SELECT g FROM GroupMembership g WHERE g.inviteAccepted = :inviteAccepted"),
// @NamedQuery(name = "GroupMembership.findByInviteEmail", query =
// "SELECT g FROM GroupMembership g WHERE g.inviteEmail = :inviteEmail"),
// @NamedQuery(name = "GroupMembership.findByInviteName", query =
// "SELECT g FROM GroupMembership g WHERE g.inviteName = :inviteName") })
public class GroupMembership extends GenericEntity {
private static final long serialVersionUID = 1L;
......@@ -50,16 +51,12 @@ public class GroupMembership extends GenericEventChild {
@Column(name = "invite_name")
private String inviteName;
@JoinColumns({
@JoinColumn(name = "group_id", referencedColumnName = "id", nullable = false),
@JoinColumn(name = "event_id", referencedColumnName = "event_id", nullable = false, updatable = false, insertable = false) })
@ManyToOne(optional = false, cascade = ALL)
@JoinColumn(name = "group_id", referencedColumnName = "id", nullable = false)
private PlaceGroup placeGroup;
@JoinColumns({
@JoinColumn(name = "place_reservation_id", referencedColumnName = "id", nullable = false),
@JoinColumn(name = "event_id", referencedColumnName = "event_id", nullable = false, updatable = false, insertable = false) })
@OneToOne(optional = false)
@JoinColumn(name = "place_reservation_id", referencedColumnName = "id", nullable = false)
private Place placeReservation;
@JoinColumn(name = "user_id", referencedColumnName = "id")
......@@ -73,8 +70,8 @@ public class GroupMembership extends GenericEventChild {
public GroupMembership() {
}
public GroupMembership(LanEvent event, PlaceGroup pg, Place p, String token) {
super(event);
public GroupMembership(PlaceGroup pg, Place p, String token) {
super();
this.setPlaceGroup(pg);
this.setPlaceReservation(p);
this.inviteToken = token;
......
......@@ -10,11 +10,8 @@ import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
......@@ -25,15 +22,21 @@ import javax.persistence.TemporalType;
*/
@Entity
@Table(name = "places")
@NamedQueries({
@NamedQuery(name = "Place.findAll", query = "SELECT p FROM Place p"),
@NamedQuery(name = "Place.findByDescription", query = "SELECT p FROM Place p WHERE p.description = :description"),
@NamedQuery(name = "Place.findByName", query = "SELECT p FROM Place p WHERE p.name = :name"),
@NamedQuery(name = "Place.findByMapX", query = "SELECT p FROM Place p WHERE p.mapX = :mapX"),
@NamedQuery(name = "Place.findByMapY", query = "SELECT p FROM Place p WHERE p.mapY = :mapY"),
@NamedQuery(name = "Place.findByDetails", query = "SELECT p FROM Place p WHERE p.details = :details"),
@NamedQuery(name = "Place.findByCode", query = "SELECT p FROM Place p WHERE p.code = :code") })
public class Place extends GenericEventChild {
// @NamedQueries({
// @NamedQuery(name = "Place.findAll", query = "SELECT p FROM Place p"),
// @NamedQuery(name = "Place.findByDescription", query =
// "SELECT p FROM Place p WHERE p.description = :description"),
// @NamedQuery(name = "Place.findByName", query =
// "SELECT p FROM Place p WHERE p.name = :name"),
// @NamedQuery(name = "Place.findByMapX", query =
// "SELECT p FROM Place p WHERE p.mapX = :mapX"),
// @NamedQuery(name = "Place.findByMapY", query =
// "SELECT p FROM Place p WHERE p.mapY = :mapY"),
// @NamedQuery(name = "Place.findByDetails", query =
// "SELECT p FROM Place p WHERE p.details = :details"),
// @NamedQuery(name = "Place.findByCode", query =
// "SELECT p FROM Place p WHERE p.code = :code") })
public class Place extends GenericEntity {
/**
*
......@@ -66,30 +69,27 @@ public class Place extends GenericEventChild {
@Column(name = "buyable", nullable = false)
private boolean buyable = true;
@Column(nullable = false)
private boolean disabled = false;
/**
* Which group has bought the place
*/
@JoinColumns({
@JoinColumn(name = "group_id", referencedColumnName = "id"),
@JoinColumn(name = "event_id", referencedColumnName = "event_id", nullable = false, updatable = false, insertable = false) })
@ManyToOne
@JoinColumn(name = "group_id", referencedColumnName = "id")
private PlaceGroup group;
@ManyToOne
@JoinColumn(name = "provided_role_id", referencedColumnName = "id")
private Role providesRole;
@JoinColumns({
@JoinColumn(name = "map_id", referencedColumnName = "id", nullable = false, updatable = true, insertable = true),
@JoinColumn(name = "event_id", referencedColumnName = "event_id", nullable = false, updatable = false, insertable = false) })
@JoinColumn(name = "map_id", referencedColumnName = "id", nullable = false)
@ManyToOne(optional = false, cascade = CascadeType.ALL)
private EventMap map;
/**
* Which ticket type is this place sold as
*/
@JoinColumns({
@JoinColumn(name = "products_id", referencedColumnName = "id"),
@JoinColumn(name = "event_id", referencedColumnName = "event_id", nullable = false, updatable = false, insertable = false) })
@JoinColumn(name = "products_id", referencedColumnName = "id")
@ManyToOne()
private Product product;
/**
......@@ -106,8 +106,6 @@ public class Place extends GenericEventChild {
public Place(EventMap eventMap) {
super();
setId(new EventPk());
getId().setEventId(eventMap.getId().getEventId());
this.map = eventMap;
}
......@@ -164,7 +162,7 @@ public class Place extends GenericEventChild {
}
public void setGroup(PlaceGroup group) {
if (group != null && group.getId().getEventId() != getId().getEventId()) {
if (group != null && !group.getEvent().equals(map.getEvent())) {
throw new RuntimeException("Can not set Group from different Event to Place!");
}
this.group = group;
......@@ -175,11 +173,7 @@ public class Place extends GenericEventChild {
}
public void setMap(EventMap map) {
if (map.getId().getEventId() != getId().getEventId()) {
throw new RuntimeException("Can not set Map from different Event to Place!");
}
this.map = map;
// this.mapId = map.getId().getId();
}
public Product getProduct() {
......@@ -236,17 +230,6 @@ public class Place extends GenericEventChild {
this.width = width;
}
public boolean isCoordinateInPlace(int x, int y) {
if (x > mapX
&& x < (mapX + width)
&& y > mapY
&& y < (mapY + height)) {
return true;
}
return false;
}
public boolean isTaken() {
return (getReleaseTime() != null || getGroup() != null);
......@@ -300,4 +283,12 @@ public class Place extends GenericEventChild {
return providesRole;
}
public boolean isDisabled() {
return disabled;
}
public void setDisabled(boolean disabled) {
this.disabled = disabled;
}
}
......@@ -37,14 +37,20 @@ import javax.persistence.TemporalType;
@NamedQuery(name = "PlaceGroup.findByName", query = "SELECT p FROM PlaceGroup p WHERE p.name = :name"),
@NamedQuery(name = "PlaceGroup.findByActive", query = "SELECT p FROM PlaceGroup p WHERE p.active = :active"),
@NamedQuery(name = "PlaceGroup.findByDetails", query = "SELECT p FROM PlaceGroup p WHERE p.details = :details") })
public class PlaceGroup extends GenericEventChild {
public class PlaceGroup extends GenericEntity {
private static final long serialVersionUID = 1L;
private static final String EVENT_ID_COLUMN = "event_id";
@Column(name = "group_created", nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Calendar created;
@ManyToOne()
@JoinColumn(name = EVENT_ID_COLUMN, nullable = false)
private LanEvent event;
@Column(name = "group_edited", nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Calendar edited;
......@@ -75,16 +81,12 @@ public class PlaceGroup extends GenericEventChild {
public PlaceGroup(LanEvent event, Calendar groupCreated, Calendar groupEdited,
boolean groupActive) {
this(event);
this.event = event;
this.created = groupCreated;
this.edited = groupEdited;
this.active = groupActive;
}
public PlaceGroup(LanEvent event) {
super(event);
}
public PlaceGroup() {
super();
}
......@@ -161,4 +163,12 @@ public class PlaceGroup extends GenericEventChild {
this.places = placeList;
}
public LanEvent getEvent() {
return event;
}
public void setEvent(LanEvent event) {
this.event = event;
}
}
......@@ -165,9 +165,6 @@ public class PrintedCard extends GenericEventChild {
return printCount;
}
@Transient
private Integer gamepoints = null;
public static final Comparator<PrintedCard> GAMEPOINT_COMPARATOR = new Comparator<PrintedCard>() {
@Override
......@@ -181,23 +178,23 @@ public class PrintedCard extends GenericEventChild {
}
};
@Transient
private Integer gamepoints = null;
public Integer getGamepoints() {
if (gamepoints == null) {
synchronized (this) {
if (gamepoints == null) {
gamepoints = 0;
for (ReaderEvent re : this.getReaderEvents()) {
gamepoints += re.getGamePoint();
}
}
Integer ret = 0;
for (ReaderEvent re : this.getReaderEvents()) {
ret += re.getGamePoint();
}
gamepoints = ret;
}
return gamepoints;
}
@Transient
private ListDataModel<ReaderEvent> revents;
private transient ListDataModel<ReaderEvent> revents;
public ListDataModel<ReaderEvent> getGameCards() {
if (revents == null) {
......
......@@ -15,8 +15,6 @@ import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
......@@ -26,15 +24,23 @@ import javax.persistence.UniqueConstraint;
*/
@Entity
@Table(name = "products")
@NamedQueries({
@NamedQuery(name = "Product.findAll", query = "SELECT p FROM Product p"),
@NamedQuery(name = "Product.findByProductName", query = "SELECT p FROM Product p WHERE p.name = :name"),
@NamedQuery(name = "Product.findByPrice", query = "SELECT p FROM Product p WHERE p.price = :price"),
@NamedQuery(name = "Product.findBySort", query = "SELECT p FROM Product p WHERE p.sort = :sort"),
@NamedQuery(name = "Product.findByBarcode", query = "SELECT p FROM Product p WHERE p.barcode = :barcode") })
public class Product extends GenericEventChild {
// @NamedQueries({
// @NamedQuery(name = "Product.findAll", query = "SELECT p FROM Product p"),
// @NamedQuery(name = "Product.findByProductName", query =
// "SELECT p FROM Product p WHERE p.name = :name"),
// @NamedQuery(name = "Product.findByPrice", query =
// "SELECT p FROM Product p WHERE p.price = :price"),
// @NamedQuery(name = "Product.findBySort", query =
// "SELECT p FROM Product p WHERE p.sort = :sort"),
// @NamedQuery(name = "Product.findByBarcode", query =
// "SELECT p FROM Product p WHERE p.barcode = :barcode") })
public class Product extends GenericEntity {
private static final long serialVersionUID = 1L;
public static final String EVENT_ID_COLUMN = "event_id";
@ManyToOne()
@JoinColumn(name = EVENT_ID_COLUMN, nullable = false)
private LanEvent event;
@Column(name = "product_name")
private String name;
......@@ -66,11 +72,11 @@ public class Product extends GenericEventChild {
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "product_discounts", inverseJoinColumns = {
@JoinColumn(name = "discount_id", referencedColumnName = "id"),
@JoinColumn(name = "event_id", referencedColumnName = "event_id") },
joinColumns = { @JoinColumn(name = "product_id", referencedColumnName = "id"),
@JoinColumn(name = "event_id", referencedColumnName = "event_id")
})
@JoinColumn(name = "discount_id", referencedColumnName = "id"),
@JoinColumn(name = "event_id", referencedColumnName = "event_id") },
joinColumns = { @JoinColumn(name = "product_id", referencedColumnName = "id")
})
private List<Discount> discounts;
private BigDecimal vat = BigDecimal.ZERO;
......@@ -78,11 +84,11 @@ public class Product extends GenericEventChild {
@ManyToMany()
@JoinTable(name = "product_foodwavetemplate", joinColumns = {
@JoinColumn(name = "product_id", referencedColumnName = "id"),
@JoinColumn(name = "event_id", referencedColumnName = "event_id") }, inverseJoinColumns = {
@JoinColumn(name = "food_wave_template_id", referencedColumnName = "id"),
@JoinColumn(name = "event_id", referencedColumnName = "event_id") },
uniqueConstraints = { @UniqueConstraint(columnNames = { "product_id", "food_wave_template_id", "event_id" }) })
@JoinColumn(name = "product_id", referencedColumnName = "id"),
}, inverseJoinColumns = {
@JoinColumn(name = "food_wave_template_id", referencedColumnName = "id"),
@JoinColumn(name = "event_id", referencedColumnName = "event_id") },
uniqueConstraints = { @UniqueConstraint(columnNames = { "product_id", "food_wave_template_id", "event_id" }) })
private List<FoodWaveTemplate> foodWaveTemplates;
public Product() {
......@@ -90,7 +96,8 @@ public class Product extends GenericEventChild {
}
public Product(LanEvent event) {
super(event);
super();
this.setEvent(event);
}
......@@ -238,4 +245,12 @@ public class Product extends GenericEventChild {
return provides;
}
public LanEvent getEvent() {
return event;
}
public void setEvent(LanEvent event) {
this.event = event;
}
}
......@@ -68,9 +68,7 @@ public class Reader extends GenericEventChild {
private Location location;
@ManyToOne
@JoinColumns({
@JoinColumn(name = "map_id", referencedColumnName = "id"),
@JoinColumn(name = "event_id", referencedColumnName = "event_id", updatable = false, insertable = false) })
@JoinColumn(name = "map_id", referencedColumnName = "id")
private EventMap eventMap;
@Column(name = "map_x")
......
......@@ -15,6 +15,8 @@ import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
......@@ -28,9 +30,7 @@ import javax.persistence.TemporalType;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import org.eclipse.persistence.annotations.ConversionValue;
import org.eclipse.persistence.annotations.Convert;
import org.eclipse.persistence.annotations.ObjectTypeConverter;
import org.eclipse.persistence.annotations.PrivateOwned;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -42,11 +42,6 @@ import fi.insomnia.bortal.utilities.PasswordFunctions;
*/
@Entity
@Table(name = "users")
@ObjectTypeConverter(name = "gender", objectType = Gender.class, dataType = String.class, conversionValues = {
@ConversionValue(objectValue = "MALE", dataValue = "M"),
@ConversionValue(objectValue = "FEMALE", dataValue = "F"),
@ConversionValue(objectValue = "UNDEFINED", dataValue = "U"),
})
public class User extends GenericEntity {
public static final String ANONYMOUS_LOGINNAME = "anonymous";
private static final long serialVersionUID = -1632200627103418206L;
......@@ -101,7 +96,7 @@ public class User extends GenericEntity {
@JoinColumn(name = "current_image_id", referencedColumnName = "id")
private UserImage currentImage;
@Convert("gender")
@Enumerated(EnumType.STRING)
@Column(name = "gender", nullable = false)
private Gender gender = Gender.UNDEFINED;
......@@ -120,8 +115,8 @@ public class User extends GenericEntity {
@ManyToMany()
@JoinTable(name = "role_memberships", inverseJoinColumns = {
@JoinColumn(name = "role_id", referencedColumnName = Role.ID_COLUMN) },
joinColumns = { @JoinColumn(name = "user_id", referencedColumnName = "id") })
@JoinColumn(name = "role_id", referencedColumnName = Role.ID_COLUMN) },
joinColumns = { @JoinColumn(name = "user_id", referencedColumnName = "id") })
private List<Role> roles = new ArrayList<Role>();
@OneToMany(mappedBy = "user")
......@@ -129,6 +124,7 @@ public class User extends GenericEntity {
@OneToMany(mappedBy = "user", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@OrderBy
@PrivateOwned
private List<UserImage> userImageList;
@OneToMany(mappedBy = "user")
......@@ -218,7 +214,11 @@ public class User extends GenericEntity {
}
public String getWholeName() {
return new StringBuilder().append(firstnames).append(" ").append(lastname).toString();
String ret = new StringBuilder().append(firstnames).append(" ").append(lastname).toString().trim();
if (ret.isEmpty()) {
ret = login;
}
return ret;
}
public String getLastname() {
......
package fi.insomnia.bortal.enums;
import java.util.HashSet;
import java.util.Set;
public enum BeanRole {
// If modified update to sun-web.xml
// Bean level access
ANONYMOUS, // Unauthenticated web user
USER_BASE, // JAAS access for logged in user
ADMIN_BASE(USER_BASE), // JAAS access to administrative beans
// Admin for the whole system (JAAS, boolean in User)
SUPERADMIN(false, ADMIN_BASE),
ORGANIZATION_ROOT(ADMIN_BASE), // E.g. Vectorama organisation admin
;
private boolean inDatabase;
private Set<BeanRole> parents = new HashSet<BeanRole>();
BeanRole() {
}
/**
* Default (on-demand create time) parents for the role
*
* @param parent
*/
BeanRole(BeanRole... parent) {
for (BeanRole role : parent) {
parents.add(role);
}
}
/**
* Is the role stored in the database (default true) or is it a magic role
* like superadmin (stored as boolean in User).
*
* @param inDb
* stored in roles-table
* @param parent
* default (create time) parent roles
*/
BeanRole(boolean inDb, BeanRole... parent) {
this(parent);
this.inDatabase = inDb;
}
public boolean isInDatabase() {
return inDatabase;
}
/**
* Default parent roles (when creating role on first use)
*
* @return
*/
public Set<BeanRole> getParents() {
return parents;
}
}
......@@ -5,13 +5,15 @@ import fi.insomnia.bortal.enums.BortalApplication;
public enum BillPermission implements IAppPermission {
READ_ALL("Read all bills"),
WRITE_ALL("Modify all bills"),
CREATE_BILL("Create bills for self")
CREATE_BILL("Create bills for self"),
VIEW_OWN("View own bills"),
;
public static final String S_READ_ALL = "BILL/READ_ALL";
public static final String S_CREATE_BILL = "BILL/CREATE_BILL";
public static final String S_WRITE_ALL = "BILL/WRITE_ALL";
public static final String S_VIEW_OWN = "BILL/VIEW_OWN";
private final String description;
private final String fullName;
......
package fi.insomnia.bortal.enums.apps;
public enum SpecialPermission {
SUPERADMIN, USER, ANONYMOUS;
public static final String S_USER = "USER";
public static final String S_SUPERADMIN = "SUPERADMIN";
public static final String S_ANONYMOUS = "ANONYMOUS";
}
......@@ -46,7 +46,7 @@ public class StreampartyLegacyPwdcheck {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new String(password);
return password;
}
......
<?xml version="1.0" encoding="UTF-8"?>
<pageflow:Pageflow xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:pageflow="http://www.sybase.com/suade/pageflow" id="pf13012981621060" configfile="/LanBortalWeb/WebContent/WEB-INF/faces-config.xml">
<nodes xsi:type="pageflow:PFPage" name="place/placemap" x="180" y="137" id="pf13156916815477" outlinks="pf13156916815478" inlinks="pf13156916815478" path="/place/placemap.xhtml"/>
<links id="pf13156916815478" target="pf13156916815477" source="pf13156916815477" outcome="placesReserved" redirect="true">
<bendPoints d1Height="-36" d2Height="-36"/>
<bendPoints d1Width="3" d1Height="-86" d2Width="3" d2Height="-86"/>
<bendPoints d1Width="-65" d1Height="-88" d2Width="-65" d2Height="-88"/>
<bendPoints d1Width="-64" d2Width="-64"/>
</links>
<nodes xsi:type="pageflow:PFPage" name="*" x="120" y="60" id="pf131682121330014" referenceLink="//@navigationRule.0/@fromViewId|" outlinks="pf131682121330015" path="*"/>
<nodes xsi:type="pageflow:PFPage" name="auth/logoutResponse" x="288" y="60" id="pf131682121330016" referenceLink="//@navigationRule.0/@navigationCase.0/@toViewId|" inlinks="pf131682121330015" path="/auth/logoutResponse"/>
<nodes xsi:type="pageflow:PFPage" name="place/placemap" x="276" y="228" id="pf13168224196920" referenceLink="//@navigationRule.1/@navigationCase.0/@toViewId|" outlinks="pf13168224196921" inlinks="pf13168224196921" path="/place/placemap"/>
<links id="pf131682121330015" target="pf131682121330016" source="pf131682121330014" outcome="logoutDone" redirect="true"/>
<links id="pf13168224196921" target="pf13168224196920" source="pf13168224196920" outcome="placesReserved" redirect="true"/>
</pageflow:Pageflow>
......@@ -20,73 +20,63 @@
</locale-config>
</application>
<!-- <navigation-rule> -->
<!-- <from-view-id>/user/list.xhtml</from-view-id> -->
<!-- <navigation-case> -->
<!-- <from-outcome>userEdit</from-outcome> -->
<!-- <to-view-id>/user/edit.xhtml</to-view-id> -->
<!-- </navigation-case> -->
<!-- </navigation-rule> -->
<!-- <navigation-rule> -->
<!-- <from-view-id>/user/edit.xhtml</from-view-id> -->
<!-- <navigation-case> -->
<!-- <from-outcome>userSave</from-outcome> -->
<!-- <to-view-id>/user/edit.xhtml</to-view-id> -->
<!-- </navigation-case> -->
<!-- </navigation-rule> -->
<!-- <navigation-rule> -->
<!-- <from-view-id>/role/list.xhtml</from-view-id> -->
<!-- <navigation-case> -->
<!-- <from-outcome>roleEdit</from-outcome> -->
<!-- <to-view-id>/role/edit.xhtml</to-view-id> -->
<!-- </navigation-case> -->
<!-- </navigation-rule> -->
<!-- <navigation-rule> -->
<!-- <from-view-id>/user/list.xhtml</from-view-id> -->
<!-- <navigation-case> -->
<!-- <from-outcome>userEdit</from-outcome> -->
<!-- <to-view-id>/user/edit.xhtml</to-view-id> -->
<!-- </navigation-case> -->
<!-- </navigation-rule> -->
<!-- <navigation-rule> -->
<!-- <from-view-id>/user/edit.xhtml</from-view-id> -->
<!-- <navigation-case> -->
<!-- <from-outcome>userSave</from-outcome> -->
<!-- <to-view-id>/user/edit.xhtml</to-view-id> -->
<!-- </navigation-case> -->
<!-- </navigation-rule> -->
<!-- <navigation-rule> -->
<!-- <from-view-id>/role/list.xhtml</from-view-id> -->
<!-- <navigation-case> -->
<!-- <from-outcome>roleEdit</from-outcome> -->
<!-- <to-view-id>/role/edit.xhtml</to-view-id> -->
<!-- </navigation-case> -->
<!-- </navigation-rule> -->
<!-- <navigation-rule> -->
<!-- <from-view-id>*</from-view-id> -->
<!-- <navigation-case> -->
<!-- <from-outcome>frontpage</from-outcome> -->
<!-- <to-view-id>/news/frontpage.xhtml</to-view-id> -->
<!-- </navigation-case> -->
<!-- <navigation-case> -->
<!-- <from-outcome>userprefs</from-outcome> -->
<!-- <to-view-id>/news/edit.xhtml</to-view-id> -->
<!-- </navigation-case> -->
<!-- <navigation-case> -->
<!-- <from-outcome>shopfrontpage</from-outcome> -->
<!-- <to-view-id>/product/createBill.xhtml</to-view-id> -->
<!-- </navigation-case> -->
<!-- <navigation-case> -->
<!-- <from-outcome>adminfront</from-outcome> -->
<!-- <to-view-id>/admin/frontpage.xhtml</to-view-id> -->
<!-- </navigation-case> -->
<navigation-rule>
<from-view-id>*</from-view-id>
<!-- </navigation-rule> -->
<!-- <navigation-rule> -->
<!-- <from-view-id>/role/edit.xhtml</from-view-id> -->
<!-- <navigation-case> -->
<!-- <from-outcome>roleSaved</from-outcome> -->
<!-- <to-view-id>/role/edit.xhtml</to-view-id> -->
<!-- </navigation-case> -->
<!-- </navigation-rule> -->
<!-- <navigation-rule> -->
<navigation-case>
<from-outcome>logoutDone</from-outcome>
<to-view-id>/auth/logoutResponse</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
<!-- </navigation-rule> -->
<!-- <navigation-rule> -->
<!-- <from-view-id>/role/edit.xhtml</from-view-id> -->
<!-- <navigation-case> -->
<!-- <from-outcome>roleSaved</from-outcome> -->
<!-- <to-view-id>/role/edit.xhtml</to-view-id> -->
<!-- </navigation-case> -->
<!-- </navigation-rule> -->
<!-- <navigation-rule> -->
<!-- <from-view-id>/product/createBill.xhtml</from-view-id> -->
<!-- <navigation-case> -->
<!-- <from-outcome>success</from-outcome> -->
<!-- <to-view-id>/bill/list.xhtml</to-view-id> -->
<!-- </navigation-case> -->
<!-- </navigation-rule> -->
<!-- <from-view-id>/product/createBill.xhtml</from-view-id> -->
<!-- <navigation-case> -->
<!-- <from-outcome>success</from-outcome> -->
<!-- <to-view-id>/bill/list.xhtml</to-view-id> -->
<!-- </navigation-case> -->
<!-- </navigation-rule> -->
<factory>
<exception-handler-factory>fi.insomnia.bortal.exceptions.BortalExceptionHandlerFactory</exception-handler-factory>
</factory>
<navigation-rule>
<display-name>place/placemap</display-name>
<from-view-id>/place/placemap.xhtml</from-view-id>
<from-view-id>/place/placemap</from-view-id>
<navigation-case>
<from-outcome>placesReserved</from-outcome>
<to-view-id>/place/placemap.xhtml</to-view-id>
<redirect />
<to-view-id>/place/placemap</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
</faces-config>
......
......@@ -64,13 +64,7 @@
<form-error-page>/auth/loginError.jsf</form-error-page>
</form-login-config>
</login-config>
<security-role>
<role-name>SUPERADMIN</role-name>
</security-role>
<security-role>
<role-name>USER</role-name>
</security-role>
<security-constraint>
<security-constraint>
<display-name>Forbidden resource</display-name>
<web-resource-collection>
<web-resource-name>Forbidden</web-resource-name>
......
......@@ -7,7 +7,6 @@
>
<h:body>
<ui:composition template="/layout/#{sessionHandler.layout}/template.xhtml">
<ui:param name="thispage" value="page.auth.logoutsuccess" />
<ui:define name="content">
<h:outputText value="#{i18n['login.logoutmessage']}" />
......
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
>
<h:head>
<title></title>
</h:head>
<h:body>
<ui:composition template="/layout/#{sessionHandler.layout}/template.xhtml">
<ui:param name="thispage" value="page.index" />
<ui:composition template="/layout/#{sessionHandler.layout}/template.xhtml">
<ui:define name="content">
<h1>Insomnia lippukauppa</h1>
<h3>Lippujen hinnat</h3>
<ul>
<li>1-4 konepaikkaa 30e/paikka</li>
......@@ -21,46 +22,36 @@
<h3>Rekisteröityminen ja lippujen tilaaminen</h3>
<p>Tilataksesi konepaikkoja sinun tulee rekisteröityä Insomnian
lippukauppaan. Rekisteröitymisvaiheessa teet käyttäjätunnuksen ja tilaat
haluamasi määrän konepaikkoja.</p>
<p>Tilataksesi konepaikkoja sinun tulee rekisteröityä Insomnian lippukauppaan. Rekisteröitymisvaiheessa teet
käyttäjätunnuksen ja tilaat haluamasi määrän konepaikkoja.</p>
<h3>Maksaminen</h3>
<p>
Lippukauppaan ilmestyy lasku tilaamiesi konepaikkojen ja lippujen mukaisesti.
Laskusta löydät kaikki maksamiseen tarvittavat tiedot.<br />
<br />
<b>Muista käyttää viitenumeroa laskua maksaessasi!</b> Huomioithan myös
pankkiviiveet maksaessasi muusta pankista kuin Osuuspankista. Maksut
tarkastetaan pari kertaa päivässä. Maksuja ei palauteta ilman erittäin hyvää
syytä (esimerkiksi sairaustapauksissa lääkärintodistusta vastaan).</p>
Lippukauppaan ilmestyy lasku tilaamiesi konepaikkojen ja lippujen mukaisesti. Laskusta löydät kaikki maksamiseen
tarvittavat tiedot.<br /> <br /> <b>Muista käyttää viitenumeroa laskua maksaessasi!</b> Huomioithan myös
pankkiviiveet maksaessasi muusta pankista kuin Osuuspankista. Maksut tarkastetaan pari kertaa päivässä. Maksuja ei
palauteta ilman erittäin hyvää syytä (esimerkiksi sairaustapauksissa lääkärintodistusta vastaan).
</p>
<h3>Paikkojen varaaminen</h3>
<p>
Kun olet maksanut saamasi laskun ja olemme kirjanneet maksusi, saat
sähköpostiisi ilmoituksen kun voit varata paikkoja. Tällöin voit varata
paikkakartalta tilaamasi määrän konepaikkoja.</p>
<p>Kun olet maksanut saamasi laskun ja olemme kirjanneet maksusi, saat sähköpostiisi ilmoituksen kun voit varata
paikkoja. Tällöin voit varata paikkakartalta tilaamasi määrän konepaikkoja.</p>
<h3>Lippujen lunastaminen tapahtuman yhteydessä</h3>
<p>
Kun olet täyttänyt tietosi järjestelmään, tulosta tilauksesi mukaiset
viivakoodit ja jaa ne ryhmäsi jäsenille. Viivakoodin avulla nopeutat lippujen
lunastusta huomattavasti.</p>
<p>Kun olet täyttänyt tietosi järjestelmään, tulosta tilauksesi mukaiset viivakoodit ja jaa ne ryhmäsi jäsenille.
Viivakoodin avulla nopeutat lippujen lunastusta huomattavasti.</p>
<h3>Tavalliset konepaikat ja pro-konepaikat</h3>
<p>
Tapahtumassa on tarjolla sekä tavallisia 80cm leveitä konepaikkoja että myös
rajattu määrä normaaleista konepaikoista poikkeavia pro-konepaikkoja.<br />
<br />
Pro-konepaikoilla pääsee nauttimaan suuremmasta tilasta, sillä konepaikan
leveys on 100cm ja lisäksi paikat on jaoteltu viiden konepaikan riveihin.
Pro-konepaikkojen käytävävälit ovat myös leveämmät.</p>
Tapahtumassa on tarjolla sekä tavallisia 80cm leveitä konepaikkoja että myös rajattu määrä normaaleista
konepaikoista poikkeavia pro-konepaikkoja.<br /> <br /> Pro-konepaikoilla pääsee nauttimaan suuremmasta tilasta,
sillä konepaikan leveys on 100cm ja lisäksi paikat on jaoteltu viiden konepaikan riveihin. Pro-konepaikkojen
käytävävälit ovat myös leveämmät.
</p>
<h3>Kysymykset</h3>
<p>
Mikäli mieltäsi askarruttaa jokin liittyen tapahtuman konepaikkoihin tai
lippukauppaan, ota rohkeasti yhteyttä sähköpostilla osoitteeseen info
[at] insomnia.fi.</p>
<p>Mikäli mieltäsi askarruttaa jokin liittyen tapahtuman konepaikkoihin tai lippukauppaan, ota rohkeasti yhteyttä
sähköpostilla osoitteeseen info [at] insomnia.fi.</p>
</ui:define>
</ui:composition>
......
......@@ -24,9 +24,7 @@
</ul></li>
<li><h:outputText styleClass="sidebartitle" value="#{i18n['sidebar.bills']}" />
<ul>
<li><h:link outcome="/bill/list" value="#{i18n['sidebar.bill.listAll']}" />
</li>
<li><h:link outcome="/bill/billSummary" value="#{i18n['sidebar.bill.summary']}" />
<li><h:link outcome="/bill/billSummary" value="#{i18n['sidebar.bill.summary']}" />
</li>
</ul></li>
<li><h:outputText styleClass="sidebartitle" value="#{i18n['sidebar.users']}" />
......
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:tools="http://java.sun.com/jsf/composite/tools"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html" xmlns:tools="http://java.sun.com/jsf/composite/tools"
xmlns:f="http://java.sun.com/jsf/core" xmlns:c="http://java.sun.com/jsp/jstl/core"
>
<h:body>
<ui:composition template="/layout/insomnia1/sidebartemplate.xhtml">
<ui:param name="rendered" value="true" />
<ui:param name="rendered" value="true" />
<ui:define name="sidebarcontent">
<ul>
<li><h:link outcome="/bill/list" value="#{i18n['sidebar.bill.list']}"/></li>
</ul>
<li><h:link outcome="/bill/list" value="#{i18n['sidebar.bill.list']}" />
</li>
<c:if test="#{billListView.canReadAllBills()}">
<li><h:link outcome="/bill/listAll" value="#{i18n['sidebar.bill.listAll']}" />
</li>
</c:if>
</ul>
</ui:define>
</ui:composition>
......
......@@ -6,11 +6,9 @@
>
<f:view locale="#{sessionHandler.locale}">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title><h:outputText value="#{layoutView.getHeader(thispage)}" />
</title>
<title><h:outputText value="#{layoutView.getHeader()}" /></title>
<meta name="description" content="Insomnia lippukauppa" />
<meta name="author" content="Niko Juusela, csharp" />
<meta http-equiv="Content-Language" content="fi" />
......@@ -34,58 +32,39 @@
<div id="wrapper">
<div id="navigation">
<ul class="menu">
<li><h:link outcome="/index" value="#{i18n['topmenu.frontpage']}"
styleClass="#{i18n[util.concat(thispage,'.pagegroup')] == 'frontpage'?'active':''}"
/></li>
<c:if test="#{sessionHandler.isLoggedIn()}">
<li><h:link outcome="/user/edit" value="#{i18n['topmenu.usersPreferences']}"
styleClass="#{i18n[util.concat(thispage,'.pagegroup')] == 'user'?'active':''}"
/>
</li>
<!--
<li><h:link outcome="/poll/start" value="#{i18n['topmenu.poll']}"
styleClass="#{i18n[util.concat(thispage,'.pagegroup')] == 'poll'?'active': ''}"
/></li>
-->
</c:if>
<c:if test="#{mapView.canView()}">
<li><h:link outcome="/place/placemap" value="#{i18n['topmenu.placemap']}"
styleClass="#{i18n[util.concat(thispage,'.pagegroup')] == 'placemap'?'active':''}"
/>
</li>
</c:if>
<c:if test="#{sessionHandler.isLoggedIn()}">
<!--<li><h:link outcome="/product/list" value="#{i18n['topmenu.adminfront']}"
styleClass="#{i18n[util.concat(thispage,'.pagegroup')] == 'admin'?'active':''}"
/>
</li>-->
<li><h:link outcome="/shop/createBill" value="#{i18n['sidebar.product.createBill']}"
styleClass="#{i18n[util.concat(thispage,'.pagegroup')] == 'admin'?'active':''}"
/>
</li>
<!-- <li><h:link outcome="/shop/showReaderEvents" value="#{i18n['topmenu.rfidshop']}"
styleClass="#{i18n[util.concat(thispage,'.pagegroup')] == 'rfidshop'?'active':''}"
/>
</li>
<li><h:link outcome="/game/start" value="#{i18n['topmenu.game']}"
styleClass="#{i18n[util.concat(thispage,'.pagegroup')] == 'game'?'active':''}"
/>
</li>
-->
</c:if>
<ul class="menu" jsfc="ui:repeat" var="menuitem" value="#{menuView.topmenu}">
<li><h:link outcome="#{menuitem.outcome}" value="#{menuitem.linktext}"
styleClass="#{menuitem.selected?'active':''}"
>
<f:param name="cid" value="#{menuitem.cid?userView.conversationId:null}" />
</h:link></li>
</ul>
</div>
<div id="container" class="top"></div>
<div id="container" class="top" />
<div id="container" class="clearfix">
<div id="left">
<ui:insert name="title" />
<h:messages globalOnly="true" />
<ui:insert name="content" />
</div>
<div id="right">
<ui:include src="/layout/insomnia2/sidebar-#{i18n[util.concat(thispage,'.pagegroup')]}.xhtml" />
<c:if test="#{menuView.submenu.size() > 1}">
<div id="right">
</div>
<ul class="menu">
<ui:repeat var="menuitem" value="#{menuView.submenu}">
<h:outputText rendered="#{!empty menuitem.header}"
value="&lt;/ul>&lt;h1>#{i18n[menuitem.header]}&lt;/h1>&lt;ul>" escape="false"
/>
<li><h:link outcome="#{menuitem.outcome}" value="#{menuitem.linktext}"
styleClass="#{menuitem.selected?'active':''}"
>
<f:param name="cid" value="#{menuitem.cid?userView.conversationId:null}" />
</h:link></li>
</ui:repeat>
</ul>
</div>
</c:if>
</div>
<div id="container" class="bottom"></div>
</div>
......
......@@ -49,12 +49,14 @@
<h:outputText value="#{placeView.place.product.name}" />
<h:outputLabel value="#{i18n['place.buyable']}" />
<h:selectBooleanCheckbox value="#{plaveView.place.buyable}"/>
<h:selectBooleanCheckbox value="#{placeView.place.buyable}"/>
<h:outputLabel value="#{i18n['place.description']}:" />
<h:inputTextarea value="#{placeView.place.description}" />
</h:panelGrid>
<h:commandButton id="commitbtn" action="#{placeView.save()}" value="#{i18n['place.commit']}" />
<h:commandButton rendered="#{placeView.place.isTaken() and (empty placeView.place.group)}"
action="#{placeView.releasePlace()}" value="#{i18n['place.release']}"
/>
......@@ -63,9 +65,9 @@
onclick="return confirm('#{i18n['place.groupremove.confirm']}')"
/>
<h:commandButton id="commitbtn" action="#{placeView.save()}" value="#{i18n['place.commit']}" />
</h:form>
<h2>Placegroup</h2>
<h:panelGrid columns="2" rendered="#{empty placeView.place.group}">
<h:form id="usersearchform">
<h:outputText value="#{i18n['user.searchUser']}" />
......@@ -124,9 +126,14 @@
<h:outputLabel value="#{i18n['placegroup.details']}:" />
<h:inputTextarea value="#{placeView.place.group.details}" />
<h:outputLabel value="#{i18n['placegroup.creator']}" />
<h:link outcome="/user/edit" value="#{placeView.place.group.creator.wholeName}" >
<f:param name="userid" value="#{placeView.place.group.creator.id}"/>
</h:link>
</h:panelGrid>
</h:form>
<h:dataTable border="0" id="placelist" value="#{placeView.place.group.places}" var="place">
......
......@@ -7,9 +7,15 @@
<h:body>
<ui:composition template="/layout/#{sessionHandler.layout}/template.xhtml">
<ui:param name="thispage" value="page.place.mygroups" />
<f:metadata>
<f:viewParam name="userid" value="#{userView.userid}" />
<f:event type="preRenderView" listener="#{userView.initView}" />
</f:metadata>
<ui:define name="content">
<h1>#{i18n['placegroupview.header']}</h1>
<p>#{i18n['placegroupview.toptext']}</p>
<h:outputText rendered="#{empty placeGroupView.groupMemberships}"
value="#{i18n['placegroupview.noMemberships']}" />
<h:form rendered="#{!empty placeGroupView.groupMemberships}" id="placelistform">
......
......@@ -18,7 +18,7 @@
/>
<h:commandButton styleClass="imgcenter" id="commandbutton" image="/PlaceMap?mapid=#{mapView.activeMap.id.id}"
<h:commandButton styleClass="imgcenter" id="commandbutton" image="/PlaceMap?mapid=#{mapView.activeMap.id}"
actionListener="#{placeView.placeSelectActionListener}"
/>
......@@ -51,10 +51,10 @@
<h:panelGroup>
<h:panelGrid columnClasses=",rightalign" columns="2">
<h:outputLabel value="#{i18n['placeSelect.totalPlaces']}:" />
<h:outputText value="#{mapView.activeMap.places.size()}" />
<h:outputText value="#{mapView.availablePlaces}" />
<h:outputLabel value="#{i18n['placeSelect.placesleft']}:" />
<h:outputText value="#{mapView.placeLeftToSelect()}" />
<h:outputText value="#{mapView.placesLeftToSelect}" />
<h:outputLabel rendered="#{mapView.canUserBuy()}" value="#{i18n['user.accountBalance']}:" />
<h:outputText rendered="#{mapView.canUserBuy()}" value="#{mapView.user.accountBalance}">
......
......@@ -18,6 +18,7 @@
action="#{request.contextPath}/UploadServlet?type=mapimage" enctype="multipart/form-data" method="post"
>
<p>
<input type="hidden" name="id" value="#{mapManageView.map.id.id}" /> Lähetä kartan taustakuva
</p>
......
......@@ -3,8 +3,7 @@
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
xmlns:composite="http://java.sun.com/jsf/composite" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:tools="http://java.sun.com/jsf/composite/tools"
>
xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:tools="http://java.sun.com/jsf/composite/tools" >
<composite:interface>
......@@ -20,6 +19,7 @@
<h:form id="userform">
<h:panelGrid columns="3">
<h:outputLabel rendered="#{!cc.attrs.creating}" value="#{i18n['user.login']}:" for="viewlogin" />
<h:outputText rendered="#{!cc.attrs.creating}" disabled="#{!cc.attrs.creating and !userView.canSave()}"
id="viewlogin" value="#{userView.selectedUser.login}"
......@@ -27,8 +27,8 @@
<h:message rendered="#{!cc.attrs.creating}" for="viewlogin" />
<h:outputLabel rendered="#{cc.attrs.creating}" value="#{i18n['user.login']}:" for="login" />
<h:inputText rendered="#{cc.attrs.creating}" validator="#{userValidator.login}" disabled="#{!cc.attrs.creating and !userView.canSave()}"
id="login" value="#{userView.selectedUser.login}"
<h:inputText rendered="#{cc.attrs.creating}" validator="#{userValidator.login}"
disabled="#{!cc.attrs.creating and !userView.canSave()}" id="login" value="#{userView.selectedUser.login}"
/>
<h:message rendered="#{cc.attrs.creating}" for="login" />
......@@ -94,13 +94,18 @@
<h:outputLabel rendered="#{cc.attrs.creating}" value="#{i18n['user.password']}:" for="password" />
<h:inputSecret validator="#{userValidator.password}" rendered="#{cc.attrs.creating}" id="password" value="#{userView.password}" />
<h:inputSecret validator="#{userValidator.password}" rendered="#{cc.attrs.creating}" id="password"
value="#{userView.password}"
/>
<h:message rendered="#{cc.attrs.creating}" for="password" />
<h:outputLabel rendered="#{cc.attrs.creating}" value="#{i18n['user.passwordcheck']}:" for="passwordcheck" />
<h:inputSecret validator="#{userValidator.password}" rendered="#{cc.attrs.creating}" id="passwordcheck" value="#{userView.passwordcheck}" />
<h:inputSecret validator="#{userValidator.password}" rendered="#{cc.attrs.creating}" id="passwordcheck"
value="#{userView.passwordcheck}"
/>
<h:message rendered="#{cc.attrs.creating}" for="passwordcheck" />
<h:outputLabel rendered="#{roleView.canReadRoles()}" value="#{i18n['user.roles']}:" for="roles" />
<h:selectManyCheckbox converter="#{roleConverter}" rendered="#{roleView.canReadRoles()}"
disabled="#{!roleView.canWriteRoles()}" layout="pageDirection" id="roles" value="#{userView.selectedUser.roles}"
......
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
xmlns:composite="http://java.sun.com/jsf/composite" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core"
>
<composite:interface>
</composite:interface>
<composite:implementation>
<h:outputScript target="head" library="script" name="jquery.min.js" />
<h:outputScript target="head" library="jpegcam" name="webcam.js" />
<h:outputScript target="head">
webcam.set_api_url( '#{request.contextPath}/UploadServlet?type=userimage&amp;id=#{userView.selectedUser.id}' );
webcam.set_hook('onComplete', 'my_completion_handler');
webcam.set_swf_url('#{request.contextPath}/resources/jpegcam/Webcam.swf');
webcam.set_shutter_sound(true,'#{request.contextPath}/resources/jpegcam/shutter.mp3');
function my_completion_handler(msg) {
// alert("Completition handler executed" + msg);
window.location.href=window.location.href;
}
</h:outputScript>
<button onclick="$('#webcamcontainer').prepend(webcam.get_html(320, 240));$('#webcamcontainer').show();$(this).hide();">#{i18n['userimage.webcam']}</button>
<div id="webcamcontainer" style="display: none;"></div>
<p>Voit lisätä kuvan kävijälippuasi varten. Näin nopeutat asiointiasi tapahtumaan tullessasi.</p>
<p>
Kuvasta on pystyttävä tunnistamaan ongelmitta kortin omistaja. Tästä johtuen kuvan tulee olla selkeä, eikä kuvassa saa
olla useita henkilöitä. Ohjeita hyvän tunnistekuvan ottamiseksi löytyy <a
href="http://www.poliisi.fi/poliisi/home.nsf/files/Passikuvaohje_26-02-2008_FI/$file/Passikuvaohje_26-02-2008_FI.pdf"
>poliisin passikuvaohjeesta.</a>
</p>
<form
onsubmit="window.open('', 'imagesubmitpopup', 'height=240,width=320'); this.target='imagesubmitpopup'; return true; "
action="#{request.contextPath}/UploadServlet?type=userimage" enctype="multipart/form-data" method="post"
>
<input type="hidden" name="id" value="#{userView.user.id}" />
<!-- <h:outputLabel value="#{i18n['imagefile.file']}" /> -->
<input type="file" name="file" />
<!-- <h:outputLabel value="#{i18n['imagefile.description']}"/><input type="text" name="description" /> -->
<input type="submit" name="submit" value="#{i18n['user.imagesubmit']}" />
</form>
<h2>#{i18n['user.thisIsCurrentImage']}</h2>
<h:outputText rendered="#{empty userView.user.currentImage}" value="#{i18n['user.noCurrentImage']}" />
<h:panelGroup rendered="#{!empty userView.user.currentImage}">
<img width="300" src="#{request.contextPath}/Userimage?imageid=#{userView.user.currentImage.id}" alt="image" />
</h:panelGroup>
</composite:implementation>
</html>
/* begin css tabs */
ul#tabnav { /* general settings */
text-align: left; /* set to left, right or center */
margin: 1em 0 1em 0; /* set margins as desired */
font: bold 11px verdana, arial, sans-serif; /* set font as desired */
border-bottom: 1px solid #6c6; /* set border COLOR as desired */
list-style-type: none;
padding: 3px 10px 3px 10px; /* THIRD number must change with respect to padding-top (X) below */
}
ul#tabnav li { /* do not change */
display: inline;
}
body#tab1 li.tab1, body#tab2 li.tab2, body#tab3 li.tab3, body#tab4 li.tab4 { /* settings for selected tab */
border-bottom: 1px solid #fff; /* set border color to page background color */
background-color: #fff; /* set background color to match above border color */
}
body#tab1 li.tab1 a, body#tab2 li.tab2 a, body#tab3 li.tab3 a, body#tab4 li.tab4 a { /* settings for selected tab link */
background-color: #fff; /* set selected tab background color as desired */
color: #000; /* set selected tab link color as desired */
position: relative;
top: 1px;
padding-top: 4px; /* must change with respect to padding (X) above and below */
}
ul#tabnav li a { /* settings for all tab links */
padding: 3px 4px; /* set padding (tab size) as desired; FIRST number must change with respect to padding-top (X) above */
border: 1px solid #6c6; /* set border COLOR as desired; usually matches border color specified in #tabnav */
background-color: #cfc; /* set unselected tab background color as desired */
color: #666; /* set unselected tab link color as desired */
margin-right: 0px; /* set additional spacing between tabs as desired */
text-decoration: none;
border-bottom: none;
}
ul#tabnav a:hover { /* settings for hover effect */
background: #fff; /* set desired hover color */
}
/* end css tabs */
\ No newline at end of file
......@@ -3,8 +3,7 @@
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
xmlns:role="http://java.sun.com/jsf/composite/cditools/role"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:role="http://java.sun.com/jsf/composite/cditools/role" xmlns:c="http://java.sun.com/jsp/jstl/core"
>
<h:body>
<ui:composition template="/layout/#{sessionHandler.layout}/template.xhtml">
......
......@@ -3,8 +3,7 @@
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
xmlns:role="http://java.sun.com/jsf/composite/cditools/role"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:role="http://java.sun.com/jsf/composite/cditools/role" xmlns:c="http://java.sun.com/jsp/jstl/core"
>
<h:body>
<ui:composition template="/layout/#{sessionHandler.layout}/template.xhtml">
......
......@@ -7,15 +7,16 @@
>
<h:body>
<ui:composition template="/layout/#{sessionHandler.layout}/template.xhtml">
<ui:param name="thispage" value="page.product.createBill" />
<f:metadata>
<f:viewParam name="userid" value="#{userView.userid}" />
<f:event type="preRenderView" listener="#{productShopView.initView}" />
</f:metadata>
<ui:define name="content">
<ui:define name="title">
<h1>#{i18n['page.product.createBill.header']}</h1>
</ui:define>
<ui:define name="content">
<h:form id="billshopform">
<products:shop commitaction="#{productShopView.commitBillCart()}" items="#{productShopView.shoppingcart}"
commitValue="#{i18n['productshop.commit']}"
......
......@@ -11,9 +11,11 @@
<f:viewParam name="userid" value="#{userView.userid}" />
<f:event type="preRenderView" listener="#{userView.initView}" />
</f:metadata>
<ui:param name="thispage" value="page.user.create" />
<ui:define name="title">
<h1>#{i18n['user.changepassword.title']}</h1>
</ui:define>
<ui:define name="content">
<h2>#{i18n['user.changepassword.forUser']}: #{userView.user.wholeName}</h2>
<h:form id="userform">
<h:panelGrid columns="2">
<h:outputLabel value="#{i18n['user.password']}:" />
......
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
......@@ -13,12 +12,13 @@
<f:event type="preRenderView" listener="#{userView.initView}" />
</f:metadata>
<ui:param name="thispage" value="page.user.edit" />
<!-- <ui:param name="thispage" value="page.user.edit" /> -->
<ui:define name="title">
<h1>#{i18n['user.edit.title']}</h1>
</ui:define>
<ui:define name="content">
<users:edit commitaction="#{userView.saveUser()}" commitvalue="#{i18n['user.save']}" />
<!--
<!--
<h2>#{i18n['user.accountEventHeader']}</h2>
<h:outputText rendered="#{userView.user.accountEvents.size() le 0}" value="#{i18n['user.noAccountevents']}" />
......@@ -94,7 +94,6 @@
</h:form>
-->
</ui:define>
</ui:composition>
</h:body>
</html>
\ No newline at end of file
......@@ -3,7 +3,7 @@
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
xmlns:users="http://java.sun.com/jsf/composite/tools/user" xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:users="http://java.sun.com/jsf/composite/cditools/user" xmlns:c="http://java.sun.com/jsp/jstl/core"
>
<h:body>
<ui:composition template="/layout/#{sessionHandler.layout}/template.xhtml">
......@@ -12,7 +12,11 @@
<f:viewParam name="userid" value="#{userView.userid}" />
<f:event type="preRenderView" listener="#{userView.initView}" />
</f:metadata>
<ui:define name="title">
<h1>#{i18n['sendPicture.header']}</h1>
</ui:define>
<ui:define name="content">
<users:sendImage />
</ui:define>
......
package fi.insomnia.bortal;
import java.io.IOException;
import java.security.AccessController;
import javax.security.auth.Subject;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
......@@ -53,7 +51,7 @@ public class HostnameFilter implements Filter {
httpRequest = ((HttpServletRequest) request);
StringBuffer url = httpRequest.getRequestURL();
Subject subj = Subject.getSubject(AccessController.getContext());
int beginindex = 7; // Let's skip http://
int slashindex = url.indexOf("/", beginindex);
......@@ -76,7 +74,7 @@ public class HostnameFilter implements Filter {
try {
httpRequest.login(User.ANONYMOUS_LOGINNAME, null);
} catch (Throwable t) {
logger.warn("Error logging in as anonymous... ignoring.. {}", t.getCause());
logger.warn("Error logging in as anonymous... ignoring.. ", t);
}
}
......
......@@ -20,7 +20,7 @@ public class NavigationHandler implements Serializable {
private String destNavi;
@Inject
private Conversation conversation;
private transient Conversation conversation;
public void saveDestination(String pageid) {
if (conversation.isTransient()) {
......
......@@ -94,7 +94,7 @@ public class SessionHandler {
public boolean hasPermission(IAppPermission permission) {
if (permission == null) {
logger.warn("permission {} is null", permission);
logger.warn("permission is null");
throw new RuntimeException("Empty target or permission!");
}
boolean ret = permbean.hasPermission(permission);
......
......@@ -77,11 +77,11 @@ page.permissionDenied.pagegroup=frontpage
page.bill.placemap.pagegroup=placemap
page.bill.listAll.pagegroup=admin
page.bill.listAll.pagegroup=shop
page.bill.edit.pagegroup=admin
page.bill.edit.pagegroup=shop
page.bill.billSummary.pagegroup=admin
page.bill.billSummary.pagegroup=shop
page.account.list.pagegroup=user
......
......@@ -95,7 +95,6 @@ mapView.errorWhenReleasingPlace=Paikkaa vapauttassa tapahtui virhe.
mapView.errorWhenReservingPlace=Paikkaa varatessa tapahtui virhe.
mapView.errorWhileBuyingPlaces=Virhe paikkojen ostossa. Ole hyv\u00e4 ja yrit\u00e4 uudelleen. Jos virhe toistuu ota yhteytt\u00e4 j\u00e4rjest\u00e4jiin.
mapView.notEnoughCreditsToReserve=Sinulla ei ole riitt\u00e4v\u00e4sti suoritettuja konepaikkamaksuja t\u00e4m\u00e4n paikan varaamiseen.
nasty.user=Wait, wot! Mene pois!
org.hibernate.validator.constraints.Email.message=not a well-formed email address
org.hibernate.validator.constraints.Length.message=length must be between {min} and {max}
org.hibernate.validator.constraints.NotEmpty.message=may not be empty
......@@ -232,20 +231,48 @@ sidebar.users=K\u00e4ytt\u00e4j\u00e4t
sidebar.utils.flushCache=Flush Cache
sidebar.utils.testdata=Testdata
topmenu.adminfront=Admintavaraa
topmenu.frontpage=Etusivu
menu.index=Etusivu
menu.user.edit=Omat tiedot
menu.place.placemap=Paikkakartta
menu.shop.createBill=Kauppa
submenu.shop.createBill=Luo lasku
submenu.bill.list=N\u00e4yt\u00e4 omat laskut
submenu.index=Etusivu
submenu.user.create=Luo uusi kyttj
submenu.auth.sendResetMail=Salasanan palautus
submenu.user.sendPicture=Lhet kuva
submenu.user.userlinks=Muokkaa tietoja
submenu.user.edit=K\u00e4ytt\u00e4j\u00e4n tiedot
user.changePassword=Vaihda salasana
submenu.user.changePassword=Vaihda salasana
submenu.user.accountEvents=Tilitapahtumat
submenu.place.myGroups=Omat paikkavaraukset
submenu.place.insertToken=Sy\u00f6t\u00e4 paikkakoodi
submenu.user.manageuserlinks=Hallitse k\u00e4ytt\u00e4ji\u00e4
submenu.user.list=Kaikki k\u00e4ytt\u00e4j\u00e4t
submenu.user.create=Luo k\u00e4ytt\u00e4j\u00e4
submenu.user.rolelinks=Hallitse rooleja
submenu.role.list=Roolit
submenu.role.create=Luo rooli
submenu.user.listCardTemplates=Korttiryhm\u00e4t
submenu.user.createCardTemplate=Luo korttiryhm\u00e4
topmenu.game=Insomnia Game
topmenu.placemap=Paikkakartta
topmenu.poll=Kyselyt
topmenu.rfidshop=Staffshop
topmenu.shoppings=Kauppa
topmenu.usersPreferences=Omat tiedot
user.accountBalance=Tilin saldo
user.accountEventHeader=Tilitapahtumat
user.accountEvents=Tilitapahtumat
user.address=Osoite
user.bank=Pankki
user.bankaccount=Pankkitili
user.changePassword=Vaihda salasana
user.create=Luo k\u00e4ytt\u00e4j\u00e4
user.createdmessage=K\u00e4ytt\u00e4j\u00e4tunnus on luotu onnistuneesti. Voit nyt kirjautua sis\u00e4\u00e4n.
user.defaultImage=Oletukuva
......@@ -255,10 +282,8 @@ user.firstNames=Etunimi
user.hasImage=Kuva
user.imagelist=Tallennetut kuvat
user.imagesubmit=L\u00e4het\u00e4 kuva
user.insertToken=Sy\u00f6t\u00e4 paikkakoodi
user.lastName=Sukunimi
user.login=K\u00e4ytt\u00e4j\u00e4tunnus
user.myGroups=Omat paikkavaraukset
user.nick=Nick
user.noAccountevents=Ei tilitapahtumia
user.noCurrentImage=Ei kuvaa
......@@ -271,7 +296,8 @@ user.realname=Nimi
user.roles=Roolit
user.rolesave=Tallenna roolit
user.save=Tallenna
user.sendPicture=Kuvan l\u00e4hetys
user.sendPicture=Kuvan lhetys
sendPicture.header=Lhet kuva
user.sex.FEMALE=Nainen
user.sex.MALE=Mies
user.sex.UNDEFINED=M\u00e4\u00e4rittelem\u00e4tt\u00e4
......@@ -301,9 +327,13 @@ page.auth.logout.header=Uloskirjautuminen
page.bill.billSummary.header=Laskujen yhteenveto
bill.markedPaid=Lasku merkitty maksetuksi.
page.product.createBill.header=Osta tuotteita
page.index.header=Etusivu
page.user.edit.header=Omat tiedot
index.title=Etusivu
user.edit.title=K\u00e4ytt\u00e4j\u00e4n tiedot
user.changepassword.title=Vaihda salasana
user.changepassword.forUser=K\u00e4ytt\u00e4j\u00e4lle
page.place.placemap.header=Paikkakartta
page.bill.list.header=Laskut
page.bill.edit.header=Laskun tiedot
page.auth.logoutsuccess.header=Logout
......@@ -315,3 +345,15 @@ page.account.list.header=Tilitapahtumat
applicationPermission.name=Oikeusryhm\u00e4
applicationPermission.description=kuvaus
userlist.header=Etsi k\u00e4ytt\u00e4ji\u00e4
userlist.search=Etsi
pagination.results=Tuloksia
pagination.pages=Sivuja
pagination.firstpage=Ensimm\u00e4inen
pagination.previouspage=Edellinen
pagination.nextpage=Seuraava
pagination.lastpage=Viimeinen
page.bill.edit.pagegroup=rai
page.bill.billSummary.pagegroup=asdasd
page.bill.placemap.pagegroup=
page.bill.listAll.pagegroup=
page.permissionDenied.pagegroup=
#Default Category
page.permissionDenied.pagegroup=frontpage
page.bill.placemap.pagegroup=placemap
page.bill.listAll.pagegroup=shop
page.bill.edit.pagegroup=shop
page.bill.billSummary.pagegroup=shop
......@@ -24,10 +24,10 @@ public class PlaceGroupPdf extends HttpServlet {
private static final long serialVersionUID = 1L;
@EJB
private PlaceGroupBeanLocal pgbean;
private transient PlaceGroupBeanLocal pgbean;
@EJB
private PermissionBeanLocal permbean;
private transient PermissionBeanLocal permbean;
private static final Logger logger = LoggerFactory.getLogger(PlaceGroupPdf.class);
/**
......
......@@ -45,10 +45,10 @@ public class PlaceMap extends HttpServlet {
*/
private static final long serialVersionUID = 8769688627918936258L;
@EJB
private PlaceMapBeanLocal placemapBean;
private transient PlaceMapBeanLocal placemapBean;
@EJB
private PermissionBeanLocal permbean;
private transient PermissionBeanLocal permbean;
private static final String PARAMETER_EVENT_MAP_ID = "mapid";
......@@ -104,11 +104,11 @@ public class PlaceMap extends HttpServlet {
* () + "</h1>"); out.println("</body>"); out.println("</html>");
*/
} catch (PermissionDeniedException e) {
logger.debug("Permission denied. Returning SC_NOT_FOUND!");
logger.debug("Permission denied. Returning SC_FORBIDDEN!");
response.setContentType("text/html;charset=UTF-8");
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
ostream = response.getOutputStream();
ostream.print("Permission denied!");
ostream.print("Error 403 \nPermission denied! Please login before accessing resource");
} finally {
if (ostream != null) {
ostream.close();
......@@ -229,6 +229,10 @@ public class PlaceMap extends HttpServlet {
private static final int BORDER_WIDTH = 2;
private static void drawPlace(Place p, Graphics2D g, User user) {
if (p.isDisabled())
{
return;
}
Color color = null;
if (!p.isBuyable()) {
color = LOCKED_COLOR;
......@@ -251,5 +255,4 @@ public class PlaceMap extends HttpServlet {
g.fill(new Rectangle(p.getMapX() + BORDER_WIDTH, p.getMapY() + BORDER_WIDTH, p.getWidth() - BORDER_WIDTH, p.getHeight() - BORDER_WIDTH));
}
}
}
......@@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.ejb.EJB;
import javax.ejb.EJBAccessException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
......@@ -24,9 +25,9 @@ public class PrintBill extends HttpServlet {
private static final String BILL_ID = "billid";
@EJB
private BillBeanLocal billentity;
private transient BillBeanLocal billentity;
@EJB
private EventBeanLocal eventbean;
private transient EventBeanLocal eventbean;
/**
* @see HttpServlet#HttpServlet()
......@@ -47,10 +48,9 @@ public class PrintBill extends HttpServlet {
private void ouput(HttpServletRequest request, HttpServletResponse response) throws IOException {
Integer billid = ServletUtils.getIntegerParameter(request, BILL_ID);
Bill bill;
try {
bill = billentity.findById(billid);
Integer billid = ServletUtils.getIntegerParameter(request, BILL_ID);
Bill bill = billentity.findById(billid);
if (bill == null) {
return;
......@@ -66,9 +66,14 @@ public class PrintBill extends HttpServlet {
ServletOutputStream ostream = response.getOutputStream();
billstream.writeTo(ostream);
ostream.close();
return;
} catch (EJBAccessException e) {
} catch (PermissionDeniedException e) {
response.getWriter().println("Permission denied!");
}
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.getWriter().println("ERROR 403\nPermission denied! Please login before trying to access resource.");
}
/**
......
......@@ -49,12 +49,12 @@ public class UploadServlet extends HttpServlet {
}
@EJB
private UserBeanLocal userbean;
private transient UserBeanLocal userbean;
@EJB
private EventMapBeanLocal eventmapbean;
private transient EventMapBeanLocal eventmapbean;
@EJB
private UtilBeanLocal utilbean;
private transient UtilBeanLocal utilbean;
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
......@@ -73,20 +73,26 @@ public class UploadServlet extends HttpServlet {
String contenttype = "";
byte[] imagedata = null;
int destId = 0;
Integer destId = 0;
String description = "";
String filename = "";
String idstr = request.getParameter("id");
if (idstr != null) {
destId = Integer.parseInt(idstr);
try {
destId = Integer.parseInt(idstr);
} catch (NumberFormatException e)
{
logger.warn("Could not parse ID from string: {}", idstr);
destId = null;
}
}
for (Object ti : upload.parseRequest(request)) {
if (ti instanceof FileItem) {
FileItem fi = (FileItem) ti;
if (fi.getFieldName().equals("id")) {
if (fi.getFieldName().equals("id") && !fi.getString().isEmpty()) {
logger.debug("Parsing int {}", fi.getString());
destId = Integer.parseInt(fi.getString());
......
......@@ -46,7 +46,7 @@ public class UserImageServlet extends HttpServlet {
}
@EJB
private UserBeanLocal userbean;
private transient UserBeanLocal userbean;
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
......
......@@ -24,6 +24,7 @@ public abstract class GenericCDIView implements Serializable {
private static final long serialVersionUID = -4000065015178815761L;
@Inject
private Conversation conversation;
private static final Logger logger = LoggerFactory.getLogger(GenericCDIView.class);
@Inject
......@@ -46,18 +47,23 @@ public abstract class GenericCDIView implements Serializable {
}
public boolean hasPermission(IAppPermission perm) {
// boolean ret =
// FacesContext.getCurrentInstance().getExternalContext().isUserInRole(perm.getFullName());
return permbean.hasPermission(perm);
}
protected boolean requirePermissions(IAppPermission perm, boolean... externalChecks) {
boolean[] perms = new boolean[externalChecks.length + 1];
perms[0] = permbean.hasPermission(perm);
if (externalChecks.length == 0) {
System.arraycopy(externalChecks, 0, perms, 1, externalChecks.length);
boolean ret = requirePermissions(hasPermission(perm));
if (ret && externalChecks.length > 0) {
ret = requirePermissions(externalChecks);
}
boolean ret = requirePermissions(perms);
if (!ret) {
logger.info("Permission required failed for {} / {}", perm.getParent(), perm);
logger.info("Permission required failed for {}", perm.getFullName());
}
return ret;
}
......
......@@ -32,16 +32,16 @@ public class MapManageView extends GenericCDIView {
private static final long serialVersionUID = -3276250982780044688L;
private static final Logger logger = LoggerFactory.getLogger(MapManageView.class);
@EJB
private UserBeanLocal userBean;
private transient UserBeanLocal userBean;
@EJB
private EventBeanLocal eventBean;
private transient EventBeanLocal eventBean;
@EJB
private EventMapBeanLocal eventmapBean;
private transient EventMapBeanLocal eventmapBean;
@EJB
private PlaceBeanLocal placebean;
private transient PlaceBeanLocal placebean;
@EJB
private ProductBeanLocal productbean;
private transient ProductBeanLocal productbean;
private List<EventMap> eventmaps;
private EventMap map;
private String mapname;
......@@ -113,7 +113,7 @@ public class MapManageView extends GenericCDIView {
public void generatePlaces() {
String[] tablenames = getNamebase().split(";");
List<Place> mapplaces = map.getPlaces();
logger.debug("places in map before {}", mapplaces.size());
if (mapplaces == null || mapplaces.isEmpty()) {
mapplaces = new ArrayList<Place>();
map.setPlaces(mapplaces);
......
......@@ -28,7 +28,7 @@ public class MapView extends GenericCDIView {
private static final long serialVersionUID = 2374905512998240551L;
@EJB
private PlaceMapBeanLocal placeMapBean;
private transient PlaceMapBeanLocal placeMapBean;
@Inject
@SelectedUser
......@@ -37,9 +37,9 @@ public class MapView extends GenericCDIView {
private EventMap activeMap;
@EJB
private PlaceBeanLocal placeBean;
private transient PlaceBeanLocal placeBean;
@EJB
private EventBeanLocal eventBean;
private transient EventBeanLocal eventBean;
private static final Logger logger = LoggerFactory.getLogger(MapView.class);
......@@ -58,13 +58,20 @@ public class MapView extends GenericCDIView {
return placeBean.totalReservationPrice(user, null);
}
public String releaseUsersPlaces() throws PermissionDeniedException {
placeBean.releaseUsersPlaces(user);
return "";
public Long getPlacesLeftToSelect() {
Long ret = placeMapBean.selectablePlaceCount(getActiveMap());
logger.info("Got {} places left for map {}", ret, getActiveMap());
return ret;
}
public Long placeLeftToSelect() {
return placeMapBean.selectablePlaceCount(getActiveMap());
public Long getAvailablePlaces()
{
Long ret = placeMapBean.availablePlaceCount(getActiveMap());
logger.info("Got {} availbale places for map {}", ret, getActiveMap());
return ret;
}
......
......@@ -39,9 +39,9 @@ public class PlaceView extends GenericCDIView {
private Place place;
@EJB
private UserBeanLocal userbean;
private transient UserBeanLocal userbean;
@EJB
private PlaceBeanLocal placebean;
private transient PlaceBeanLocal placebean;
@Inject
@SelectedUser
......@@ -50,7 +50,7 @@ public class PlaceView extends GenericCDIView {
private EventMap currentMap;
private String searchuser;
private ListDataModel<User> userlist;
private transient ListDataModel<User> userlist;
public boolean canEdit() {
return permbean.hasPermission(MapPermission.MANAGE_MAPS);
......@@ -62,7 +62,6 @@ public class PlaceView extends GenericCDIView {
return "/place/myGroups";
} catch (BortalCatchableException e) {
addFaceMessage("mapView.errorWhileBuyingPlaces");
placebean.releaseUsersPlaces(user);
}
return null;
}
......@@ -167,6 +166,7 @@ public class PlaceView extends GenericCDIView {
public String save() {
placebean.mergeChanges(place);
super.addFaceMessage("place.saved");
return null;
}
......
......@@ -31,18 +31,19 @@ public class PlacegroupView extends GenericCDIView {
@Inject
@SelectedUser
private User user;
@EJB
private PlaceGroupBeanLocal placegroupBean;
private transient PlaceGroupBeanLocal placegroupBean;
@EJB
private UserBeanLocal userbean;
private transient UserBeanLocal userbean;
private Place place;
private PlaceGroup group;
private ListDataModel<PlaceGroup> placegroups;
private ListDataModel<Place> placelist;
private transient ListDataModel<PlaceGroup> placegroups;
private transient ListDataModel<Place> placelist;
private ListDataModel<GroupMembership> memberlist;
private transient ListDataModel<GroupMembership> memberlist;
public String editGroup() {
setGroup(placegroups.getRowData());
......@@ -68,15 +69,17 @@ public class PlacegroupView extends GenericCDIView {
public String releasePlace() throws PermissionDeniedException {
GroupMembership row = memberlist.getRowData();
if (row != null && (permbean.isCurrentUser(row.getPlaceGroup().getCreator()) ||
permbean.hasPermission(MapPermission.MANAGE_OTHERS))) {
placegroupBean.releaseAndGenerateToken(row);
this.addFaceMessage("placegroupview.placeReleased", row.getPlaceReservation().getName());
} else {
this.addFaceMessage("placegroupview.placeReleaseFailed", row.getPlaceReservation().getName());
if (row != null)
{
if (permbean.isCurrentUser(row.getPlaceGroup().getCreator()) ||
permbean.hasPermission(MapPermission.MANAGE_OTHERS)) {
placegroupBean.releaseAndGenerateToken(row);
this.addFaceMessage("placegroupview.placeReleased", row.getPlaceReservation().getName());
} else {
this.addFaceMessage("placegroupview.placeReleaseFailed", row.getPlaceReservation().getName());
}
}
return null;
}
......
......@@ -25,7 +25,7 @@ public class TokenView extends GenericCDIView {
private User user;
@EJB
private PlaceGroupBeanLocal placegroupbean;
private transient PlaceGroupBeanLocal placegroupbean;
public String saveToken() throws PermissionDeniedException {
super.requirePermissions();
......
package fi.insomnia.bortal.web.cdiview.menu;
public class JsfMenuitem {
private final Menuitem item;
private boolean selected;
private final String text;
public JsfMenuitem(Menuitem item, String text) {
this.item = item;
this.text = text;
}
public MenuGroup getGroup() {
return item.getGroup();
}
public void setSelected() {
selected = true;
}
public boolean isSelected() {
return selected;
}
public String getOutcome() {
return item.getUrl();
}
public String getLinktext() {
return text;
}
public String getHeader() {
return item.getHeader();
}
public boolean isCid() {
return item.isCid();
}
}
package fi.insomnia.bortal.web.cdiview.menu;
import java.util.ArrayList;
import java.util.List;
public class MenuGroup {
private final List<Menuitem> items = new ArrayList<Menuitem>();
private final String groupname;
public MenuGroup(String name) {
groupname = name;
}
public void add(Menuitem menuitem) {
getItems().add(menuitem);
}
public String getGroupname() {
return groupname;
}
public List<Menuitem> getItems() {
return items;
}
}
package fi.insomnia.bortal.web.cdiview.menu;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;
import fi.insomnia.bortal.beans.PermissionBeanLocal;
import fi.insomnia.bortal.enums.apps.BillPermission;
import fi.insomnia.bortal.enums.apps.IAppPermission;
import fi.insomnia.bortal.enums.apps.UserPermission;
@RequestScoped
@Named
public class MenuView {
private static List<MenuGroup> PAGEGROUPS;
@Inject
private FacesContext context;
private String pagename;
@EJB
private PermissionBeanLocal permbean;
private ArrayList<JsfMenuitem> topmenu;
private ArrayList<JsfMenuitem> submenu;
private ResourceBundle rb;
private static final Map<String, Menuitem> PAGES;
private String localize(String key) {
String value = null;
try {
value = getResourcebundle().getString(key);
} catch (MissingResourceException e) {
value = null;
}
if (key == null) {
value = "########";
} else if (value == null) {
value = "???" + key + "???";
}
return value;
}
private ResourceBundle getResourcebundle() {
if (rb == null) {
rb = context.getApplication().getResourceBundle(context, "i18n");
}
return rb;
}
static {
Map<String, Menuitem> temppages = new HashMap<String, Menuitem>();
MenuGroup frontpage = new MenuGroup("frontpage");
MenuGroup user = new MenuGroup("user");
MenuGroup placemap = new MenuGroup("placemap");
MenuGroup shop = new MenuGroup("shop");
PAGEGROUPS = Collections.unmodifiableList(Arrays.asList(frontpage, user, placemap, shop));
addPage(temppages, "/index", frontpage, null);
addPage(temppages, "/user/create", frontpage, UserPermission.CREATE_NEW);
addPage(temppages, "/auth/sendResetMail", frontpage, UserPermission.LOGIN);
addPage(temppages, "/user/edit", user, UserPermission.VIEW_SELF).setHeader("submenu.user.userlinks").setCid(true);
addPage(temppages, "/user/changePassword", user, UserPermission.VIEW_SELF).setCid(true);
addPage(temppages, "/user/accountEvents", user, UserPermission.VIEW_SELF).setCid(true);
addPage(temppages, "/place/myGroups", user, UserPermission.VIEW_SELF).setCid(true);
addPage(temppages, "/place/insertToken", user, UserPermission.VIEW_SELF).setCid(true);
addPage(temppages, "/user/sendPicture", user, UserPermission.VIEW_SELF).setCid(true);
addPage(temppages, "/user/list", user, UserPermission.VIEW_ALL).setHeader("submenu.user.manageuserlinks");
addPage(temppages, "/user/create", user, UserPermission.VIEW_ALL);
addPage(temppages, "/role/list", user, UserPermission.READ_ROLES).setHeader("submenu.user.rolelinks");
addPage(temppages, "/role/create", user, UserPermission.WRITE_ROLES);
addPage(temppages, "/user/listCardTemplates", user, UserPermission.READ_ROLES);
addPage(temppages, "/user/createCardTemplate", user, UserPermission.WRITE_ROLES);
addPage(temppages, "/place/placemap", placemap, null);
addPage(temppages, "/shop/createBill", shop, BillPermission.CREATE_BILL).setCid(true);
addPage(temppages, "/bill/list", shop, BillPermission.VIEW_OWN).setCid(true);
PAGES = Collections.unmodifiableMap(temppages);
}
public String getPagename() {
if (pagename == null) {
HttpServletRequest req = (HttpServletRequest) context.getExternalContext().getRequest();
String[] splitted = req.getServletPath().split("\\.");
if (splitted.length > 0) {
pagename = splitted[0];
}
}
return pagename;
}
private static Menuitem addPage(Map<String, Menuitem> temppages, String url, MenuGroup group, IAppPermission perm) {
Menuitem ret = new Menuitem(url, group, perm);
temppages.put(url, ret);
return ret;
}
public void setContext(FacesContext context) {
this.context = context;
}
public FacesContext getContext() {
return context;
}
public List<JsfMenuitem> getTopmenu() {
if (topmenu == null) {
topmenu = new ArrayList<JsfMenuitem>();
Menuitem currentPage = PAGES.get(getPagename());
MenuGroup currentGroup = null;
if (currentPage != null) {
currentGroup = currentPage.getGroup();
}
for (MenuGroup m : PAGEGROUPS) {
for (Menuitem item : m.getItems()) {
if (permbean.hasPermission(item.getPermission())) {
JsfMenuitem thisitem = new JsfMenuitem(item, this.localize(item, "menu"));
topmenu.add(thisitem);
if (m.equals(currentGroup)) {
thisitem.setSelected();
}
break;
}
}
}
}
return topmenu;
}
private String localize(Menuitem item, String prefix) {
StringBuilder sb = new StringBuilder(prefix);
for (String part : item.getUrl().split("/")) {
if (!part.isEmpty()) {
sb.append(".").append(part);
}
}
return localize(sb.toString());
}
public void setSubmenu(ArrayList<JsfMenuitem> submenu) {
this.submenu = submenu;
}
public ArrayList<JsfMenuitem> getSubmenu() {
if (submenu == null) {
Menuitem currentPage = PAGES.get(getPagename());
if (currentPage != null) {
MenuGroup currentGroup = currentPage.getGroup();
submenu = new ArrayList<JsfMenuitem>();
for (Menuitem item : currentGroup.getItems()) {
if (permbean.hasPermission(item.getPermission())) {
JsfMenuitem thisitem = new JsfMenuitem(item, localize(item, "submenu"));
submenu.add(thisitem);
if (currentPage.equals(item)) {
thisitem.setSelected();
}
}
}
}
}
return submenu;
}
}
package fi.insomnia.bortal.web.cdiview.menu;
import fi.insomnia.bortal.enums.apps.IAppPermission;
public class Menuitem {
private final String url;
private final MenuGroup group;
private final IAppPermission permission;
private String header;
private boolean cid = false;
public Menuitem(String url, MenuGroup group, IAppPermission perm) {
this.url = url;
this.permission = perm;
this.group = group;
group.add(this);
}
public String getUrl() {
return url;
}
public MenuGroup getGroup() {
return group;
}
public IAppPermission getPermission() {
return permission;
}
public Menuitem setHeader(String string) {
header = string;
return this;
}
public String getHeader() {
return header;
}
public void setCid(boolean val) {
this.cid = val;
}
public boolean isCid() {
return cid;
}
}
......@@ -21,7 +21,7 @@ public class NewsListView extends GenericCDIView {
private static final long serialVersionUID = 1720809638296537794L;
@EJB
private NewsBeanLocal newsbean;
private transient NewsBeanLocal newsbean;
private List<NewsGroup> newsgroups;
......
......@@ -13,7 +13,7 @@ public class NewsView extends GenericCDIView {
private static final long serialVersionUID = 4141547312297765524L;
@EJB
private NewsBeanLocal newsbean;
private transient NewsBeanLocal newsbean;
private NewsGroup group;
......
......@@ -19,7 +19,7 @@ public class NewsgroupView extends GenericCDIView {
private static final long serialVersionUID = 1752803732191587695L;
private int newsgroupid;
@EJB
private NewsBeanLocal newsbean;
private transient NewsBeanLocal newsbean;
private NewsGroup newsgroup;
public void initView() {
......
......@@ -21,9 +21,9 @@ public class EventOrgView extends GenericCDIView {
private static final long serialVersionUID = -1351272199807699797L;
@EJB
private EventOrganiserBeanLocal eventorgbean;
private transient EventOrganiserBeanLocal eventorgbean;
@EJB
private EventBeanLocal eventbean;
private transient EventBeanLocal eventbean;
@LoggedIn
@Inject
......
......@@ -27,7 +27,7 @@ public class PollView extends GenericCDIView {
private static final long serialVersionUID = -7636682120192671958L;
@EJB
private PollBeanLocal pollBean;
private transient PollBeanLocal pollBean;
private List<Poll> polls;
private HashMap<Integer, List<QuestionWrapper>> pages;
......@@ -128,7 +128,7 @@ public class PollView extends GenericCDIView {
return pages;
}
public class QuestionWrapper {
public static class QuestionWrapper {
private PollQuestion question;
private ArrayList<PollAnswer> answers;
......
......@@ -23,7 +23,7 @@ public class BillEditView extends GenericCDIView {
private Bill bill;
@EJB
private BillBeanLocal billbean;
private transient BillBeanLocal billbean;
public void initView() throws PermissionDeniedException {
if (this.requirePermissions(permbean.isLoggedIn())) {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!