package org.butor.dbauth.model;
import static com.google.common.base.Strings.isNullOrEmpty;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.butor.attrset.common.AttrSet;
import org.butor.attrset.common.AttrSetCriteria;
import org.butor.attrset.dao.AttrSetDao;
import org.butor.auth.common.AuthData;
import org.butor.auth.common.AuthModel;
import org.butor.auth.common.AuthServices;
import org.butor.auth.common.ListAuthDataCriteria;
import org.butor.auth.common.SecurityConstants;
import org.butor.auth.common.auth.Auth;
import org.butor.auth.common.auth.AuthKey;
import org.butor.auth.common.auth.ListAuthCriteria;
import org.butor.auth.common.auth.ListUserAuthFuncCriteria;
import org.butor.auth.common.auth.SecData;
import org.butor.auth.common.func.Func;
import org.butor.auth.dao.AuthDao;
import org.butor.auth.dao.DataDao;
import org.butor.dao.DAOMessageID;
import org.butor.json.CommonRequestArgs;
import org.butor.json.service.Context;
import org.butor.json.service.ResponseHandler;
import org.butor.json.service.ResponseHandlerHelper;
import org.butor.utils.AccessMode;
import org.butor.utils.ApplicationException;
import org.butor.utils.CommonDateFormat;
import org.butor.utils.CommonMessageID;
import org.springframework.transaction.annotation.Transactional;
public class DefaultAuthModel implements AuthServices, AuthModel {
private AuthDao authDao;
private DataDao dataDao;
private AttrSetDao attrSetDao;
@Override
public void hasAccess(Context ctx, String system, String func, AccessMode am) {
CommonRequestArgs cra = ctx.getRequest();
ResponseHandler<Object> handler = ctx.getResponseHandler();
boolean has = hasAccess(system, func, am, cra);
handler.addRow(has);
}
@Override
public void listAuthFunc(Context ctx) {
CommonRequestArgs cra = ctx.getRequest();
ResponseHandlerHelper.addList(authDao.listAuthFunc(cra),
ctx.getResponseHandler());
}
@Override
public void listAuthSys(Context ctx, String system, String function) {
CommonRequestArgs cra = ctx.getRequest();
List<AttrSet> list = new ArrayList<AttrSet>();
Map<String, List<String>> authData = authDao.prepareAuthData(system,
function, AccessMode.READ, cra, "func");
if (authData.size() > 0 && authData.get("func_list") != null) {
// REP authorisation are of the form: d1=branchCode and d2=repId
// if a person has access to a branch, it must have an entry with d2=*
List<String> authSys = authData.get("func_list");
List<AttrSet> las = listSys(cra);
for (AttrSet sys : las) {
if (authSys.contains("*") || // all systems
authSys.contains("*.*") || // all systems and all functions
authSys.contains(sys.getK1() +".*")) { // all functions of a system
list.add(sys);
} else {
// a function of a system
String sysFunc = sys.getK1() +".";
for (String auth : authSys) {
if (auth.startsWith(sysFunc)) {
list.add(sys);
break;
}
}
}
}
}
ResponseHandlerHelper.addList(list, ctx.getResponseHandler());
}
private List<AttrSet> listSys(CommonRequestArgs cra) {
AttrSetCriteria criteria = AttrSetCriteria.valueOf("codeset", "systems", null, cra.getLang());
return attrSetDao.getAttrSet(criteria, cra);
}
@Override
public void listAuthData(Context ctx, ListAuthDataCriteria criteria) {
CommonRequestArgs cra = ctx.getRequest();
ResponseHandlerHelper.addList(listAuthData(criteria, cra),
ctx.getResponseHandler());
}
@Override
public void listAuth(Context ctx, ListAuthCriteria criteria) {
CommonRequestArgs cra = ctx.getRequest();
ResponseHandlerHelper.addList(listAuth(criteria, cra),
ctx.getResponseHandler());
}
@Override
public List<Auth> listAuth(ListAuthCriteria criteria, CommonRequestArgs cra) {
return authDao.listAuth(criteria, cra);
}
@Override
public void listUserAuthFunc(Context ctx, ListUserAuthFuncCriteria criteria) {
CommonRequestArgs cra = ctx.getRequest();
ResponseHandlerHelper.addList(authDao.listUserAuthFunc(criteria, cra),
ctx.getResponseHandler());
}
public void setAuthDao(AuthDao authDao) {
this.authDao = authDao;
}
@Override
public boolean hasAccess(String system, String func, AccessMode am, CommonRequestArgs cra) {
return authDao.hasAccess(system, func, am, cra);
}
@Override
public List<Func> listAuthFunc(CommonRequestArgs cra) {
return authDao.listAuthFunc(cra);
}
@Override
public List<AuthData> listAuthData(ListAuthDataCriteria criteria, CommonRequestArgs cra) {
return authDao.listAuthData(criteria, cra);
}
@Override
public void readAuth(Context ctx, int authId) {
CommonRequestArgs cra = ctx.getRequest();
ResponseHandler<Object> handler = ctx.getResponseHandler();
handler.addRow(readAuth(authId, cra));
}
@Override
public Auth readAuth(int authId, CommonRequestArgs cra) {
Auth auth = authDao.readAuth(authId, cra);
if (auth != null && auth.getDataId() != null && auth.getDataId() > -1) {
SecData criteria = new SecData();
criteria.setDataId(auth.getDataId());
auth.setData(dataDao.listData(criteria, cra));
}
auth.setStartDate("");
return auth;
}
@Override
@Transactional
public void createAuth(Context ctx, Auth auth) {
CommonRequestArgs cra = ctx.getRequest();
AuthKey key = createAuth(auth, cra);
ctx.getResponseHandler().addRow(key);
}
@Override
public AuthKey createAuth(Auth auth, CommonRequestArgs cra) {
if (!authDao.hasAccess(SecurityConstants.SYSTEM_ID,
SecurityConstants.SEC_FUNC_AUTHS, AccessMode.WRITE, cra)) {
ApplicationException.exception(DAOMessageID.UNAUTHORIZED.getMessage());
}
// all occurrences of data must have the same dataId.
// get the first generated one and set it to others
long dataId = -1;
if (auth.getData() != null) {
for (SecData sd : auth.getData()) {
dataDao.validateData(sd);
if (dataId != -1 ) {
sd.setDataId(dataId);
}
dataId = dataDao.insertData(sd, cra);
}
}
auth.setDataId(dataId);
AuthKey ak = authDao.insertAuth(auth, cra);
if (ak == null) {
ApplicationException.exception(CommonMessageID.NOT_FOUND.getMessage().setSysId(SecurityConstants.SYSTEM_ID));
}
return ak;
}
@Override
@Transactional
public void updateAuth(Context ctx, Auth auth) {
CommonRequestArgs cra = ctx.getRequest();
AuthKey key = updateAuth(auth, cra);
ctx.getResponseHandler().addRow(key);
}
@Override
public AuthKey updateAuth(Auth auth, CommonRequestArgs cra) {
if (!authDao.hasAccess(SecurityConstants.SYSTEM_ID,
SecurityConstants.SEC_FUNC_AUTHS, AccessMode.WRITE, cra)) {
ApplicationException.exception(DAOMessageID.UNAUTHORIZED.getMessage());
}
Auth oldAuth = readAuth(auth.getAuthId(), cra);
if (oldAuth == null) {
ApplicationException.exception(DAOMessageID.UPDATE_FAILURE.getMessage());
}
Date sd = null;
if (!isNullOrEmpty(auth.getStartDate())) {
try {
sd = CommonDateFormat.YYYYMMDD_HHMM.parse(auth.getStartDate());
} catch (ParseException ex) {
ApplicationException.exception(CommonMessageID.INVALID_ARG.getMessage("Start date").setSysId(SecurityConstants.SYSTEM_ID));
}
}
Date ed = null;
if (!isNullOrEmpty(auth.getEndDate())) {
try {
ed = CommonDateFormat.YYYYMMDD_HHMM.parse(auth.getEndDate());
} catch (ParseException ex) {
ApplicationException.exception(CommonMessageID.INVALID_ARG.getMessage("End date").setSysId(SecurityConstants.SYSTEM_ID));
}
}
if (sd != null && ed != null && sd.after(ed)) {
ApplicationException.exception(CommonMessageID.INVALID_ARG.getMessage("End date").setSysId(SecurityConstants.SYSTEM_ID));
}
long dataId = oldAuth.getDataId() != null ? oldAuth.getDataId().longValue() : -1;
dataId = dataDao.updateData(dataId, auth.getData(), cra);
if (auth.getData() != null && auth.getData().size() == 0) {
dataId = -1; // no data bundle attached to authorisation.
}
auth.setDataId(dataId);
AuthKey ak = authDao.updateAuth(auth, cra);
if (ak == null) {
ApplicationException.exception(CommonMessageID.NOT_FOUND.getMessage().setSysId(SecurityConstants.SYSTEM_ID));
}
return ak;
}
@Override
@Transactional
public void deleteAuth(Context ctx, AuthKey ak) {
CommonRequestArgs cra = ctx.getRequest();
deleteAuth(ak, cra);
}
@Override
public void deleteAuth(AuthKey ak, CommonRequestArgs cra) {
if (!authDao.hasAccess(SecurityConstants.SYSTEM_ID,
SecurityConstants.SEC_FUNC_AUTHS, AccessMode.WRITE, cra)) {
ApplicationException.exception(DAOMessageID.UNAUTHORIZED.getMessage());
}
Auth oldAuth = readAuth(ak.getAuthId(), cra);
if (oldAuth == null) {
ApplicationException.exception(DAOMessageID.UPDATE_FAILURE.getMessage());
}
authDao.deleteAuth(ak, cra);
if (oldAuth.getData() != null) {
dataDao.deleteData(oldAuth.getDataId(), cra);
}
}
@Override
public List<SecData> listData(SecData criteria, CommonRequestArgs cra) {
return dataDao.listData(criteria, cra);
}
public void updateData(long dataId, List<SecData> data, CommonRequestArgs cra) {
dataDao.updateData(dataId, data, cra);
}
public void setDataDao(DataDao dataDao) {
this.dataDao = dataDao;
}
public void setAttrSetDao(AttrSetDao attrSetDao) {
this.attrSetDao = attrSetDao;
}
}