Commit 7cb69d31 by Tuukka Kivilahti

Merge branch 'master' of codecrew.fi:codecrew/moya

2 parents 5b540454 fe44ba6d
No preview for this file type
......@@ -86,13 +86,14 @@ public class MoyaLoginModule extends AppservPasswordLoginModule {
// Authenticate User
MoyaRealm samplerealm = (MoyaRealm) _currentRealm;
if (!authbean.authenticate(_username, new String(_passwd))) {
AuthenticationResult authResult = authbean.authUsername(_username, new String(_passwd));
if (authResult == null || authResult.getUsername() == null) {
// Login fails
throw new LoginException((new StringBuilder())
.append("moya realm:Login Failed for user ")
.append(_username).toString());
}
_username = authResult.getUsername();
// Login succeeds
log((new StringBuilder()).append("MoyaRealm:login succeeded for ")
.append(_username).toString());
......@@ -100,7 +101,7 @@ public class MoyaLoginModule extends AppservPasswordLoginModule {
// Get group names for the authenticated user from the Realm class
Enumeration<String> enumeration = null;
try {
enumeration = samplerealm.getGroupNames(_username);
enumeration = samplerealm.getGroupNames(_username, authResult.getUsertype());
} catch (InvalidOperationException invalidoperationexception) {
throw new LoginException(
(new StringBuilder())
......
......@@ -89,7 +89,7 @@ public class MoyaRealm extends AppservRealm {
*/
@Override
public String getAuthType() {
return "Omnia Lan system authentication Realm";
return "Moya authentication Realm";
}
/**
......@@ -127,4 +127,8 @@ public class MoyaRealm extends AppservRealm {
}
public Enumeration<String> getGroupNames(String username, String usertype) throws InvalidOperationException, NoSuchUserException {
return getAuthBean().getGroupNames(username, usertype);
}
}
package fi.codecrew.moya;
public class AuthenticationResult {
private String username = null;
private String usertype = null;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUsertype() {
return usertype;
}
public void setUsertype(String usertype) {
this.usertype = usertype;
}
}
......@@ -13,4 +13,8 @@ public interface MoyaRealmBeanRemote {
boolean authenticate(String _username, String string);
AuthenticationResult authUsername(String _username, String string);
Enumeration<String> getGroupNames(String username, String usertype);
}
......@@ -11,18 +11,24 @@ import javax.ejb.Stateless;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fi.codecrew.moya.AuthenticationResult;
import fi.codecrew.moya.MoyaRealmBeanRemote;
import fi.codecrew.moya.enums.BortalApplication;
import fi.codecrew.moya.enums.apps.IAppPermission;
import fi.codecrew.moya.enums.apps.SpecialPermission;
import fi.codecrew.moya.enums.apps.UserPermission;
import fi.codecrew.moya.facade.ApiApplicationFacade;
import fi.codecrew.moya.facade.ApiApplicationInstanceFacade;
import fi.codecrew.moya.facade.EventUserFacade;
import fi.codecrew.moya.facade.UserFacade;
import fi.codecrew.moya.model.ApiApplication;
import fi.codecrew.moya.model.ApiApplicationInstance;
import fi.codecrew.moya.model.ApplicationPermission;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.LanEvent;
import fi.codecrew.moya.model.Role;
import fi.codecrew.moya.model.User;
import fi.codecrew.moya.utilities.PasswordFunctions;
/**
* Session Bean implementation class SessionHandlerBean
......@@ -48,6 +54,13 @@ public class JaasBean implements MoyaRealmBeanRemote {
@EJB
private EventBeanLocal eventbean;
@EJB
private RestBean restbean;
@EJB
private ApiApplicationFacade appfacade;
@EJB
private ApiApplicationInstanceFacade appInstanceFacade;
public EventUser tryLogin(String username, String password) {
EventUser eventUser = eventUserFacade.findByLogin(username.trim().toLowerCase());
......@@ -97,15 +110,45 @@ public class JaasBean implements MoyaRealmBeanRemote {
// }
// }
public static enum UserType
{
USER, REST
}
@Override
public boolean authenticate(String username, String password) {
boolean ret = (tryLogin(username, password) != null);
public AuthenticationResult authUsername(String username, String password) {
AuthenticationResult ret = new AuthenticationResult();
ret.setUsertype(UserType.USER.name());
if ((username == null || username.isEmpty()) && password.startsWith("rest:")) {
ret.setUsertype(UserType.REST.name());
ret.setUsername(restAuth(password));
} else {
EventUser retUser = tryLogin(username, password);
if (retUser != null) {
ret.setUsername(retUser.getLogin());
}
}
return ret;
}
@Override
public Enumeration<String> getGroupNames(String user) {
logger.info("Fetching groupNames for user {} event {}", user, eventbean.getCurrentEvent().getName());
public boolean authenticate(String username, String password) {
return (tryLogin(username, password) != null);
}
private String restAuth(String restauth) {
String[] authsplit = restauth.split(":");
if (authsplit.length != 6 || !authsplit[0].equals("rest")) {
return null;
}
return authenticateApp(authsplit[1], authsplit[2], authsplit[3], authsplit[4], authsplit[5]);
}
@Override
public Enumeration<String> getGroupNames(String user, String usertype) {
EventUser usr = eventUserFacade.findByLogin(user.toLowerCase().trim());
HashSet<String> roleset = new HashSet<String>();
roleset.add(UserPermission.ANYUSER.getFullName());
......@@ -119,6 +162,23 @@ public class JaasBean implements MoyaRealmBeanRemote {
roleset.add(SpecialPermission.ANONYMOUS.name());
}
if (usertype != null) {
try {
switch (UserType.valueOf(usertype))
{
case REST:
roleset.add(SpecialPermission.REST.name());
break;
case USER:
break;
default:
throw new RuntimeException("Unknown user type: " + usertype);
}
} catch (Throwable t) {
logger.warn("UserType authentication " + usertype);
}
}
if (!usr.getUser().isAnonymous()) {
// all logged in users should be able to logout :)
roleset.add(UserPermission.LOGOUT.name());
......@@ -152,8 +212,46 @@ public class JaasBean implements MoyaRealmBeanRemote {
Vector<String> retvect = new Vector<String>();
retvect.addAll(roleset);
logger.info("group names for user {}: {}", user, retvect);
logger.debug("group names for user {}: {}", user, retvect);
return retvect.elements();
}
@Override
public Enumeration<String> getGroupNames(String username) {
return getGroupNames(username, null);
}
public String authenticateApp(String pathInfo, String appId, String userId, String appStamp, String mac) {
if (mac == null)
return null;
ApiApplication app = appfacade.findByAppid(appId);
if (app == null)
return null;
ApiApplicationInstance apiInstance = appInstanceFacade.findInstance(app, userId);
if (apiInstance == null)
return null;
if (!app.isEnabled() || !apiInstance.isEnabled())
return null;
String ret = null;
String macSource = PasswordFunctions.mkSeparatedString("+", pathInfo, appId, userId, appStamp, apiInstance.getSecretKey());
String macHash = PasswordFunctions.calculateSha1(macSource);
if (mac.equalsIgnoreCase(macHash))
{
switch (app.getAuthtype()) {
case ORGAUTH:
ret = User.ANONYMOUS_LOGINNAME;
break;
case USERKEY:
if (apiInstance.getEventuser() != null) {
ret = apiInstance.getEventuser().getUser().getLogin();
}
break;
default:
throw new RuntimeException("Unknown application authtype!");
}
}
return ret;
}
}
......@@ -200,15 +200,15 @@ public class PlaceBean implements PlaceBeanLocal {
place = placeFacade.find(place.getId());
user = eventUserFacade.find(user.getId());
boolean ret = false;
// when admin click's place, he reserves it -> just ignore it
if (!place.isTaken() || (permbean.hasPermission(MapPermission.MANAGE_OTHERS) && permbean.getCurrentUser().equals(place.getCurrentUser()) )) {
if (!place.isTaken() || (permbean.hasPermission(MapPermission.MANAGE_OTHERS) && permbean.getCurrentUser().equals(place.getCurrentUser()))) {
if (place.isBuyable() || permbean.hasPermission(MapPermission.MANAGE_OTHERS)) {
if(!place.isBuyable()) {
if (!place.isBuyable()) {
place.setBuyable(true);
}
place.setCurrentUser(user);
place.setReleaseTime(Calendar.getInstance());
place.getReleaseTime().add(Calendar.MINUTE, RESERVE_MINUTES);
......@@ -249,7 +249,7 @@ public class PlaceBean implements PlaceBeanLocal {
// }
// logger.debug("timeouting places");
// placeFacade.releasePlaces(permbean.getCurrentUser());
// }
// }
@Override
@RolesAllowed({ MapPermission.S_BUY_PLACES, MapPermission.S_MANAGE_OTHERS })
public PlaceGroup buySelectedPlaces(EventUser user) throws BortalCatchableException {
......@@ -283,7 +283,7 @@ public class PlaceBean implements PlaceBeanLocal {
}
// PlaceGroup pg = pgbean.createPlaceGroup(user);
if (!createAccountevents)
if (createAccountevents)
{
BigDecimal totalprice = addAndCalcPrice(user, null);
BigDecimal balance = user.getAccountBalance();
......@@ -553,7 +553,8 @@ public class PlaceBean implements PlaceBeanLocal {
PDF pdf = new PDF(outputStream);
pdf.setTitle("Place");
float pointInMillim = (25.4f / 72.0f); // 1 point is 1/72 inches. 1 inch = 25.4mm
float pointInMillim = (25.4f / 72.0f); // 1 point is 1/72 inches. 1 inch
// = 25.4mm
float pagex = width / pointInMillim;
float pagey = height / pointInMillim;
......@@ -572,7 +573,7 @@ public class PlaceBean implements PlaceBeanLocal {
double currentX = 42;
// nick
// nick
if (place.getPlaceReserver() != null && place.getPlaceReserver().getUser() != null) {
font = new com.pdfjet.Font(pdf, CoreFont.HELVETICA);
font.setSize(font2);
......@@ -584,7 +585,7 @@ public class PlaceBean implements PlaceBeanLocal {
textLine.drawOn(page);
}
// place hex code
// place hex code
font = new com.pdfjet.Font(pdf, CoreFont.HELVETICA);
font.setSize(font2);
......
......@@ -19,7 +19,6 @@ import fi.codecrew.moya.facade.ReaderEventFacade;
import fi.codecrew.moya.facade.ReaderFacade;
import fi.codecrew.moya.model.AccountEvent;
import fi.codecrew.moya.model.CardCode;
import fi.codecrew.moya.model.CardTemplate;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.Place;
import fi.codecrew.moya.model.PrintedCard;
......@@ -38,12 +37,10 @@ public class ReaderBean implements ReaderBeanLocal {
@EJB
private ReaderFacade readerfacade;
@EJB
private PrintedCardFacade cardfacade;
@EJB
private CardTemplateBeanLocal cardtemplatebean;
@EJB
......@@ -56,12 +53,10 @@ public class ReaderBean implements ReaderBeanLocal {
private CardTemplateBean cardTemplateBean;
@EJB
private ProductPBean productPBean;
@EJB
private CardCodeFacade cardCodeFacade;
@EJB
private BarcodeBeanLocal barcodeBean;
......@@ -72,18 +67,21 @@ public class ReaderBean implements ReaderBeanLocal {
Reader reader = readerfacade.findOrCreateByIdent(readerIdent);
return checkCode(reader, code);
}
@Override
/**
* check reader code, and add it to the database
*/
public ReaderEvent checkCode(Reader reader, String code) {
if (reader == null || code == null || code.isEmpty()) {
return null;
}
logger.info("got code from reader {}", code);
code = code.replace("\"\b", "");
if (reader.getType() == ReaderType.RFID) {
if (ReaderType.RFID.equals(reader.getType())) {
if (Pattern.matches("^.*000000$", code))
{
......@@ -96,65 +94,63 @@ public class ReaderBean implements ReaderBeanLocal {
}
code = sb.toString();
}
ReaderEvent event = new ReaderEvent(new Date(), reader, code);
// first, check if dublicate, there is 30s timeout for dublicates, afther that it's ok to create dublicate
// that's bcause accident dublicates are bad, but otherwise it's probably bcause user want's to read it again
// first, check if dublicate, there is 30s timeout for dublicates,
// afther that it's ok to create dublicate
// that's bcause accident dublicates are bad, but otherwise it's
// probably bcause user want's to read it again
List<ReaderEvent> lastevents = readerEventFacade.findLastEvents(reader, 1);
if (!lastevents.isEmpty() && !reader.isAutoproduct())
{
ReaderEvent lastevent = lastevents.get(0);
if(lastevent.getValue() == event.getValue() && (lastevent.getUpdatetime().getTime() + 60000l) > event.getTime().getTime()) {
if (lastevent.getValue() == event.getValue() && (lastevent.getUpdatetime().getTime() + 60000l) > event.getTime().getTime()) {
lastevent = readerEventFacade.reload(lastevent);
lastevent = readerEventFacade.merge(lastevent);
return lastevent; // todo: update lastevent bfore return
}
}
// find stuff with barcode and set type
// IF we find 2 stuff with same barcode, it's just bad luck and things may be little random.
// IF we find 2 stuff with same barcode, it's just bad luck and things
// may be little random.
EventUser user = barcodeBean.getUser(code);
if(user != null) {
if (user != null) {
event.setType(ReaderEventType.USER);
event.setUser(user);
}
PrintedCard card = barcodeBean.getPrintedCard(code);
if(card != null) {
if (card != null) {
event.setType(ReaderEventType.CARD);
event.setPrintedCard(card);
if(card.getUser() != null) {
if (card.getUser() != null) {
event.setUser(card.getUser());
}
}
Product product = barcodeBean.getProduct(code);
if(product != null) {
if (product != null) {
event.setType(ReaderEventType.PRODUCT);
event.setProduct(product);
}
Place place = barcodeBean.getPlaceFromBarcode(code);
if(place != null) {
if (place != null) {
event.setType(ReaderEventType.PLACE);
event.setPlace(place);
}
event.setUpdatetime(new Date());
// reader is in autoproduct-mode, create dat product
......@@ -166,19 +162,18 @@ public class ReaderBean implements ReaderBeanLocal {
event.setNotes("Created automatic account event from reader. " + createAc);
}
event = readerEventFacade.create(event);
return event;
}
@Override
public ReaderEvent assocCodeToCard(ReaderEvent readerEvent, PrintedCard card) {
CardCode code = new CardCode(card, readerEvent.getReader().getType(), readerEvent.getValue());
code = cardCodeFacade.create(code);
card = cardfacade.reload(card);
......@@ -197,7 +192,7 @@ public class ReaderBean implements ReaderBeanLocal {
@Override
public List<ReaderEvent> getReaderEvents(Integer readerId, Integer count) {
logger.info("Getting events for reader {}", readerId);
Reader reader = readerfacade.find(readerId);
return readerEventFacade.findLastEvents(reader, count);
......@@ -236,34 +231,25 @@ public class ReaderBean implements ReaderBeanLocal {
return ret;
}
// ok, let's comment this out, so I can see where this is used
/*
@Override
public ReaderEvent createCard(ReaderEvent event, EventUser user) {
ReaderEvent ret = null;
logger.info("Trying to create card for event {} with printed card {}", event, event.getPrintedCard());
if (event.getPrintedCard() == null)
{
CardTemplate ct = cardTemplateBean.getUsersCardtype(user);
logger.info("Card template {}", ct);
if (ct == null)
{
return null;
}
PrintedCard card = new PrintedCard(user, ct, null, true);
card.setRfidUid(event.getValue());
cardfacade.create(card);
ret = new ReaderEvent(Calendar.getInstance(), card, event.getReader());
card.getReaderEvents().add(event);
ret.setNotes("User associated to a card");
}
return ret;
}
*/
* @Override public ReaderEvent createCard(ReaderEvent event, EventUser
* user) { ReaderEvent ret = null;
* logger.info("Trying to create card for event {} with printed card {}",
* event, event.getPrintedCard());
*
* if (event.getPrintedCard() == null) { CardTemplate ct =
* cardTemplateBean.getUsersCardtype(user); logger.info("Card template {}",
* ct); if (ct == null) { return null; } PrintedCard card = new
* PrintedCard(user, ct, null, true); card.setRfidUid(event.getValue());
* cardfacade.create(card);
*
* ret = new ReaderEvent(Calendar.getInstance(), card, event.getReader());
* card.getReaderEvents().add(event);
* ret.setNotes("User associated to a card");
*
* } return ret; }
*/
@Override
public Reader getReader(Integer readerid) {
......
package fi.codecrew.moya.beans;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.SessionContext;
import javax.ejb.Singleton;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fi.codecrew.moya.facade.ApiApplicationFacade;
import fi.codecrew.moya.facade.ApiApplicationInstanceFacade;
import fi.codecrew.moya.utilities.PasswordFunctions;
/**
* Session Bean implementation class RestAuthBean
*/
@Singleton
@LocalBean
public class RestBean implements RestBeanLocal {
/**
* Default constructor.
*/
public RestBean() {
// TODO Auto-generated constructor stub
}
@Resource
private TimerService ts;
@Resource
private SessionContext context;
private static final Logger logger = LoggerFactory.getLogger(RestBean.class);
@PostConstruct
public void initialize() {
ts.createTimer(60 * 1000, 60 * 1000, null);
}
@EJB
private ApiApplicationFacade appfacade;
@EJB
private ApiApplicationInstanceFacade apiInstanceFacade;
@Timeout
public void timeoutNonces(Timer timer) {
int count = 0;
long now = System.currentTimeMillis();
synchronized (userRestAuths) {
for (Map<String, Long> ua : userRestAuths.values()) {
for (Entry<String, Long> no : ua.entrySet()) {
if (no != null && now > no.getValue()) {
ua.remove(no.getKey());
++count;
}
}
}
}
logger.info("Timeouted {} nonces", count);
}
// Username -> Nonce -> expiration
private Map<String, Map<String, Long>> userRestAuths = Collections.synchronizedMap(new HashMap<String, Map<String, Long>>());
@Override
public String getLoggedinUserRestNonce()
{
String username = context.getCallerPrincipal().getName();
if (username == null) {
return null;
}
Map<String, Long> userAuthMap = userRestAuths.get(username);
if (userAuthMap == null) {
synchronized (userRestAuths) {
if (!userRestAuths.containsKey(username)) {
userAuthMap = Collections.synchronizedMap(new HashMap<String, Long>());
userRestAuths.put(username, userAuthMap);
}
}
}
Random random = new Random();
int charcount = 20 + random.nextInt(10);
String nonce = null;
do {
nonce = PasswordFunctions.generateRandomString(charcount, PasswordFunctions.ALL_CHARS);
} while (userAuthMap.containsKey(nonce));
userAuthMap.put(nonce, System.currentTimeMillis() + 120 * 1000); // Timeout in 60 seconds.
return nonce;
}
@Override
public boolean validateUserNonce(String nonce) {
String username = context.getCallerPrincipal().getName();
boolean ret = false;
// Validation is successfull if user exists, nonce exists and timeout has not passed.
if (username != null && userRestAuths.containsKey(username)) {
Long time = userRestAuths.get(username).remove(nonce);
ret = time != null && time > System.currentTimeMillis();
}
return ret;
}
}
......@@ -77,7 +77,8 @@ public class UserBean implements UserBeanLocal {
private static final Logger logger = LoggerFactory.getLogger(UserBean.class);
/**
* Java EE container injektoi tämän luokkamuuttujan luokan luonnin yhteydessä.
* Java EE container injektoi tämän luokkamuuttujan luokan luonnin
* yhteydessä.
*/
@EJB
private UserFacade userFacade;
......@@ -167,8 +168,9 @@ public class UserBean implements UserBeanLocal {
// private EventUser currentEventuser;
// private ArrayList<Role> currentEventuserRoles;
// HUOMHUOM! Älä määrittele tätä UserBeanLocal interfacelle.
// Käytä Viewien puolelta findUsersRoles joka tarkistaa käyttäjän oikeudet ensin.
// HUOMHUOM! Älä määrittele tätä UserBeanLocal interfacelle.
// Käytä Viewien puolelta findUsersRoles joka tarkistaa käyttäjän oikeudet
// ensin.
public Set<Role> localFindUsersRoles(EventUser u) {
// if (currentEventuser != null && u.equals(currentEventuser)) {
// logger.debug("Returnin cached eventuserroles for user {}: {}",
......@@ -275,7 +277,7 @@ public class UserBean implements UserBeanLocal {
bimage = resized;
}
bimage = forceCrop(bimage);
ByteArrayOutputStream naamaout = new ByteArrayOutputStream();
......@@ -300,42 +302,42 @@ public class UserBean implements UserBeanLocal {
return userimage;
}
private BufferedImage forceCrop(BufferedImage source) {
int x,y,xl,yl,xh,yh,xc,yc,x0,y0,x1,y1;
int x, y, xl, yl, xh, yh, xc, yc, x0, y0, x1, y1;
double ar = CardPrintBean.ASPECT_RATIO; // x/y
x=source.getWidth();
y=source.getHeight();
xc = x/2;
yc = y/2;
if(y >= x) {
x = source.getWidth();
y = source.getHeight();
xc = x / 2;
yc = y / 2;
if (y >= x) {
xl = x;
yl = (int)(y*((double)x/(double)y));
yl = (int) (y * ((double) x / (double) y));
} else {
xl = (int)(x*((double)y/(double)x));
xl = (int) (x * ((double) y / (double) x));
yl = y;
}
xh = (int)((xl/2)*ar);
yh = yl/2;
x0 = xc-xh;
x1 = xc+xh;
y0 = yc-yh;
y1 = yc+yh;
int cix = (int)(((double)xl)*ar);
xh = (int) ((xl / 2) * ar);
yh = yl / 2;
x0 = xc - xh;
x1 = xc + xh;
y0 = yc - yh;
y1 = yc + yh;
int cix = (int) (((double) xl) * ar);
int ciy = yl;
BufferedImage cropped = new BufferedImage(cix, ciy, source.getType());
Graphics2D g = cropped.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(source, 0, 0, cix, ciy, x0, y0, x1, y1, null);
g.dispose();
return cropped;
}
......@@ -582,8 +584,10 @@ public class UserBean implements UserBeanLocal {
public void removeGameIdById(Integer gameIdId) {
GameID gi = gameIDFacade.find(gameIdId);
// In the future we may edit other peoples' gameids, leave this as a placeholder for now
// At the very least it safeguards the situation if user gets another users gameid in somehow..
// In the future we may edit other peoples' gameids, leave this as a
// placeholder for now
// At the very least it safeguards the situation if user gets another
// users gameid in somehow..
if (!permbean.isCurrentUser(gi.getEventUser())) {
loggerbean.logMessage(SecurityLogType.permissionDenied, permbean.getCurrentUser(), "User tried to remove GameID from another user: " + gi.getEventUser());
throw new EJBAccessException("Not enough rights to remove another users' GameIDs");
......@@ -684,19 +688,22 @@ public class UserBean implements UserBeanLocal {
return userFacade.searchAllUsers(search);
}
// @Override
// public SearchResult<User> getEventUsers(SearchQuery search) {
// if (search.getSearch() == null || search.getSearch().isEmpty())
// {
// throw new RuntimeException("You should be using getThisEventsUsers if not searching globally...");
// // return userFacade.searchEventUsers(search);
// } else {
// return userFacade.searchAllUsers(search);
// }
// @Override
// public SearchResult<User> getEventUsers(SearchQuery search) {
// if (search.getSearch() == null || search.getSearch().isEmpty())
// {
// throw new
// RuntimeException("You should be using getThisEventsUsers if not searching globally...");
// // return userFacade.searchEventUsers(search);
// } else {
// return userFacade.searchAllUsers(search);
// }
//
// }
// }
//
@Override
@RolesAllowed(UserPermission.S_VIEW_ALL)
public SearchResult<EventUser> getThisEventsUsers(UserSearchQuery searchQuery) {
SearchResult<EventUser> returnUsers = eventUserFacade.searchEventUsers(searchQuery);
......@@ -748,6 +755,9 @@ public class UserBean implements UserBeanLocal {
@Override
public UserApproval setUserApproval(EventUser user, String approvalName, boolean approvalValue, String notes) {
if (!permbean.getCurrentUser().equals(user) && permbean.hasPermission(UserPermission.MODIFY))
throw new EJBAccessException("Tried to set approval without permissions: " + approvalName + " to " + approvalValue + " with notes " + notes);
Approval approval = approvalFacade.findOrCreate(approvalName);
UserApproval ret = userApprovalFacade.findOrCreateApproval(user, approval);
ret.setApprovalValue(approvalValue);
......@@ -773,7 +783,12 @@ public class UserBean implements UserBeanLocal {
@Override
public User getUser(Integer id) {
return userFacade.find(id);
}
User ret = userFacade.find(id);
if (!permbean.getCurrentUser().getUser().equals(ret) && permbean.hasPermission(UserPermission.VIEW_ALL)) {
throw new EJBAccessException("Tried to fetch user with id " + id + " from database without sufficient permissions");
}
return ret;
}
}
\ No newline at end of file
package fi.codecrew.moya.facade;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import fi.codecrew.moya.model.ApiApplication;
import fi.codecrew.moya.model.ApiApplication_;
@Stateless
@LocalBean
public class ApiApplicationFacade extends IntegerPkGenericFacade<ApiApplication> {
public ApiApplicationFacade() {
super(ApiApplication.class);
}
public ApiApplication findByAppid(String appId) {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<ApiApplication> q = cb.createQuery(ApiApplication.class);
Root<ApiApplication> root = q.from(ApiApplication.class);
q.where(cb.equal(root.get(ApiApplication_.applicationKey), appId));
return super.getSingleNullableResult(getEm().createQuery(q));
}
}
package fi.codecrew.moya.facade;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import fi.codecrew.moya.model.ApiApplication;
import fi.codecrew.moya.model.ApiApplicationInstance;
import fi.codecrew.moya.model.ApiApplicationInstance_;
@Stateless
@LocalBean
public class ApiApplicationInstanceFacade extends IntegerPkGenericFacade<ApiApplicationInstance> {
public ApiApplicationInstanceFacade() {
super(ApiApplicationInstance.class);
}
public ApiApplicationInstance findInstance(ApiApplication app, String userId) {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<ApiApplicationInstance> q = cb.createQuery(ApiApplicationInstance.class);
Root<ApiApplicationInstance> root = q.from(ApiApplicationInstance.class);
q.where(cb.equal(root.get(ApiApplicationInstance_.application), app),
cb.equal(root.get(ApiApplicationInstance_.authname), userId));
return super.getSingleNullableResult(getEm().createQuery(q));
}
}
......@@ -11,10 +11,10 @@ import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import fi.codecrew.moya.model.Product_;
import fi.codecrew.moya.beans.EventBeanLocal;
import fi.codecrew.moya.model.Product;
import fi.codecrew.moya.model.ProductFlag;
import fi.codecrew.moya.model.Product_;
@Stateless
@LocalBean
......@@ -65,18 +65,19 @@ public class ProductFacade extends IntegerPkGenericFacade<Product> {
return getEm().createQuery(cq).getResultList();
}
public Product findProductByBarcode(String barcode) {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<Product> cq = cb.createQuery(Product.class);
Root<Product> root = cq.from(Product.class);
cq.where(
cq.where(
cb.equal(root.get(Product_.event), eventbean.getCurrentEvent()),
cb.equal(root.get(Product_.barcode), barcode)
);
return super.getSingleNullableResult(getEm().createQuery(cq));
}
}
package fi.codecrew.moya.beans;
import javax.ejb.Local;
@Local
public interface RestBeanLocal {
boolean validateUserNonce(String nonce);
String getLoggedinUserRestNonce();
// String authenticateApp(String pathInfo, String appId, String userid, String applicationStamp, String mac);
}
package fi.codecrew.moya.model;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.eclipse.persistence.annotations.OptimisticLocking;
import org.eclipse.persistence.annotations.OptimisticLockingType;
@Entity
@Table(name = "api_applications")
@OptimisticLocking(type = OptimisticLockingType.CHANGED_COLUMNS)
public class ApiApplication extends GenericEntity {
public static enum AuthType {
USERKEY, ORGAUTH
}
/**
*
*/
private static final long serialVersionUID = -2283975589693287217L;
@JoinColumn(nullable = false, updatable = false)
@ManyToOne
private User developer;
@Lob
@Column(nullable = false, unique = true)
private String applicationKey;
@Column(nullable = false, unique = true)
private String name;
@Lob
private String description;
@Column(nullable = false, updatable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date created;
@Column(nullable = false)
@Enumerated(EnumType.STRING)
private AuthType authtype = AuthType.USERKEY;
@Column(nullable = false)
private boolean enabled = true;
@Enumerated(EnumType.STRING)
private ReaderType readerType;
@OneToMany(mappedBy = "application")
private List<ApiApplicationInstance> instances = new ArrayList<>();
public User getDeveloper() {
return developer;
}
public void setDeveloper(User developer) {
this.developer = developer;
}
public String getApplicationKey() {
return applicationKey;
}
public void setApplicationKey(String applicationKey) {
this.applicationKey = applicationKey;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public AuthType getAuthtype() {
return authtype;
}
public void setAuthtype(AuthType authtype) {
this.authtype = authtype;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public ReaderType getReaderType() {
return readerType;
}
public void setReaderType(ReaderType readerType) {
this.readerType = readerType;
}
public List<ApiApplicationInstance> getInstances() {
return instances;
}
public void setInstances(List<ApiApplicationInstance> instances) {
this.instances = instances;
}
}
package fi.codecrew.moya.model;
import java.util.Date;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.UniqueConstraint;
@Entity
@Table(name = "api_application_instances", uniqueConstraints = @UniqueConstraint(columnNames = {
ApiApplicationInstance.APPLICATION_ID_COLUMN,
ApiApplicationInstance.AUTHNAME_COLUMN
}))
public class ApiApplicationInstance extends GenericEntity {
public static final String UNIQUE_KEY_COLUMN = "secret_key";
public static final String APPLICATION_ID_COLUMN = "application_id";
private static final long serialVersionUID = 8311790714131060263L;
public static final String AUTHNAME_COLUMN = "authname";
@JoinColumn(nullable = false, name = APPLICATION_ID_COLUMN, updatable = false)
@ManyToOne()
private ApiApplication application;
@Column(nullable = false)
private boolean enabled = true;
@Column(nullable = false, updatable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date created;
@Column(nullable = false, updatable = false, name = AUTHNAME_COLUMN)
private String authname;
@Lob
private String name;
@OneToMany()
private List<Reader> readers;
@Lob
private String notes;
@JoinColumn(nullable = true)
@ManyToOne
private EventUser eventuser;
@Lob
@Column(name = UNIQUE_KEY_COLUMN, nullable = false, updatable = false)
private String secretKey;
public ApiApplication getApplication() {
return application;
}
public void setApplication(ApiApplication application) {
this.application = application;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Reader> getReaders() {
return readers;
}
public void setReaders(List<Reader> readers) {
this.readers = readers;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
public EventUser getEventuser() {
return eventuser;
}
public void setEventuser(EventUser eventuser) {
this.eventuser = eventuser;
}
public String getAuthname() {
return authname;
}
public void setAuthname(String authname) {
this.authname = authname;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
}
......@@ -5,7 +5,8 @@ public enum SpecialPermission {
USER,
ANONYMOUS,
// ORGANISATION_ADMIN,
VERKKOMAKSU_CHECKER
VERKKOMAKSU_CHECKER,
REST
;
public static final String S_USER = "USER";
......
package fi.codecrew.moya.utilities;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;
......@@ -19,6 +20,44 @@ public class PasswordFunctions {
private static final boolean UGLY_FIX = true;
private static final Charset LATIN1 = Charset.forName("ISO-8859-15");
public static final String calculateSha1(String source)
{
String ret = null;
try {
final MessageDigest algo = MessageDigest.getInstance("SHA");
final byte[] resultByte = algo.digest(source.getBytes(LATIN1));
ret = new String(Hex.encodeHex(resultByte)).toUpperCase();
} catch (NoSuchAlgorithmException e) {
logger.warn("THIS SHOULD NEVER HAPPEN! (SHA1 hashfunction should always exist)", e);
}
return ret;
}
/**
* Returns the SHA1 sum of the @param fields separated by @param separator e
* eg separator = "+" fields {"ONE", "TWO", "THREE"} return value
* ONE+TWO+THREE
*
* @param separator
* @param fields
* @return
*/
public static final String calculateSha1(String separator, String... fields)
{
String str = mkSeparatedString(separator, fields);
String ret = null;
try {
final MessageDigest algo = MessageDigest.getInstance("SHA");
final byte[] resultByte = algo.digest(str.getBytes(LATIN1));
ret = new String(Hex.encodeHex(resultByte)).toUpperCase();
} catch (NoSuchAlgorithmException e) {
logger.warn("THIS SHOULD NEVER HAPPEN! (SHA1 hashfunction should always exist)", e);
}
return ret;
}
/**
* Returns the MD5 sum of the @param fields separated by @param separator e
* eg separator = "+" fields {"ONE", "TWO", "THREE"} return value
......@@ -28,9 +67,13 @@ public class PasswordFunctions {
* @param fields
* @return
*/
public static String calculateMd5(String separator, String... fields)
public static final String calculateMd5(String separator, String... fields)
{
return calculateMd5(mkSeparatedString(separator, fields));
}
public static final String mkSeparatedString(String separator, String... fields)
{
StringBuilder sb = new StringBuilder();
boolean first = true;
for (String field : fields)
......@@ -42,17 +85,15 @@ public class PasswordFunctions {
}
sb.append(field);
}
logger.info("Calculating md5 from {}", sb.toString());
return calculateMd5(sb.toString());
return sb.toString();
}
public static String calculateMd5(String str)
public static final String calculateMd5(String str)
{
String ret = null;
try {
final MessageDigest algo = MessageDigest.getInstance("MD5");
final byte[] resultByte = algo.digest(str.getBytes());
final byte[] resultByte = algo.digest(str.getBytes(LATIN1));
ret = new String(Hex.encodeHex(resultByte)).toUpperCase();
} catch (NoSuchAlgorithmException e) {
logger.warn("THIS SHOULD NEVER HAPPEN! (md5 hashfunction should always exist)", e);
......
......@@ -14,7 +14,7 @@
</ui:define>
<ui:define name="content">
<ui:fragment rendered="#{!inviteAcceptView.done}">
<users:edit creating="true" commitaction="#{inviteAcceptView.createUser()}" commitvalue="#{i18n['user.create']}" />
<users:create creating="true" commitaction="#{inviteAcceptView.createUser()}" commitvalue="#{i18n['user.create']}" />
</ui:fragment>
</ui:define>
</ui:composition>
......
package fi.codecrew.moya;
import java.io.IOException;
import java.io.PrintWriter;
import javax.ejb.EJB;
import javax.faces.application.ProjectStage;
......@@ -12,13 +13,16 @@ import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fi.codecrew.moya.beans.RestBeanLocal;
import fi.codecrew.moya.beans.SessionMgmtBeanLocal;
import fi.codecrew.moya.clientutils.BortalLocalContextHolder;
import fi.codecrew.moya.model.User;
import fi.codecrew.moya.rest.RestApplicationEntrypoint;
/**
* Servlet Filter implementation class HostnameFilter
......@@ -26,8 +30,22 @@ import fi.codecrew.moya.model.User;
public class HostnameFilter implements Filter {
private static final Logger logger = LoggerFactory.getLogger(HostnameFilter.class);
private boolean developmentMode = false;
private static final String HTTP_HOSTNAME_ID = "moya_hostname_session_id";
private boolean developmentMode = false;
@EJB
private RestBeanLocal restauth;
@Override
public void init(FilterConfig config) throws ServletException {
// check if software is in development -mode
FacesContext fc = FacesContext.getCurrentInstance();
if (ProjectStage.Development.equals(fc.getApplication().getProjectStage())) {
developmentMode = true;
}
}
@EJB
private SessionMgmtBeanLocal sessionmgmt;
......@@ -51,68 +69,33 @@ public class HostnameFilter implements Filter {
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
@SuppressWarnings("unchecked")
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
logger.info("HostnameFilter called!");
HttpServletRequest httpRequest = null;
if (request != null && request instanceof HttpServletRequest) {
httpRequest = ((HttpServletRequest) request);
StringBuffer url = httpRequest.getRequestURL();
// logger.info("Original hostname {}", url);
// Subject subj = Subject.getSubject(AccessController.getContext());
// int beginindex = 8; // Let's skip http://
int beginindex = url.indexOf("//", 0);
if (beginindex < 0)
{
beginindex = 0;
} else {
beginindex = beginindex + 2;
}
// Find the first / from URL after http://
int slashindex = url.indexOf("/", beginindex);
int colonindex = url.indexOf(":", beginindex);
int lastindex = slashindex;
if (colonindex >= 0 && slashindex > colonindex) {
lastindex = colonindex;
}
if (lastindex < 0) {
lastindex = url.length() - 1;
}
String hostname = url.substring(beginindex, lastindex);
// httpRequest.getSession().setAttribute(EventBeanLocal.HTTP_URL_HOSTNAME,
// hostname);
String proto = url.substring(0, 5).toLowerCase();
boolean ssl = proto.equals("https");
BortalLocalContextHolder.setSsl(ssl);
BortalLocalContextHolder.setHostname(hostname);
BortalLocalContextHolder.setInDevelopmentMode(developmentMode);
//
// Object hostname_session_id =
// httpRequest.getSession().getAttribute(HTTP_HOSTNAME_ID);
// if (hostname_session_id != null && hostname_session_id instanceof
// Integer) {
// BortalLocalContextHolder.setHostnameId((Integer)
// hostname_session_id);
// } else {
// BortalLocalContextHolder.setHostnameId(null);
// }
parseHostname(httpRequest);
if (httpRequest.getUserPrincipal() == null) {
try {
httpRequest.login(User.ANONYMOUS_LOGINNAME, null);
} catch (Throwable t) {
logger.warn("Error logging in as anonymous... ignoring.. ", t);
// Check if we are logging in with rest
if (RestApplicationEntrypoint.REST_PATH.equals(httpRequest.getServletPath())) {
if (!restAuth(httpRequest, response)) {
response.getWriter().write("REST authentication failed!");
if (response instanceof HttpServletResponse) {
HttpServletResponse httpResp = (HttpServletResponse) response;
httpResp.setStatus(HttpServletResponse.SC_FORBIDDEN);
}
return;
}
} else {
try {
httpRequest.login(User.ANONYMOUS_LOGINNAME, null);
} catch (Throwable t) {
logger.warn("Error logging in as anonymous... ignoring.. ", t);
}
}
}
else if (!httpRequest.getUserPrincipal().getName().equals(User.ANONYMOUS_LOGINNAME))
......@@ -120,24 +103,6 @@ public class HostnameFilter implements Filter {
sessionmgmt.updateSessionUser(httpRequest.getSession().getId(), httpRequest.getUserPrincipal().getName());
}
// Object trailO =
// httpRequest.getSession().getAttribute(HTTP_TRAIL_NAME);
// ConcurrentLinkedQueue<Object> trail = null;
// if (trailO != null && trailO instanceof ConcurrentLinkedQueue)
// {
// trail = (ConcurrentLinkedQueue<Object>) trailO;
// } else {
// trail = new ConcurrentLinkedQueue<Object>();
// httpRequest.getSession().setAttribute(HTTP_TRAIL_NAME, trail);
// }
// for (int remove = trail.size() - 10; remove > 0; --remove) {
// Object removed = trail.poll();
// logger.debug("Removed {} from http trail", removed);
// }
// if (!httpRequest.getRequestURI().matches(".*(resource).*")) {
// trail.add(httpRequest.getRequestURI());
// }
}
// pass the request along the filter chain
try {
......@@ -147,19 +112,6 @@ public class HostnameFilter implements Filter {
}
}
/**
* @see Filter#init(FilterConfig)
*/
@Override
public void init(FilterConfig fConfig) throws ServletException {
// check if software is in development -mode
FacesContext fc = FacesContext.getCurrentInstance();
if (ProjectStage.Development.equals(fc.getApplication().getProjectStage())) {
developmentMode = true;
}
}
// public static String getCurrentHostname(HttpSession sess) {
// String ret = null;
// if (sess != null) {
......@@ -171,4 +123,89 @@ public class HostnameFilter implements Filter {
// return ret;
// }
private boolean restAuth(HttpServletRequest httpRequest, ServletResponse response) {
StringBuilder hashBuilder = new StringBuilder();
hashBuilder.append("rest:");
hashBuilder.append(httpRequest.getPathInfo()).append(":");
hashBuilder.append(httpRequest.getParameter("appkey")).append(":");
hashBuilder.append(httpRequest.getParameter("appuser")).append(":");
hashBuilder.append(httpRequest.getParameter("appstamp")).append(":");
hashBuilder.append(httpRequest.getParameter("appmac"));
boolean ret = true;
try {
httpRequest.login(null, hashBuilder.toString());
} catch (ServletException loginEx) {
ret = false;
logger.info("Rest api authentication failed! ", loginEx);
if (response instanceof HttpServletResponse)
{
HttpServletResponse httpResp = ((HttpServletResponse) response);
httpResp.setStatus(HttpServletResponse.SC_FORBIDDEN);
try {
PrintWriter w = httpResp.getWriter();
w.write("Rest auth failed! ");
w.flush();
} catch (IOException e) {
logger.info("Error writing error message from restauth failure to ostream", e);
}
}
} finally {
}
return ret;
}
protected void parseHostname(HttpServletRequest httpRequest)
{
logger.info("Path info {}", httpRequest.getPathInfo());
logger.info("querystring {}", httpRequest.getQueryString());
logger.info("ctxpath {}", httpRequest.getContextPath());
logger.info("pathTranslated {}", httpRequest.getPathTranslated());
logger.info("requestUri {}", httpRequest.getRequestURI());
logger.info("URL {}", httpRequest.getRequestURL().toString());
logger.info("servletpath {}", httpRequest.getServletPath());
logger.info("servletCtx {}", httpRequest.getServletContext());
StringBuffer url = httpRequest.getRequestURL();
// logger.info("Original hostname {}", url);
// Subject subj = Subject.getSubject(AccessController.getContext());
// int beginindex = 8; // Let's skip http://
int beginindex = url.indexOf("//", 0);
if (beginindex < 0)
{
beginindex = 0;
} else {
beginindex = beginindex + 2;
}
// Find the first / from URL after http://
int slashindex = url.indexOf("/", beginindex);
int colonindex = url.indexOf(":", beginindex);
int lastindex = slashindex;
if (colonindex >= 0 && slashindex > colonindex) {
lastindex = colonindex;
}
if (lastindex < 0) {
lastindex = url.length() - 1;
}
String hostname = url.substring(beginindex, lastindex);
// httpRequest.getSession().setAttribute(EventBeanLocal.HTTP_URL_HOSTNAME,
// hostname);
String proto = url.substring(0, 5).toLowerCase();
boolean ssl = proto.equals("https");
BortalLocalContextHolder.setSsl(ssl);
BortalLocalContextHolder.setHostname(hostname);
BortalLocalContextHolder.setInDevelopmentMode(developmentMode);
}
}
package fi.codecrew.moya.rest;
import javax.enterprise.context.RequestScoped;
import javax.ws.rs.Consumes;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
@RequestScoped
@Path("/app")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON + "; charset=UTF-8" })
public class ApplicationRestView {
@Path("/hello")
public Response hello() {
return Response.ok().status(Status.FORBIDDEN).build();
}
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!