Commit 57ab0e15 by Tuomas Riihimäki

Merge branch 'networkassociation' into 'master'

Networkassociation

oh god

Reviewed-by: @tuomari
2 parents 9025e382 cd83eda8
......@@ -149,6 +149,8 @@ public class BootstrapBean implements BootstrapBeanLocal {
"user_images",
"user_notes",
"users"));
dbUpdates.add(new String[]{"CREATE TABLE network_associations (id SERIAL NOT NULL, create_time TIMESTAMPTZ NOT NULL, ip TEXT, mac TEXT, META TEXT, modify_time TIMESTAMPTZ NOT NULL, status TEXT NOT NULL, event INTEGER, event_user INTEGER, place INTEGER, PRIMARY KEY (id))"});
}
@EJB
......
......@@ -17,6 +17,7 @@ import fi.codecrew.moya.enums.apps.ContentPermission;
import fi.codecrew.moya.enums.apps.EventPermission;
import fi.codecrew.moya.enums.apps.LicensePermission;
import fi.codecrew.moya.enums.apps.MapPermission;
import fi.codecrew.moya.enums.apps.NetworkAssociationPermission;
import fi.codecrew.moya.enums.apps.PollPermission;
import fi.codecrew.moya.enums.apps.ShopPermission;
import fi.codecrew.moya.enums.apps.SpecialPermission;
......@@ -195,6 +196,10 @@ public class MenuBean implements MenuBeanLocal {
adminEventCards.addPage(menuitemfacade.findOrCreate("/shop/shopToUser"), null).setVisible(false);
adminEventCards.addPage(menuitemfacade.findOrCreate("/shop/assocToUser"), null).setVisible(false);
MenuNavigation adminAssociation = adminmenu.addPage(null, null);
adminAssociation.setKey("topnavi.adminassoc");
adminAssociation.addPage(menuitemfacade.findOrCreate("/networkassociation/index"), NetworkAssociationPermission.CAN_ADMINISTER_ASSOCIATIONS);
// shop
MenuNavigation adminshop = adminmenu.addPage(null, null);
adminshop.setKey("topnavi.adminshop");
......
package fi.codecrew.moya.beans;
import java.util.Calendar;
import java.util.HashSet;
import java.util.List;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import fi.codecrew.moya.enums.BortalApplication;
import fi.codecrew.moya.enums.NetworkAssociationStatus;
import fi.codecrew.moya.enums.apps.IAppPermission;
import fi.codecrew.moya.enums.apps.NetworkAssociationPermission;
import fi.codecrew.moya.facade.NetworkAssociationFacade;
import fi.codecrew.moya.model.ApplicationPermission;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.GroupMembership;
import fi.codecrew.moya.model.NetworkAssociation;
import fi.codecrew.moya.model.Place;
import fi.codecrew.moya.model.Role;
/**
* Session Bean implementation class NetworkAssociationBean
*/
@Stateless
@LocalBean
public class NetworkAssociationBean implements NetworkAssociationBeanLocal {
@EJB
private UserBean userBean;
@EJB
private BarcodeBean barcodeBean;
@EJB
private RoleBean roleBean;
@EJB
private NetworkAssociationFacade networkAssociationFacade;
@EJB
private EventBean eventBean;
@EJB
private PermissionBean permissionBean;
public NetworkAssociationBean() {}
@Override
@RolesAllowed(NetworkAssociationPermission.S_CAN_ADMINISTER_ASSOCIATIONS)
public List<NetworkAssociation> getStatusByIPAndMAC(String ip, String mac) {
return networkAssociationFacade.findByIPAndMAC(eventBean.getCurrentEvent(), ip, mac);
}
@Override
@RolesAllowed(NetworkAssociationPermission.S_CAN_ADMINISTER_ASSOCIATIONS)
public List<NetworkAssociation> getActiveAssociations(boolean activatePending) {
if(activatePending)
activatePendingAssociations();
return networkAssociationFacade.findByStatus(eventBean.getCurrentEvent(), NetworkAssociationStatus.ACTIVE);
}
@Override
@RolesAllowed(NetworkAssociationPermission.S_CAN_ADMINISTER_ASSOCIATIONS)
public NetworkAssociation tryAssociate(String ip, String mac) {
EventUser eu = permissionBean.getCurrentUser();
HashSet<IAppPermission> userPerms = buildPermsFor(eu);
NetworkAssociation nasc = associate(eu, userPerms, null, ip, mac);
return nasc;
}
@Override
@RolesAllowed(NetworkAssociationPermission.S_CAN_ADMINISTER_ASSOCIATIONS)
public NetworkAssociation tryAssociate(String username, String password,
String ip, String mac, String code, boolean codeRequired)
throws Exception {
EventUser authUser = userBean.validateUser(username, password);
if(authUser == null)
throw new Exception("INVALID_USER_OR_PASSWORD");
NetworkAssociation association;
HashSet<IAppPermission> userPerms = buildPermsFor(authUser);
if(!userPerms.contains(NetworkAssociationPermission.CAN_ASSOCIATE))
throw new Exception("USER_HAS_NO_ASSOCIATE_PERMISSION");
if(codeRequired) {
Place place = resolvePlaceFromCode(code);
if(place == null) {
// This is a valid case when user has permissions that allow them to
// override any place requirements, effectively allowing for free
// associations without the need of a real place.
if(!userPerms.contains(NetworkAssociationPermission.OVERRIDE_PLACE_REQUIREMENT))
throw new Exception("INVALID_PLACECODE");
association = associate(authUser, userPerms, place, ip, mac);
} else {
if(place.getPlaceReserver().getUser().equals(authUser)) {
// This is the simple case when user goes to their own place
association = associate(authUser, userPerms, place, ip, mac);
} else {
// In this case, the user has probably shuffled their seats
// within their group
if(!userPerms.contains(NetworkAssociationPermission.CAN_SHUFFLE_IN_GROUP))
throw new Exception("INVALID_PLACECODE");
boolean userIsInGroup = false;
for(GroupMembership gm : place.getGroup().getMembers()) {
EventUser member = gm.getUser();
if(member != null && gm.getUser().equals(authUser)) {
userIsInGroup = true;
break;
}
}
if(!userIsInGroup)
throw new Exception("INVALID_PLACECODE");
association = associate(authUser, userPerms, place, ip, mac);
}
}
} else {
// Code was not required, this is often a case for WLAN
association = associate(authUser, userPerms, null, ip, mac);
}
return association;
}
@Override
@RolesAllowed(NetworkAssociationPermission.S_CAN_ADMINISTER_ASSOCIATIONS)
public List<NetworkAssociation> getPendingAssociations() {
return networkAssociationFacade.findByStatus(eventBean.getCurrentEvent(), NetworkAssociationStatus.PENDING);
}
@Override
@RolesAllowed(NetworkAssociationPermission.S_CAN_ADMINISTER_ASSOCIATIONS)
public void dropAssociationById(Integer associd) {
NetworkAssociation na = networkAssociationFacade.find(associd);
if(na.getEvent().equals(eventBean.getCurrentEvent())) {
na.setModifyTime(Calendar.getInstance());
na.setStatus(NetworkAssociationStatus.EXPIRED);
}
}
private HashSet<IAppPermission> buildPermsFor(EventUser authUser) {
HashSet<IAppPermission> userPerms = new HashSet<>();
if (authUser.getUser().isSuperadmin()) {
// Iterate through all permissions & add
for (BortalApplication app : BortalApplication.values()) {
for (IAppPermission perm : app.getPermissions()) {
userPerms.add(perm);
}
}
} else {
for(Role r : userBean.localFindUsersRoles(authUser)) {
for(ApplicationPermission appPerm : r.getPermissions()) {
IAppPermission iap = appPerm.getPermission();
if(!userPerms.contains(iap)) {
userPerms.add(iap);
}
}
}
}
return userPerms;
}
private void activatePendingAssociations() {
List<NetworkAssociation> netAssocs = networkAssociationFacade.findByStatus(
eventBean.getCurrentEvent(), NetworkAssociationStatus.PENDING);
for(NetworkAssociation na : netAssocs) {
na.setStatus(NetworkAssociationStatus.ACTIVE);
na.setModifyTime(Calendar.getInstance());
}
}
private NetworkAssociation associate(EventUser authUser, HashSet<IAppPermission> userPerms,
Place place, String ip, String mac) {
// This tests the case where association request is still pending, we will not
// create new one but rather return an old one
List<NetworkAssociation> nas = networkAssociationFacade.findByIPAndMACAndStatus(
eventBean.getCurrentEvent(), ip, mac, NetworkAssociationStatus.PENDING);
if(nas.size() > 0)
return nas.get(0);
nas = networkAssociationFacade.findByIPAndMACAndStatus(
eventBean.getCurrentEvent(), ip, mac, NetworkAssociationStatus.ACTIVE);
if(nas.size() > 0)
return nas.get(0);
NetworkAssociation na = new NetworkAssociation();
na.setIP(ip);
na.setMAC(mac);
na.setPlace(place);
na.setEventUser(authUser);
na.setEvent(authUser.getEvent());
na.setStatus(NetworkAssociationStatus.PENDING);
List<NetworkAssociation> activeAssocs;
if(place == null) {
// When in this branch, we are doing an association which will never
// dis-associate things EXCEPT in the case where IP collision happens
// which usually is a result of network ops change...
activeAssocs = networkAssociationFacade.findActiveAssociationsByIP(
eventBean.getCurrentEvent(), ip);
for(NetworkAssociation activeAssoc : activeAssocs) {
activeAssoc.setModifyTime(Calendar.getInstance());
activeAssoc.setStatus(NetworkAssociationStatus.EXPIRED);
}
} else {
// Disassociate any colliding IPs
activeAssocs = networkAssociationFacade.findActiveAssociationsByIP(
eventBean.getCurrentEvent(), ip);
for(NetworkAssociation activeAssoc : activeAssocs) {
activeAssoc.setModifyTime(Calendar.getInstance());
activeAssoc.setStatus(NetworkAssociationStatus.EXPIRED);
}
// In here we disassociate old associations from this place unless the user has many
// associations per place
if(!userPerms.contains(NetworkAssociationPermission.CAN_ASSOCIATE_MANY_PER_PLACE)) {
activeAssocs = networkAssociationFacade.findActiveAssociationsByPlace(place);
for(NetworkAssociation activeAssoc : activeAssocs) {
activeAssoc.setModifyTime(Calendar.getInstance());
activeAssoc.setStatus(NetworkAssociationStatus.EXPIRED);
}
}
}
// Finally persist the association and return
na = networkAssociationFacade.create(na);
return na;
}
private Place resolvePlaceFromCode(String code) {
if(code == null) return null;
return barcodeBean.getPlaceFromTextCode(code);
}
}
package fi.codecrew.moya.facade;
import java.util.List;
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.enums.NetworkAssociationStatus;
import fi.codecrew.moya.model.LanEvent;
import fi.codecrew.moya.model.NetworkAssociation;
import fi.codecrew.moya.model.NetworkAssociation_;
import fi.codecrew.moya.model.Place;
@Stateless
@LocalBean
public class NetworkAssociationFacade extends IntegerPkGenericFacade<NetworkAssociation> {
public NetworkAssociationFacade() { super(NetworkAssociation.class); }
public List<NetworkAssociation> findByIPAndMACAndStatus(LanEvent event, String ip, String mac, NetworkAssociationStatus nas) {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<NetworkAssociation> cq = cb.createQuery(NetworkAssociation.class);
Root<NetworkAssociation> root = cq.from(NetworkAssociation.class);
cq.where(
cb.and(
cb.equal(root.get(NetworkAssociation_.event), event),
cb.equal(root.get(NetworkAssociation_.ip), ip),
cb.equal(root.get(NetworkAssociation_.mac), mac),
cb.equal(root.get(NetworkAssociation_.status), nas)
)
);
return getEm().createQuery(cq).getResultList();
}
public List<NetworkAssociation> findActiveAssociationsByIP(LanEvent event, String ip) {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<NetworkAssociation> cq = cb.createQuery(NetworkAssociation.class);
Root<NetworkAssociation> root = cq.from(NetworkAssociation.class);
cq.where(
cb.and(
cb.equal(root.get(NetworkAssociation_.event), event),
cb.or(
cb.equal(root.get(NetworkAssociation_.status), NetworkAssociationStatus.PENDING),
cb.equal(root.get(NetworkAssociation_.status), NetworkAssociationStatus.ACTIVE)
),
cb.equal(root.get(NetworkAssociation_.ip), ip)
)
);
return getEm().createQuery(cq).getResultList();
}
public List<NetworkAssociation> findActiveAssociationsByPlace(Place place) {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<NetworkAssociation> cq = cb.createQuery(NetworkAssociation.class);
Root<NetworkAssociation> root = cq.from(NetworkAssociation.class);
cq.where(
cb.and(
cb.or(
cb.equal(root.get(NetworkAssociation_.status), NetworkAssociationStatus.PENDING),
cb.equal(root.get(NetworkAssociation_.status), NetworkAssociationStatus.ACTIVE)
),
cb.equal(root.get(NetworkAssociation_.place), place)
)
);
return getEm().createQuery(cq).getResultList();
}
public List<NetworkAssociation> findByIPAndMAC(LanEvent event, String ip, String mac) {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<NetworkAssociation> cq = cb.createQuery(NetworkAssociation.class);
Root<NetworkAssociation> root = cq.from(NetworkAssociation.class);
cq.where(
cb.and(
cb.equal(root.get(NetworkAssociation_.event), event),
cb.equal(root.get(NetworkAssociation_.ip), ip),
cb.equal(root.get(NetworkAssociation_.mac), mac)
)
);
return getEm().createQuery(cq).getResultList();
}
public List<NetworkAssociation> findByStatus(LanEvent event, NetworkAssociationStatus status) {
CriteriaBuilder cb = getEm().getCriteriaBuilder();
CriteriaQuery<NetworkAssociation> cq = cb.createQuery(NetworkAssociation.class);
Root<NetworkAssociation> root = cq.from(NetworkAssociation.class);
cq.where(
cb.and(
cb.equal(root.get(NetworkAssociation_.event), event),
cb.equal(root.get(NetworkAssociation_.status), status)
)
);
return getEm().createQuery(cq).getResultList();
}
}
package fi.codecrew.moya.beans;
import java.util.List;
import javax.ejb.Local;
import fi.codecrew.moya.model.NetworkAssociation;
@Local
public interface NetworkAssociationBeanLocal {
NetworkAssociation tryAssociate(String username, String password,
String ip, String mac, String code, boolean codeRequired)
throws Exception;
List<NetworkAssociation> getStatusByIPAndMAC(String ip, String mac);
List<NetworkAssociation> getActiveAssociations(boolean activatePending);
NetworkAssociation tryAssociate(String ip, String mac);
List<NetworkAssociation> getPendingAssociations();
void dropAssociationById(Integer associd);
}
package fi.codecrew.moya.model;
import java.util.Calendar;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.JoinColumn;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.eclipse.persistence.annotations.OptimisticLocking;
import org.eclipse.persistence.annotations.OptimisticLockingType;
import fi.codecrew.moya.enums.NetworkAssociationStatus;
@Entity
@Table(name = "network_associations")
@OptimisticLocking(type = OptimisticLockingType.CHANGED_COLUMNS)
public class NetworkAssociation extends GenericEntity {
private static final long serialVersionUID = -7621152614442737756L;
@JoinColumn(name="event")
private LanEvent event;
@JoinColumn(name="event_user")
private EventUser eventUser;
@Column(name="ip")
private String ip;
@Column(name="mac")
private String mac;
@JoinColumn(name="place")
private Place place;
@Column(name = "create_time", nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Calendar createTime = Calendar.getInstance();
@Column(name = "modify_time", nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Calendar modifyTime = Calendar.getInstance();
@Column(name="status", nullable = false)
@Enumerated(EnumType.STRING)
private NetworkAssociationStatus status;
public LanEvent getEvent() {
return event;
}
public void setEvent(LanEvent event) {
this.event = event;
}
public EventUser getEventUser() {
return eventUser;
}
public void setEventUser(EventUser eventUser) {
this.eventUser = eventUser;
}
public String getIP() {
return ip;
}
public String getIp() {
return ip;
}
public void setIP(String ip) {
this.ip = ip;
}
public String getMAC() {
return mac;
}
public String getMac() {
return mac;
}
public void setMAC(String mac) {
this.mac = mac;
}
public Place getPlace() {
return place;
}
public void setPlace(Place place) {
this.place = place;
}
public Calendar getCreateTime() {
return createTime;
}
public void setCreateTime(Calendar createTime) {
this.createTime = createTime;
}
public Calendar getModifyTime() {
return modifyTime;
}
public void setModifyTime(Calendar modifyTime) {
this.modifyTime = modifyTime;
}
public NetworkAssociationStatus getStatus() {
return status;
}
public void setStatus(NetworkAssociationStatus status) {
this.status = status;
}
}
......@@ -7,6 +7,7 @@ import fi.codecrew.moya.enums.apps.EventPermission;
import fi.codecrew.moya.enums.apps.LicensePermission;
import fi.codecrew.moya.enums.apps.IAppPermission;
import fi.codecrew.moya.enums.apps.MapPermission;
import fi.codecrew.moya.enums.apps.NetworkAssociationPermission;
import fi.codecrew.moya.enums.apps.PollPermission;
import fi.codecrew.moya.enums.apps.SalespointPermission;
import fi.codecrew.moya.enums.apps.ShopPermission;
......@@ -26,8 +27,8 @@ public enum BortalApplication {
COMPO(CompoPermission.class),
EVENT(EventPermission.class),
LICENSE(LicensePermission.class),
TOURNAMENT(TournamentPermission.class)
TOURNAMENT(TournamentPermission.class),
NETWORKASSOCIATION(NetworkAssociationPermission.class)
;
private final String key;
......
package fi.codecrew.moya.enums;
public enum NetworkAssociationStatus {
PENDING,
ACTIVE,
EXPIRED
}
package fi.codecrew.moya.enums.apps;
import fi.codecrew.moya.enums.BortalApplication;
public enum NetworkAssociationPermission implements IAppPermission {
OVERRIDE_PLACE_REQUIREMENT,
CAN_SHUFFLE_IN_GROUP,
CAN_ASSOCIATE,
CAN_ASSOCIATE_MANY_PER_PLACE,
CAN_ADMINISTER_ASSOCIATIONS,
;
public static final String S_OVERRIDE_PLACE_REQUIREMENT = "NETWORKASSOCIATION/OVERRIDE_PLACE_REQUIREMENT";
public static final String S_CAN_SHUFFLE_IN_GROUP = "NETWORKASSOCIATION/CAN_SHUFFLE_IN_GROUP";
public static final String S_CAN_ASSOCIATE = "NETWORKASSOCIATION/CAN_ASSOCIATE";
public static final String S_CAN_ASSOCIATE_MANY_PER_PLACE = "NETWORKASSOCIATION/CAN_ASSOCIATE_MANY_PER_PLACE";
public static final String S_CAN_ADMINISTER_ASSOCIATIONS = "NETWORKASSOCIATION/CAN_ADMINISTER_ASSOCIATIONS";
private final String fullName;
private final String key;
private static final String I18N_HEADER = "bortalApplication.networkauthentication.";
private NetworkAssociationPermission() {
key = I18N_HEADER + name();
fullName = new StringBuilder().append(getParent().toString()).append(DELIMITER).append(toString()).toString();
}
@Override
public BortalApplication getParent() {
return BortalApplication.NETWORKASSOCIATION;
}
@Override
public String getFullName() {
return fullName;
}
@Override
public String getI18nKey() {
return key;
}
}
<!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:products="http://java.sun.com/jsf/composite/cditools/products"
xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.org/ui"
>
<h:body>
<ui:composition template="#{sessionHandler.template}">
<f:metadata>
<f:event type="preRenderView" listener="#{networkAssociationView.initView}" />
</f:metadata>
<ui:define name="content">
<h:form>
<p:messages autoUpdate="true" redisplay="false"></p:messages>
<h1>#{i18n['networkassociation.current_associations']}</h1>
<p:dataTable var="activeAssoc" value="#{networkAssociationView.activeAssociations}">
<p:column headerText="#{i18n['networkassociation.create_time']}">
<h:outputText value="#{activeAssoc.createTime.time}">
<f:convertDateTime pattern="#{sessionHandler.datetimeFormat}" timeZone="#{sessionHandler.timezone}" />
</h:outputText>
</p:column>
<p:column headerText="#{i18n['networkassociation.modify_time']}">
<h:outputText value="#{activeAssoc.modifyTime.time}">
<f:convertDateTime pattern="#{sessionHandler.datetimeFormat}" timeZone="#{sessionHandler.timezone}" />
</h:outputText>
</p:column>
<p:column headerText="#{i18n['networkassociation.user']}">
<h:link outcome="/useradmin/edit" value="#{activeAssoc.eventUser.user.nick}">
<f:param name="userid" value="#{activeAssoc.eventUser.user.id}" />
</h:link>
</p:column>
<p:column headerText="#{i18n['networkassociation.ip_address']}">
<h:outputText value="#{activeAssoc.ip}" />
</p:column>
<p:column headerText="#{i18n['networkassociation.mac_address']}">
<h:outputText value="#{activeAssoc.mac}" />
</p:column>
<p:column headerText="#{i18n['networkassociation.place']}">
<h:outputText value="#{activeAssoc.place.name}" />
</p:column>
<p:column headerText="#{i18n['networkassociation.action']}">
<p:commandButton value="#{i18n['networkassociation.drop_association']}" action="#{networkAssociationView.dropAssociation(activeAssoc.id)}" update="@form" immediate="true"/>
</p:column>
</p:dataTable>
<h1>#{i18n['networkassociation.pending_associations']}</h1>
<p:dataTable var="activeAssoc" value="#{networkAssociationView.pendingAssociations}">
<p:column headerText="#{i18n['networkassociation.create_time']}">
<h:outputText value="#{activeAssoc.createTime.time}">
<f:convertDateTime pattern="#{sessionHandler.datetimeFormat}" timeZone="#{sessionHandler.timezone}" />
</h:outputText>
</p:column>
<p:column headerText="#{i18n['networkassociation.modify_time']}">
<h:outputText value="#{activeAssoc.modifyTime.time}">
<f:convertDateTime pattern="#{sessionHandler.datetimeFormat}" timeZone="#{sessionHandler.timezone}" />
</h:outputText>
</p:column>
<p:column headerText="#{i18n['networkassociation.user']}">
<h:link outcome="/useradmin/edit" value="#{activeAssoc.eventUser.user.nick}">
<f:param name="userid" value="#{activeAssoc.eventUser.user.id}" />
</h:link>
</p:column>
<p:column headerText="#{i18n['networkassociation.ip_address']}">
<h:outputText value="#{activeAssoc.ip}" />
</p:column>
<p:column headerText="#{i18n['networkassociation.mac_address']}">
<h:outputText value="#{activeAssoc.mac}" />
</p:column>
<p:column headerText="#{i18n['networkassociation.place']}">
<h:outputText value="#{activeAssoc.place.name}" />
</p:column>
<p:column headerText="#{i18n['networkassociation.action']}">
<p:commandButton value="#{i18n['networkassociation.drop_association']}" action="#{networkAssociationView.dropAssociation(activeAssoc.id)}" update="@form" immediate="true"/>
</p:column>
</p:dataTable>
<br />
<h:panelGrid columns="3">
<h:outputText value="#{i18n['networkassociation.ip_address']}" />
<h:outputText value="#{i18n['networkassociation.mac_address']}" />
<h:outputText value="" />
<p:inputText style="width: 90%;" validator="#{networkAssociationView.validateIP}" value="#{networkAssociationView.ipAddress}"/>
<p:inputText style="width: 90%;" validator="#{networkAssociationView.validateMAC}" value="#{networkAssociationView.macAddress}"/>
<p:commandButton value="#{i18n['networkassociation.create_association']}" action="#{networkAssociationView.createAssociation}" update="@form"/>
</h:panelGrid>
</h:form>
</ui:define>
</ui:composition>
</h:body>
</html>
\ No newline at end of file
......@@ -232,17 +232,17 @@ resetMail.username = Username
resetmailSent.body = Email has been sent containing a link where you can change the password.
resetmailSent.header = Email sent
submenu.NotImplementedYet = Not implemented
submenu.admin.adduser = K\u00E4ytt\u00E4j\u00E4nlis\u00E4ys
submenu.admin.adduser.index = K\u00E4ytt\u00E4j\u00E4nlis\u00E4ys
submenu.frontpage = Frontpage
submenu.info.incoming = Incomingview
submenu.info.index = Infon\u00E4kym\u00E4
submenu.NotImplementedYet = Not implemented
submenu.admin.adduser = K\u00E4ytt\u00E4j\u00E4nlis\u00E4ys
submenu.admin.adduser.index = K\u00E4ytt\u00E4j\u00E4nlis\u00E4ys
submenu.frontpage = Frontpage
submenu.info.incoming = Incomingview
submenu.info.index = Infon\u00E4kym\u00E4
subnavi.cards = \u0009\u0009
subnavi.info = Info
topnavi.license = Lisenssikoodit
topnavi.license = Lisenssikoodit
user.cropImage = Crop
user.imageUpload.imageNotFound = Select image to upload
......
......@@ -545,6 +545,18 @@ menuitem.navigation.key = Product flag
nasty.user = Go away!
networkassociation.action = Action
networkassociation.create_association = Create association
networkassociation.create_time = Created on
networkassociation.current_associations = Current Associations
networkassociation.drop_association = Drop
networkassociation.ip_address = IP Address
networkassociation.mac_address = MAC Address
networkassociation.modify_time = Modified on
networkassociation.pending_associations = Pending Associations
networkassociation.place = Place
networkassociation.user = User
news.abstract = Abstract
news.edit = Edit
news.expire = Expire
......@@ -952,6 +964,7 @@ submenu.license.manageCodes = Manage codes
submenu.license.viewCodes = View codes
submenu.map.create = Create map
submenu.map.list = List maps
submenu.networkassociation.index = Associations
submenu.orgrole.create = Create organisationrole
submenu.orgrole.list = Organisation roles
submenu.pages.create = Create content
......@@ -1029,6 +1042,7 @@ topmenu.admin = Admin View
topmenu.helpdesk = Helpdesk
topmenu.user = User View
topnavi.adminassoc = Net Associations
topnavi.adminshop = Adminshop
topnavi.billing = Billing
topnavi.competitions = Competitions
......
......@@ -555,6 +555,18 @@ menu.user.edit = Omat tiedot
nasty.user = Mene pois!
networkassociation.action = Toiminto
networkassociation.create_association = Luo assosiaatio
networkassociation.create_time = Luontiaika
networkassociation.current_associations = Aktiiviset assosiaatiot
networkassociation.drop_association = Poista
networkassociation.ip_address = IP-osoite
networkassociation.mac_address = MAC-osoite
networkassociation.modify_time = Muutosaika
networkassociation.pending_associations = Odottavat assosiaatiot
networkassociation.place = Paikka
networkassociation.user = K\u00E4ytt\u00E4j\u00E4
news.abstract = Lyhennelm\u00E4
news.edit = Muokkaa
news.expire = Lopeta julkaisu
......@@ -933,6 +945,7 @@ submenu.license.manageCodes = Hallinnoi lisenssej\u00E4
submenu.license.viewCodes = N\u00E4yt\u00E4 koodit
submenu.map.create = Uusi kartta
submenu.map.list = N\u00E4yt\u00E4 kartat
submenu.networkassociation.index = Assosiaatiot
submenu.orgrole.create = Luo j\u00E4rjest\u00E4j\u00E4rooli
submenu.orgrole.list = J\u00E4rjest\u00E4j\u00E4roolit
submenu.pages.create = Luo sis\u00E4lt\u00F6\u00E4
......@@ -1013,6 +1026,7 @@ topmenu.admin = Yll\u00E4piton\u00E4kym\u00E4
topmenu.helpdesk = Helpdesk
topmenu.user = K\u00E4ytt\u00E4j\u00E4n\u00E4kym\u00E4
topnavi.adminassoc = Verkkoassosioinnit
topnavi.adminshop = Kauppa
topnavi.billing = Laskutus
topnavi.competitions = Kilpailut
......
package fi.codecrew.moya.rest;
import java.util.List;
import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import fi.codecrew.moya.beans.NetworkAssociationBeanLocal;
import fi.codecrew.moya.enums.NetworkAssociationStatus;
import fi.codecrew.moya.model.NetworkAssociation;
import fi.codecrew.moya.rest.pojo.NetworkAssociationActionPojo;
import fi.codecrew.moya.rest.pojo.NetworkAssociationResponseRoot;
@RequestScoped
@Path("/networkassociation")
public class NetworkAssociationRestView {
@EJB
private NetworkAssociationBeanLocal networkAssociationBean;
@POST
@Path("/auth")
@Produces({ MediaType.APPLICATION_JSON })
public NetworkAssociationResponseRoot auth(
@FormParam("username") String username,
@FormParam("password") String password,
@FormParam("ip") String ip,
@FormParam("mac") String mac,
@FormParam("code") String code,
@FormParam("coderequired") Boolean codeRequired
) {
NetworkAssociationResponseRoot resp = new NetworkAssociationResponseRoot();
try {
NetworkAssociation na = networkAssociationBean.tryAssociate(
username, password, ip, mac, code, codeRequired);
if(na.getStatus().equals(NetworkAssociationStatus.ACTIVE))
resp.getAdditions().add(new NetworkAssociationActionPojo(na.getIP(), na.getMAC()));
else
resp.getPendings().add(new NetworkAssociationActionPojo(na.getIP(), na.getMAC()));
} catch(Exception e) {
resp.getResult().setResultCode(0);
if(e.getMessage() != null && e.getMessage() != "") {
resp.getResult().setMessage(e.getMessage());
} else {
resp.getResult().setMessage("UNKNOWN_ERROR");
}
}
return resp;
}
@GET
@Path("/get_all/{activate}")
@Produces({ MediaType.APPLICATION_JSON })
public NetworkAssociationResponseRoot getAll(
@PathParam("activate") Boolean activate
) {
NetworkAssociationResponseRoot resp = new NetworkAssociationResponseRoot();
try {
if(activate == null)
throw new Exception("INVALID_PARAMETER_FOR_ACTIVATE");
List<NetworkAssociation> activeAssociations = networkAssociationBean.getActiveAssociations(activate);
for(NetworkAssociation na : activeAssociations) {
resp.getAdditions().add(new NetworkAssociationActionPojo(na.getIP(), na.getMAC()));
}
return resp;
} catch(Exception e) {
resp.getResult().setResultCode(0);
resp.getResult().setMessage(e.getMessage());
return resp;
}
}
@POST
@Path("/get_status_by_ip_mac")
@Produces({ MediaType.APPLICATION_JSON })
public NetworkAssociationResponseRoot getChanges(
@FormParam("ip") String ip,
@FormParam("mac") String mac
) {
NetworkAssociationResponseRoot resp = new NetworkAssociationResponseRoot();
try {
for(NetworkAssociation na : networkAssociationBean.getStatusByIPAndMAC(ip, mac)) {
if(na.getStatus().equals(NetworkAssociationStatus.ACTIVE)) {
resp.getAdditions().add(new NetworkAssociationActionPojo(na.getIP(), na.getMAC()));
} else if(na.getStatus().equals(NetworkAssociationStatus.PENDING)) {
resp.getPendings().add(new NetworkAssociationActionPojo(na.getIP(), na.getMAC()));
} else if(na.getStatus().equals(NetworkAssociationStatus.EXPIRED)) {
resp.getRemovals().add(new NetworkAssociationActionPojo(na.getIP(), na.getMAC()));
}
}
return resp;
} catch(Exception e) {
resp.getResult().setResultCode(0);
resp.getResult().setMessage(e.getMessage());
return resp;
}
}
}
package fi.codecrew.moya.rest.pojo;
import javax.xml.bind.annotation.XmlElement;
public class NetworkAssociationActionPojo {
private String ip;
private String mac;
public NetworkAssociationActionPojo() {
this.ip = "";
this.mac = "";
}
public NetworkAssociationActionPojo(String ip, String mac) {
this.ip = ip;
this.mac = mac;
}
@XmlElement(name = "ip")
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
@XmlElement(name = "mac")
public String getMac() {
return mac;
}
public void setMac(String mac) {
this.mac = mac;
}
}
\ No newline at end of file
package fi.codecrew.moya.rest.pojo;
import java.util.ArrayList;
import java.util.List;
public class NetworkAssociationResponseRoot {
private RESTCallResultPojo result;
private List<NetworkAssociationActionPojo> additions;
private List<NetworkAssociationActionPojo> removals;
private List<NetworkAssociationActionPojo> pendings;
public NetworkAssociationResponseRoot() {
this.result = new RESTCallResultPojo();
this.setAdditions(new ArrayList<NetworkAssociationActionPojo>());
this.setRemovals(new ArrayList<NetworkAssociationActionPojo>());
this.setPendings(new ArrayList<NetworkAssociationActionPojo>());
}
public RESTCallResultPojo getResult() {
return result;
}
public void setResult(RESTCallResultPojo result) {
this.result = result;
}
public List<NetworkAssociationActionPojo> getAdditions() {
return additions;
}
public void setAdditions(List<NetworkAssociationActionPojo> additions) {
this.additions = additions;
}
public List<NetworkAssociationActionPojo> getRemovals() {
return removals;
}
public void setRemovals(List<NetworkAssociationActionPojo> removals) {
this.removals = removals;
}
public List<NetworkAssociationActionPojo> getPendings() {
return pendings;
}
public void setPendings(List<NetworkAssociationActionPojo> pendings) {
this.pendings = pendings;
}
}
\ No newline at end of file
package fi.codecrew.moya.rest.pojo;
import javax.xml.bind.annotation.XmlElement;
public class RESTCallResultPojo {
private Integer resultCode;
private String resultMessage;
@XmlElement(name = "code")
public Integer getResultCode() {
return resultCode;
}
public void setResultCode(Integer resultCode) {
this.resultCode = resultCode;
}
@XmlElement(name = "message")
public String getMessage() {
return this.resultMessage;
}
public void setMessage(String message) {
this.resultMessage = message;
}
public RESTCallResultPojo(Integer code, String result) {
this.resultCode = code;
this.resultMessage = result;
}
public RESTCallResultPojo() {
this.resultCode = 1;
this.resultMessage = "ok";
}
}
\ No newline at end of file
package fi.codecrew.moya.web.cdiview.networkassociation;
import java.net.InetAddress;
import java.util.List;
import java.util.regex.Pattern;
import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;
import javax.inject.Named;
import javax.mail.internet.InternetAddress;
import fi.codecrew.moya.beans.NetworkAssociationBeanLocal;
import fi.codecrew.moya.enums.apps.NetworkAssociationPermission;
import fi.codecrew.moya.enums.apps.TournamentPermission;
import fi.codecrew.moya.model.NetworkAssociation;
import fi.codecrew.moya.utilities.jsf.MessageHelper;
import fi.codecrew.moya.web.cdiview.GenericCDIView;
@Named
@RequestScoped
public class NetworkAssociationView extends GenericCDIView {
private String ipAddress;
private String macAddress;
@EJB
private NetworkAssociationBeanLocal networkAssociationBean;
public void initView() {
super.requirePermissions(NetworkAssociationPermission.CAN_ADMINISTER_ASSOCIATIONS);
}
public String createAssociation() {
this.networkAssociationBean.tryAssociate(this.ipAddress, this.macAddress.toLowerCase());
this.ipAddress = "";
this.macAddress = "";
return "";
}
public String dropAssociation(String aid) {
Integer associd = Integer.parseInt(aid);
this.networkAssociationBean.dropAssociationById(associd);
return "";
}
public void validateIP(FacesContext context, UIComponent ui, Object object) throws Exception {
String addr = object.toString().trim();
if(addr.length() == 0)
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "networkassociation.invalid_ip_address", ""));
try {
InetAddress.getByName(addr);
} catch(Exception e) {
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "networkassociation.invalid_ip_address", ""));
}
}
public void validateMAC(FacesContext context, UIComponent ui, Object object) {
String addr = object.toString().trim();
Pattern p = Pattern.compile("(?:[0-9a-fA-F]{1,2}:){5}[0-9a-fA-F]{1,2}");
if(!p.matcher(addr).find()) {
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "networkassociation.invalid_mac_address", ""));
}
}
public List<NetworkAssociation> getActiveAssociations() {
return networkAssociationBean.getActiveAssociations(false);
}
public List<NetworkAssociation> getPendingAssociations() {
return networkAssociationBean.getPendingAssociations();
}
public String getIpAddress() {
return ipAddress;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
public String getMacAddress() {
return macAddress;
}
public void setMacAddress(String macAddress) {
this.macAddress = macAddress;
}
}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!