/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package framework.beans.collaborator;
import framework.audit.AuditDetails;
import framework.audit.AuditDoc;
import framework.beans.EntityDetails;
import framework.beans.FacadeBean;
import framework.beans.ModificationInfo;
import framework.beans.client.ClientAbstract;
import framework.beans.config.server.ConfigBeanRemoteM;
import framework.beans.security.BeanRights;
import framework.beans.security.entities.CollaboratorRightAbstract;
import framework.beans.collaborator.panel.CollaboratorPanel;
import framework.beans.collaborator.panel.CollaboratorPanelPK;
import framework.beans.security.entities.CollaboratorSessionActive;
import framework.generic.ClipsServerException;
import framework.generic.EDataIntegrity;
import framework.generic.EMoveToTrash;
import framework.generic.ESecurity;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import framework.security.UserRight;
import framework.security.UserRightsGroup;
import framework.security.UserRightsSetAbstract;
import framework.security.UserRightsSetLocal;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
/**
* @param <TYPE>
* @security - Ok.
* @author axe
*/
public abstract class CollaboratorBeanAbstract<TYPE extends CollaboratorAbstract<?, CLIENTTYPE>, CLIENTTYPE extends ClientAbstract<?>>
extends FacadeBean<TYPE>
implements CollaboratorBeanRemoteAbstract {
public static final UserRight RIGHT_CREATION = UserRightsSetAbstract.WRITE_COLLABORATOR;
public static int COMMAND_WRITE_COLLABORATOR_RIGHTS = 4;
public static int COMMAND_CHANGE_OWN_PASSWORD = 5;
@EJB
private UserRightsSetLocal rightsSet;
private Class<CLIENTTYPE> clientClass;
public CollaboratorBeanAbstract(Class<TYPE> cls, Class<CLIENTTYPE> clientClass) {
super(cls);
this.clientClass = clientClass;
}
@Override
protected void initBeanRights() {
int[] r = new int[6];
if (this.getId() == getCollaboratorId()){
r[COMMAND_READ] = UserRightsSetAbstract.READ_COLLABORATOR_FULLY.id;
}else{
r[COMMAND_READ]= RightPresence(UserRightsSetAbstract.READ_COLLABORATOR_FULLY.id);
}
int cmr = RightPresence(UserRightsSetAbstract.WRITE_COLLABORATOR.id);
r[COMMAND_WRITE_COLLABORATOR_RIGHTS] = cmr;
r[COMMAND_CREATE] = cmr;
r[COMMAND_REMOVE] = cmr;
r[COMMAND_MODIFY] = cmr;
r[COMMAND_CHANGE_OWN_PASSWORD] = RightPresence(UserRightsSetAbstract.CHANGE_OWN_PASSWORD.id);
rights = new BeanRights(r);
}
/**
* Обновляет или создает запись сотрудника.
* Пароль пользователя задается не здесь
* @param details - CollaboratorDetails
* @throws ClipsServerException
*/
@Override
protected void onUpdate(TYPE entity, EntityDetails details, AuditDoc auditDoc, List<AuditDoc> auditDocList) throws ClipsServerException {
CollaboratorDetailsAbstract d = (CollaboratorDetailsAbstract) details;
entity.setTrash(d.hidden);
if (entity.getId() == 0) {
//Проверка может уже есть сотрудник привязанный к тому же человеку
Field f[] = {
new Field("client.id", d.clientID)
};
List<TYPE> collabList = findEntityList(getEntityClass(), f);
if (collabList.size() > 0) {
throw new EDataIntegrity("Такой сотрудник уже имеется в списке");
} else {
entity.setClient(findEntity(clientClass, d.clientID));
}
} else if (d.clientID != entity.getClient().getId()) {
throw new ClipsServerException("Нельзя заменять клиента соответствующего сотруднику");
}
if (entity.isTrash()) {
deleteActiveSessions();
}
entity.setLdapName(d.ldapName);
}
/**
* Изменения пароля пользователя.
* @param aNewPasswordHash
* @param anOldPasswordHash
* @return
*/
@Override
public ModificationInfo changePassword(byte [] aNewPasswordHash, byte [] anOldPasswordHash) throws ClipsServerException {
checkDischarge();
TYPE entity = getExistentEntity();
if (entity.getId() == getCollaboratorId()) {
checkCommandAccessibility(COMMAND_CHANGE_OWN_PASSWORD);
if (entity.getPasswordHash()!= null && !MessageDigest.isEqual(entity.getPasswordHash(), anOldPasswordHash)) {
return new ModificationInfo(ConfigBeanRemoteM.INVALID_OLD_ADMIN_PASSWORD, (AuditDetails) null);
}
} else {
checkCommandAccessibility(COMMAND_WRITE_COLLABORATOR_RIGHTS);
}
AuditDoc<CollaboratorAbstract> auditDoc = new AuditDoc<CollaboratorAbstract>(entity, getCollaborator());
entity.setPasswordHash(aNewPasswordHash);
saveEntity(entity);
auditDoc.check(entity);
return new ModificationInfo(ConfigBeanRemoteM.ADMIN_PASSWORD_CHANGED, persistAudit(auditDoc));
}
/**
* Возвращает список имен панелей для указанного АРМА
* @return список
* @throws ClipsServerException
*/
@Override
public Set<String> getPanelList() throws ClipsServerException {
TYPE entity = getExistentEntity();
if(entity.getId() != getCollaboratorId()) {
checkCommandAccessibility(COMMAND_MODIFY);
}
Iterator i = findEntityList(CollaboratorPanel.class,
"key.collaborator", entity.getId()).iterator();
Set<String> res = new HashSet<String>();
while (i.hasNext()) {
CollaboratorPanel j = (CollaboratorPanel) i.next();
res.add(j.getKey().getPanel());
}
return res;
}
/**
* Назначает список панелей для указанного АРМА
* @param armID АРМ
* @param panels не пустой список панелей
*/
@Override
public ModificationInfo setPanelList(Set<String> panels) throws ClipsServerException {
checkCommandAccessibility(COMMAND_MODIFY);
checkEntityExist();
checkDischarge();
Set<String> backup = new HashSet<String>(panels);
Set<String> oldPanels = getPanelList();
//make panels to add
panels.removeAll(oldPanels);
//make panels to delete
oldPanels.removeAll(backup);
ArrayList<AuditDoc> auditDocList = new ArrayList<AuditDoc>();
int eid = getId();
Iterator<String> addNew = panels.iterator();
while (addNew.hasNext()) {
CollaboratorPanel r = new CollaboratorPanel();
AuditDoc<CollaboratorPanel> auditDoc = new AuditDoc<CollaboratorPanel>(null, getCollaborator());
auditDocList.add(auditDoc);
r.setKey(new CollaboratorPanelPK(addNew.next(), eid));
manager.persist(r);
manager.flush();
manager.refresh(r);
auditDoc.check(r);
}
if (oldPanels.size() > 0) {
ArrayList<String> list2remove = new ArrayList<String>(oldPanels);
Field f[] = {
new Field("key.collaborator", eid),
new Field("key.panel", list2remove, Field.OPERATOR_IN)
};
deleteEntityList2(CollaboratorPanel.class, f, auditDocList);
}
return new ModificationInfo(0, persistAudit(auditDocList));
}
/**
* Вовзврашает список идентификаторов прав сотрудника
* @return
* @throws generic.EDataIntegrity
*/
@Override
public Set<Integer> getRights() throws ClipsServerException {
checkCommandAccessibility(COMMAND_READ);
checkEntityExist();
Iterator list = findEntityList(CollaboratorRightAbstract.class, "id.collId", getId()).iterator();
Set<Integer> res = new HashSet<Integer>();
while (list.hasNext()) {
CollaboratorRightAbstract right = (CollaboratorRightAbstract) list.next();
int rg = right.getId().getRightId();
if (UserRightsSetAbstract.getRightFromID(rg) != null) {
res.add(rg);
}
}
return res;
}
/**
* Возвращает концигурацию ГУИ для данного пользователя
* @return
*/
@Override
public String getGUIConfig() throws ClipsServerException {
checkCommandAccessibility(COMMAND_READ);
TYPE entity = getExistentEntity();
return entity.getGuiConfig();
}
/**
* Обновляет концигурацию ГУИ для данного пользователя
* @return
*/
@Override
public ModificationInfo setGUIConfig(String gc) throws ClipsServerException {
checkDischarge();
//редактирование ГУИ возможно только свое либо иметь право модифицировать данные сотрудников
if (getExistentEntity().getId() != getCollaboratorId()) {
checkCommandAccessibility(COMMAND_MODIFY);
}
TYPE entity = getExistentEntity();
AuditDoc<CollaboratorAbstract> auditDoc = new AuditDoc<CollaboratorAbstract>(entity, getCollaborator());
entity.setGuiConfig(gc);
saveEntity(entity);
auditDoc.addFieldFormat("guiConfig", "");
auditDoc.check(entity);
return new ModificationInfo(persistAudit(auditDoc));
}
protected void deleteActiveSessions() throws ClipsServerException {
TYPE entity = getExistentEntity();
deleteEntityList2(CollaboratorSessionActive.class,
new Field[]{new Field("collaborator", entity)},
new ArrayList<AuditDoc>()
);
}
@Override
protected void onRemove(TYPE entity, List<AuditDoc> audit) throws ClipsServerException {
deleteActiveSessions();
}
/**
* выкинет эксепшн если сотрудник был уволен
* @throws generic.ClipsServerException
*/
protected void checkDischarge() throws ClipsServerException{
TYPE entity = getExistentEntity();
if (entity.isTrash()){
throw new EMoveToTrash("Сотрудник был уволен");
}
}
@Override
public EntityDetails getDetails() throws ClipsServerException {
return super.getDetails();
}
@Override
public Map<String, Integer> getRightsMask() throws ClipsServerException {
Map<String, Integer> rm = new HashMap<String, Integer>();
Enumeration<UserRightsGroup> e = rightsSet.rightsGroups();
while (e.hasMoreElements()) {
rm.put(e.nextElement().getTitle(), 0);
}
int mask = 0;
Iterator<Integer> it = getRights().iterator();
while (it.hasNext()) {
Integer id = it.next();
UserRight right = UserRightsSetAbstract.getRightFromID(id);
mask = rm.get(right.getGroup().getTitle());
mask = mask | right.getRightsMask();
rm.put(right.getGroup().getTitle(), mask);
}
return rm;
}
@Override
public ModificationInfo setRightsMask(Map<String, Integer> maskMap) throws ClipsServerException {
Set<Integer> rightsId2Save = new HashSet<Integer>();//эти права будут сохранены
int mask = 0;
Enumeration<UserRightsGroup> e = rightsSet.rightsGroups();
while (e.hasMoreElements()) {
UserRightsGroup group = e.nextElement();
mask = maskMap.get(group.getTitle());
Iterator<UserRight> it = getRightsFromMask(group, mask).iterator();
while (it.hasNext()) {
UserRight ur = it.next();
rightsId2Save.add(ur.getID());
}
mask = 0;
}
return setRights(rightsId2Save);
}
/**
* извлекает из группы сет прав доступных по маске
* если из имеющихся прав данную маску построить невозможно
* выкинет ошибку
* @param group
* @param mask
* @return
* @throws generic.ESecurity
*/
protected Set<UserRight> getRightsFromMask(UserRightsGroup group, int mask) throws ESecurity{
Set<UserRight> rts = new HashSet<UserRight>();
Iterator<UserRight> it = group.getRights().iterator();
//разбираем
while (it.hasNext()) {
UserRight ur = it.next();
if (UserRight.include(mask, ur.getRightsMask())){
rts.add(ur);
}
}
//сравниваем
if (createMask(rts) != mask){
throw new ESecurity("Попытка установить невозможную комбинацию прав: " + mask);
}
return rts;
}
/**
* Строит маску из прав
* @param rts
* @param mask
* @return
* @throws generic.ESecurity
*/
protected int createMask(Set<UserRight> rts){
int mask = 0;
Iterator<UserRight> it = rts.iterator();
while (it.hasNext()) {
UserRight ur = it.next();
mask = mask | ur.getRightsMask();
}
return mask;
}
@Override
public void addCurrentCertificate(byte[] encoded) throws ClipsServerException{
if (!isCurrentCertificate(encoded)){
CollaboratorCertificate certificate = new CollaboratorCertificate();
certificate.setCertData(encoded);
certificate.setCollaborator(getExistentEntity());
manager.persist(certificate);
}
}
@Override
public boolean isCurrentCertificate(byte[] encoded) throws ClipsServerException{
CollaboratorCertificate lastCert = getLastCert();
return lastCert != null && Arrays.equals(lastCert.getCertData(),encoded);
}
private CollaboratorCertificate getLastCert() throws ClipsServerException{
List<CollaboratorCertificate> certificates = findEntityList(CollaboratorCertificate.class, "collaborator", getExistentEntity());
if (certificates.size() > 0){
CollaboratorCertificate cert = certificates.get(0);
for (CollaboratorCertificate cc : certificates) {
if (cc.getId() > cert.getId()){
cert = cc;
}
}
return cert;
}else{
return null;
}
}
}