Module member, emailaddress, domain

This commit is contained in:
Peter Hormanns 2010-10-05 19:42:07 +00:00
parent a6c4debb06
commit 726244a061
42 changed files with 2924 additions and 316 deletions

View File

@ -41,6 +41,7 @@
<classes dir="build/cls" />
<classes dir="src">
<include name="**/*.properties"/>
<include name="**/*.jtpl"/>
</classes>
<classes dir="conf">
<include name="**/*.xml"/>

View File

@ -16,6 +16,9 @@
<class>de.hsadmin.mods.pac.Hive</class>
<class>de.hsadmin.mods.pac.INetAddress</class>
<class>de.hsadmin.mods.user.UnixUser</class>
<class>de.hsadmin.mods.dom.Domain</class>
<class>de.hsadmin.mods.email.EMailAddress</class>
<class>de.hsadmin.mods.email.EMailAlias</class>
<properties>
<property name="openjpa.ConnectionDriverName" value="org.postgresql.Driver"/>
<!--

View File

@ -1,244 +0,0 @@
/*
* @(#)Base64.java 1.5 03/12/19
*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package de.hsadmin.cliClientConnector;
/**
* Static methods for translating Base64 encoded strings to byte arrays
* and vice-versa.
*
* @author Josh Bloch
* @version 1.5, 12/19/03
* @see Preferences
* @since 1.4
*/
class Base64 {
/**
* Translates the specified byte array into a Base64 string as per
* Preferences.put(byte[]).
*/
static String byteArrayToBase64(byte[] a) {
return byteArrayToBase64(a, false);
}
/**
* Translates the specified byte array into an "aternate representation"
* Base64 string. This non-standard variant uses an alphabet that does
* not contain the uppercase alphabetic characters, which makes it
* suitable for use in situations where case-folding occurs.
*/
static String byteArrayToAltBase64(byte[] a) {
return byteArrayToBase64(a, true);
}
private static String byteArrayToBase64(byte[] a, boolean alternate) {
int aLen = a.length;
int numFullGroups = aLen/3;
int numBytesInPartialGroup = aLen - 3*numFullGroups;
int resultLen = 4*((aLen + 2)/3);
StringBuffer result = new StringBuffer(resultLen);
char[] intToAlpha = (alternate ? intToAltBase64 : intToBase64);
// Translate all full groups from byte array elements to Base64
int inCursor = 0;
for (int i=0; i<numFullGroups; i++) {
int byte0 = a[inCursor++] & 0xff;
int byte1 = a[inCursor++] & 0xff;
int byte2 = a[inCursor++] & 0xff;
result.append(intToAlpha[byte0 >> 2]);
result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
result.append(intToAlpha[(byte1 << 2)&0x3f | (byte2 >> 6)]);
result.append(intToAlpha[byte2 & 0x3f]);
}
// Translate partial group if present
if (numBytesInPartialGroup != 0) {
int byte0 = a[inCursor++] & 0xff;
result.append(intToAlpha[byte0 >> 2]);
if (numBytesInPartialGroup == 1) {
result.append(intToAlpha[(byte0 << 4) & 0x3f]);
result.append("==");
} else {
// assert numBytesInPartialGroup == 2;
int byte1 = a[inCursor++] & 0xff;
result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
result.append(intToAlpha[(byte1 << 2)&0x3f]);
result.append('=');
}
}
// assert inCursor == a.length;
// assert result.length() == resultLen;
return result.toString();
}
/**
* This array is a lookup table that translates 6-bit positive integer
* index values into their "Base64 Alphabet" equivalents as specified
* in Table 1 of RFC 2045.
*/
private static final char intToBase64[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
};
/**
* This array is a lookup table that translates 6-bit positive integer
* index values into their "Alternate Base64 Alphabet" equivalents.
* This is NOT the real Base64 Alphabet as per in Table 1 of RFC 2045.
* This alternate alphabet does not use the capital letters. It is
* designed for use in environments where "case folding" occurs.
*/
private static final char intToAltBase64[] = {
'!', '"', '#', '$', '%', '&', '\'', '(', ')', ',', '-', '.', ':',
';', '<', '>', '@', '[', ']', '^', '`', '_', '{', '|', '}', '~',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '?'
};
/**
* Translates the specified Base64 string (as per Preferences.get(byte[]))
* into a byte array.
*
* @throw IllegalArgumentException if <tt>s</tt> is not a valid Base64
* string.
*/
static byte[] base64ToByteArray(String s) {
return base64ToByteArray(s, false);
}
/**
* Translates the specified "aternate representation" Base64 string
* into a byte array.
*
* @throw IllegalArgumentException or ArrayOutOfBoundsException
* if <tt>s</tt> is not a valid alternate representation
* Base64 string.
*/
static byte[] altBase64ToByteArray(String s) {
return base64ToByteArray(s, true);
}
private static byte[] base64ToByteArray(String s, boolean alternate) {
byte[] alphaToInt = (alternate ? altBase64ToInt : base64ToInt);
int sLen = s.length();
int numGroups = sLen/4;
if (4*numGroups != sLen)
throw new IllegalArgumentException(
"String length must be a multiple of four.");
int missingBytesInLastGroup = 0;
int numFullGroups = numGroups;
if (sLen != 0) {
if (s.charAt(sLen-1) == '=') {
missingBytesInLastGroup++;
numFullGroups--;
}
if (s.charAt(sLen-2) == '=')
missingBytesInLastGroup++;
}
byte[] result = new byte[3*numGroups - missingBytesInLastGroup];
// Translate all full groups from base64 to byte array elements
int inCursor = 0, outCursor = 0;
for (int i=0; i<numFullGroups; i++) {
int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt);
int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt);
int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt);
int ch3 = base64toInt(s.charAt(inCursor++), alphaToInt);
result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
result[outCursor++] = (byte) ((ch2 << 6) | ch3);
}
// Translate partial group, if present
if (missingBytesInLastGroup != 0) {
int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt);
int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt);
result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
if (missingBytesInLastGroup == 1) {
int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt);
result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
}
}
// assert inCursor == s.length()-missingBytesInLastGroup;
// assert outCursor == result.length;
return result;
}
/**
* Translates the specified character, which is assumed to be in the
* "Base 64 Alphabet" into its equivalent 6-bit positive integer.
*
* @throw IllegalArgumentException or ArrayOutOfBoundsException if
* c is not in the Base64 Alphabet.
*/
private static int base64toInt(char c, byte[] alphaToInt) {
int result = alphaToInt[c];
if (result < 0)
throw new IllegalArgumentException("Illegal character " + c);
return result;
}
/**
* This array is a lookup table that translates unicode characters
* drawn from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045)
* into their 6-bit positive integer equivalents. Characters that
* are not in the Base64 alphabet but fall within the bounds of the
* array are translated to -1.
*/
private static final byte base64ToInt[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54,
55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34,
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
};
/**
* This array is the analogue of base64ToInt, but for the nonstandard
* variant that avoids the use of uppercase alphabetic characters.
*/
private static final byte altBase64ToInt[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1,
2, 3, 4, 5, 6, 7, 8, -1, 62, 9, 10, 11, -1 , 52, 53, 54, 55, 56, 57,
58, 59, 60, 61, 12, 13, 14, -1, 15, 63, 16, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 17, -1, 18, 19, 21, 20, 26, 27, 28, 29, 30, 31, 32, 33,
34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
51, 22, 23, 24, 25
};
public static void main(String args[]) {
int numRuns = Integer.parseInt(args[0]);
int numBytes = Integer.parseInt(args[1]);
java.util.Random rnd = new java.util.Random();
for (int i=0; i<numRuns; i++) {
for (int j=0; j<numBytes; j++) {
byte[] arr = new byte[j];
for (int k=0; k<j; k++)
arr[k] = (byte)rnd.nextInt();
String s = byteArrayToBase64(arr);
byte [] b = base64ToByteArray(s);
if (!java.util.Arrays.equals(arr, b))
System.out.println("Dismal failure!");
s = byteArrayToAltBase64(arr);
b = altBase64ToByteArray(s);
if (!java.util.Arrays.equals(arr, b))
System.out.println("Alternate dismal failure!");
}
}
}
}

View File

@ -16,6 +16,8 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.codec.binary.Base64;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.GenericModuleImpl;
import de.hsadmin.core.model.ModuleInterface;
@ -32,7 +34,7 @@ import de.hsadmin.core.model.onetier.TicketValidator;
*/
public class CLIClientConnectorServlet extends HttpServlet {
private static final long serialVersionUID = 7150004719303750077L;
public static final String version = "1.0.8 (2009/May/27 18:22)";
public static final String version = "1.0.9 (2010/Oct/05 18:34)";
private Map<String, Class<?>> componentmap;
private Map<String, String> componentDescriptions;
private ArgumentParser parser;
@ -445,11 +447,9 @@ public class CLIClientConnectorServlet extends HttpServlet {
// parse login information
String[] a = auth.split(" ", 2);
String ticket = a[1];
byte[] decoded = Base64.base64ToByteArray(ticket.trim());
StringBuffer s = new StringBuffer();
for (int i = 0; i < decoded.length; i++)
s.append((char) decoded[i]);
a = s.toString().split(":", 2);
byte[] decoded = Base64.decodeBase64(ticket.trim().getBytes());
String s = new String(decoded);
a = s.split(":", 2);
// try to log in
String login = a[0];
ticket = a[1];

View File

@ -37,12 +37,8 @@ public class GenericModuleImpl implements ModuleInterface {
EntitySessionHelper.createEntitySessionWrapper(newEntity.getClass());
wrapper.construct(tx);
AbstractEntity result = null;
try {
result = wrapper.add(newEntity);
return result;
} catch (Exception e) {
throw new HSAdminException(e);
}
result = wrapper.add(newEntity);
return result;
}
@Override
@ -76,11 +72,7 @@ public class GenericModuleImpl implements ModuleInterface {
log.debug("update(" + existingEntity + ")");
AbstractModuleImpl wrapper = EntitySessionHelper.createEntitySessionWrapper(existingEntity.getClass());
wrapper.construct(tx);
try {
return wrapper.update(existingEntity);
} catch (Exception e) {
throw new HSAdminException(e);
}
return wrapper.update(existingEntity);
}
@Override
@ -89,11 +81,7 @@ public class GenericModuleImpl implements ModuleInterface {
AbstractModuleImpl wrapper =
EntitySessionHelper.createEntitySessionWrapper(existingEntity.getClass());
wrapper.construct(tx);
try {
wrapper.delete(existingEntity);
} catch (Exception e) {
throw new HSAdminException(e);
}
wrapper.delete(existingEntity);
}
}

View File

@ -0,0 +1,51 @@
package de.hsadmin.core.util;
import java.net.InetAddress;
import java.net.UnknownHostException;
import de.hsadmin.core.model.HSAdminException;
import de.hsadmin.core.util.dns.DNSQuery;
import de.hsadmin.core.util.dns.DNSService;
public class DNSCheck {
private String dnsServer;
public DNSCheck(String dnsServer) {
this.dnsServer = dnsServer;
InetAddress dnsInetAddress;
try {
dnsInetAddress = InetAddress.getByName(dnsServer);
DNSService.SetDNSAddress(dnsInetAddress);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public boolean checkDomain(String domain) throws HSAdminException {
boolean hasNSRecord = false;
boolean hasARecord = false;
DNSQuery dnsQuery = new DNSQuery();
dnsQuery.SetQuery(DNSQuery.TYPE_NS, DNSQuery.CLASS_INTERNET, domain);
if (DNSService.PerformDNSQuery(dnsQuery)) {
hasNSRecord = dnsQuery.getDNSAuthorityRecords() != null && dnsQuery.getDNSAuthorityRecords().length > 0;
if (dnsQuery.getDNSAuthorityRecords() != null) {
System.out.println("NS:" + dnsQuery.getDNSAuthorityRecords().length);
}
} else {
throw new HSAdminException("domain " + domain + " is not delegated to " + dnsServer);
}
dnsQuery.SetQuery(DNSQuery.TYPE_A, DNSQuery.CLASS_INTERNET, domain);
if (DNSService.PerformDNSQuery(dnsQuery)) {
hasARecord = dnsQuery.getDNSAnswerRecords() != null && dnsQuery.getDNSAnswerRecords().length > 0;
if (dnsQuery.getDNSAnswerRecords() != null) {
System.out.println("A: " + dnsQuery.getDNSAnswerRecords().length);
}
} else {
throw new HSAdminException("domain " + domain + " is not delegated to " + dnsServer);
}
return hasNSRecord & !hasARecord;
}
}

View File

@ -0,0 +1,45 @@
package de.hsadmin.core.util;
public class TextUtil {
public static String replaceUmlauts(String umlautString) {
StringBuffer buffer = new StringBuffer();
for (char c : umlautString.toCharArray()) {
if ( (c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') ||
(c == ' ') ) {
buffer.append(c);
} else {
switch (c) {
case 'ä':
buffer.append("ae");
break;
case 'ö':
buffer.append("oe");
break;
case 'ü':
buffer.append("ue");
break;
case 'Ä':
buffer.append("Ae");
break;
case 'Ö':
buffer.append("Oe");
break;
case 'Ü':
buffer.append("Ue");
break;
case 'ß':
buffer.append("ss");
break;
default:
buffer.append('-');
break;
}
}
}
return buffer.toString();
}
}

View File

@ -0,0 +1,395 @@
package de.hsadmin.core.util.dns;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class DNSQuery {
// DNS constants
private final static int MAX_LABEL = 128;
// DNS flag values
private final static int QR_MASK = 0x8000;
private final static int QR_SHIFT = 0;
private final static int OPCODE_MASK = 0x7800;
private final static int AA_MASK = 0x0400;
private final static int TC_MASK = 0x0200;
private final static int RD_MASK = 0x0100;
private final static int RA_MASK = 0x0080;
private final static int ZERO_MASK = 0x0070;
private final static int RCODE_MASK = 0x000f;
// DNS query/type constants
public final static int TYPE_A = 1;
public final static int TYPE_NS = 2;
public final static int TYPE_MD = 3;
public final static int TYPE_MF = 4;
public final static int TYPE_CNAME = 5;
public final static int TYPE_SOA = 6;
public final static int TYPE_MB = 7;
public final static int TYPE_MG = 8;
public final static int TYPE_MR = 9;
public final static int TYPE_NULL = 10;
public final static int TYPE_WKS = 11;
public final static int TYPE_PTR = 12;
public final static int TYPE_HINFO = 13;
public final static int TYPE_MINFO = 14;
public final static int TYPE_MX = 15;
public final static int TYPE_AXFR = 252;
public final static int TYPE_ANY = 255;
// DNS query classes
public final static byte CLASS_INTERNET = 1;
// query data members
public int m_idQuery = 0x0101;
// opcodes
public final static int OP_NORM_QRY = 0x0000;
public final static int OP_INVERSE_QRY = 0x0800;
public final static int OP_SERVER_STAT = 0x1000;
public int m_iOpCode = OP_NORM_QRY;
// flags
public boolean m_fQueryResult = false;
public boolean m_fAuthAns = false;
public boolean m_fTruncated = false;
public boolean m_fRecurse = true;
public boolean m_fRecursionAvail = false;
private int m_iQryType = TYPE_A;
private int m_iQryClass = CLASS_INTERNET;
private String m_strQryName = null;
// return codes
public int m_iRCode = 0;
public final static int RCODE_SUCCESS = 0;
public final static int RCODE_NAME_ERROR = 0x0003;
public int m_cQuestions = 1;
public int m_cAnswerRRs = 0;
public int m_cAuthRRs = 0;
public int m_cInfoRRs = 0;
DNSResourceRecord [] m_arrAns;
DNSResourceRecord [] m_arrAuth;
DNSResourceRecord [] m_arrInfo;
public static String GetTypeDesc(int iType) {
String str = null;
switch (iType) {
case TYPE_A: { str = new String("TYPE_A"); } break;
case TYPE_NS: { str = new String("TYPE_NS"); } break;
case TYPE_CNAME: { str = new String("TYPE_CNAME"); } break;
case TYPE_SOA: { str = new String("TYPE_SOA"); } break;
case TYPE_PTR: { str = new String("TYPE_PTR"); } break;
case TYPE_HINFO: { str = new String("TYPE_HINFO"); } break;
case TYPE_MX: { str = new String("TYPE_MX"); } break;
case TYPE_AXFR: { str = new String("TYPE_AXFR"); } break;
case TYPE_ANY: { str = new String("TYPE_ANY"); } break;
default: { str = new String(Integer.toString(iType)); };
}
return str;
}
public DNSResourceRecord[] getDNSAnswerRecords() {
return m_arrAns;
}
public DNSResourceRecord[] getDNSAuthorityRecords() {
return m_arrAuth;
}
public static String GetClassDesc(int iClass) {
String str = null;
switch (iClass) {
case CLASS_INTERNET: { str = new String("CLASS_INTERNET"); } break;
default: { str = new String(); };
}
return str;
}
private int BuildFlags() {
int iFlags = 0;
iFlags |= m_iOpCode;
if (m_fRecurse) {
iFlags |= RD_MASK;
}
return iFlags;
}
private boolean SetFlags(int iFlags) {
m_fQueryResult = (iFlags & QR_MASK) == QR_MASK;
m_fAuthAns = (iFlags & AA_MASK) == AA_MASK;
m_fTruncated = (iFlags & TC_MASK) == TC_MASK;
m_fRecurse = (iFlags & RD_MASK) == RD_MASK;
m_fRecursionAvail = (iFlags & RA_MASK) == RA_MASK;
m_iRCode = iFlags & RCODE_MASK;
return m_iRCode == RCODE_SUCCESS;
}
public boolean SetQuery(int iType, int iClass, String strName) {
m_iQryType = iType;
m_iQryClass = iClass;
m_cQuestions = 1;
m_strQryName = new String(strName);
return true;
}
private boolean WriteFQDN(DataOutputStream dos, String strName) {
try {
int iPos = 0;
int iSep = 0;
while ((iSep = strName.indexOf('.', iPos)) >= 0) {
dos.writeByte((byte)(iSep - iPos));
dos.writeBytes(strName.substring(iPos, iSep));
iPos = iSep + 1;
}
if (iPos < strName.length()) {
dos.writeByte((byte)(strName.length() - iPos));
dos.writeBytes(strName.substring(iPos));
}
// terminator
dos.writeByte(0);
return true;
} catch (IOException ioe) {
return false;
}
}
public static String ReadLabelList(DataInputStream dis, byte [] abData) {
int cb;
byte [] ab = new byte[MAX_LABEL];
String str = new String();
String strNext = new String();
try {
while ((cb = dis.readUnsignedByte()) > 0) {
if ((cb & 0xc0) == 0xc0) {
int iReadOff = (int)(cb & ~0xc0) << 8;
cb = dis.readUnsignedByte();
iReadOff += (int)cb;
while (iReadOff < abData.length && ((cb = abData[iReadOff++]) > 0)) {
if ((cb & 0xc0) == 0xc0) {
return str;
}
strNext = new String(abData, 0, iReadOff, cb);
if (str.length() > 0) {
str += "." + strNext;
} else {
str = strNext;
}
iReadOff += cb;
}
return str;
} else {
byte [] abNext = new byte[cb];
if (dis.read(abNext) < cb) {
return new String();
}
strNext = new String(abNext, 0, 0, cb);
}
if (str.length() > 0) {
str += "." + strNext;
} else {
str = strNext;
}
}
} catch (IOException ioe) {
System.err.println("exception: " + ioe.getMessage());
}
return str;
}
public boolean WriteQuery(OutputStream os) {
try {
if (m_strQryName == null) {
return false;
}
DataOutputStream dos = new DataOutputStream(os);
// query sequence ID
dos.writeShort(m_idQuery);
// query flags
dos.writeShort(BuildFlags());
// question count
dos.writeShort(1);
// answer count
dos.writeShort(0);
// authority count
dos.writeShort(0);
// additional info count
dos.writeShort(0);
// write query name
WriteFQDN(dos, m_strQryName);
// query type
dos.writeShort(m_iQryType);
// query class
dos.writeShort(m_iQryClass);
return true;
} catch (IOException ioe) {
return false;
}
}
private void SortRRs(DNSResourceRecord [] arr, boolean fDescending) {
if (arr == null || arr.length < 2) {
return;
}
boolean fSwapped;
DNSResourceRecord rrSwap;
do {
fSwapped = false;
for (int i = 0; i < arr.length - 1; i++) {
boolean fSwap = false;
if (arr[i+1].m_iType < arr[i].m_iType) {
fSwap = true;
} else if (arr[i+1].m_iType == arr[i].m_iType) {
switch (arr[i].m_iType) {
case TYPE_MX: {
fSwap = arr[i+1].m_lData < arr[i].m_lData;
} break;
}
}
if (fSwap = fSwap ^ fDescending) {
rrSwap = arr[i];
arr[i] = arr[i+1];
arr[i+1] = rrSwap;
fSwapped = true;
}
}
} while (fSwapped);
}
public boolean ReadQuery(byte [] abData, int cbData) {
try {
ByteArrayInputStream is = new ByteArrayInputStream(abData, 0, cbData);
DataInputStream dis = new DataInputStream(is);
// query sequence ID
m_idQuery = dis.readShort();
// query flags
if (!SetFlags(dis.readShort())) {
return false;
}
// question count
m_cQuestions = dis.readShort();
// answer count
m_cAnswerRRs = dis.readShort();
// authority count
m_cAuthRRs = dis.readShort();
// additional info count
m_cInfoRRs = dis.readShort();
// read query name
m_strQryName = ReadLabelList(dis, abData);
// query type
m_iQryType = dis.readShort();
// query class
m_iQryClass = dis.readShort();
m_arrAns = new DNSResourceRecord[m_cAnswerRRs];
for (int i = 0; i < m_cAnswerRRs; i++) {
m_arrAns[i] = new DNSResourceRecord();
if (!m_arrAns[i].readRecord(dis, abData)) {
return false;
}
}
SortRRs(m_arrAns, false);
if (m_cAuthRRs > 0) {
m_arrAuth = new DNSResourceRecord[m_cAuthRRs];
for (int i = 0; i < m_cAuthRRs; i++) {
m_arrAuth[i] = new DNSResourceRecord();
if (!m_arrAuth[i].readRecord(dis, abData)) {
return false;
}
}
SortRRs(m_arrAuth, false);
} else {
m_arrAuth = null;
}
if (m_cInfoRRs > 0) {
m_arrInfo = new DNSResourceRecord[m_cInfoRRs];
for (int i = 0; i < m_cInfoRRs; i++) {
m_arrInfo[i] = new DNSResourceRecord();
if (!m_arrInfo[i].readRecord(dis, abData)) {
return false;
}
}
SortRRs(m_arrInfo, false);
} else {
m_arrInfo = null;
}
} catch (IOException ioe) {
System.err.println("exception: " + ioe.getMessage());
return false;
}
return true;
}
}

View File

@ -0,0 +1,190 @@
package de.hsadmin.core.util.dns;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Date;
public class DNSResourceRecord {
public String m_strDomainName;
public int m_iType;
public int m_iClass;
public Date m_dtExpire = new Date();
public int m_cbData;
public byte [] m_abData = null;
// these fields are interpreted differently depending on m_iType
// (can you say union?)
public long m_lData;
public long m_lData1;
public long m_lData2;
public long m_lData3;
public long m_lData4;
public long m_lData5;
public String m_strData;
public String m_strData1;
public boolean readRecord(DataInputStream dis, byte [] abData) {
try {
m_strDomainName = DNSQuery.ReadLabelList(dis, abData);
m_iType = dis.readShort();
m_iClass = dis.readShort();
// time from DNS is in seconds, need milliseconds
long lSecondsToLive = dis.readInt();
Date dtNow = new Date();
m_dtExpire.setTime(dtNow.getTime() + (lSecondsToLive * 1000L));
m_cbData = dis.readShort();
m_abData = null;
switch (m_iType) {
case DNSQuery.TYPE_A: {
m_lData = dis.readInt();
} break;
case DNSQuery.TYPE_MX: {
m_lData = dis.readShort();
m_strData = DNSQuery.ReadLabelList(dis, abData);
} break;
case DNSQuery.TYPE_NS:
case DNSQuery.TYPE_MD:
case DNSQuery.TYPE_MF:
case DNSQuery.TYPE_CNAME:
case DNSQuery.TYPE_MB:
case DNSQuery.TYPE_MG:
case DNSQuery.TYPE_MR:
case DNSQuery.TYPE_PTR: {
m_strData = DNSQuery.ReadLabelList(dis, abData);
} break;
case DNSQuery.TYPE_SOA: {
// !!!LATER!!! I had a real problem getting this code to work.
// I think the spec I had was old RFC 883
m_strData = DNSQuery.ReadLabelList(dis, abData);
m_strData1 = DNSQuery.ReadLabelList(dis, abData);
// SERIAL
m_lData = dis.readUnsignedShort();
// REFRESH
m_lData1 = dis.readInt() & 0xffffffff;
// RETRY
m_lData2 = dis.readInt() & 0xffffffff;
// EXPIRE
m_lData3 = dis.readInt() & 0xffffffff;
// MINIMUM
m_lData4 = dis.readUnsignedShort();
// UNKNOWN
m_lData5 = dis.readInt() & 0xffffffff;
} break;
case DNSQuery.TYPE_MINFO:
case DNSQuery.TYPE_HINFO: {
m_strData = DNSQuery.ReadLabelList(dis, abData);
m_strData1 = DNSQuery.ReadLabelList(dis, abData);
} break;
default: {
m_abData = new byte[m_cbData];
dis.read(m_abData);
} break;
}
} catch (IOException ioe) {
System.err.println("exception: " + ioe.getMessage());
}
return true;
}
public String getMXServer() {
if (m_iType != DNSQuery.TYPE_MX) {
return new String();
}
return new String(m_strData);
}
public int getMXPref() {
if (m_iType != DNSQuery.TYPE_MX) {
return -1;
}
return (int)m_lData;
}
public void dumpRecord(PrintStream ps) {
ps.println("Domain: " + m_strDomainName);
ps.println("Type: " + DNSQuery.GetTypeDesc(m_iType));
ps.println("Class: " + DNSQuery.GetClassDesc(m_iClass));
ps.println("Expires: " + m_dtExpire.toString());
switch (m_iType) {
case DNSQuery.TYPE_A: {
ps.println("IP Address: " + Long.toHexString(m_lData));
} break;
case DNSQuery.TYPE_MX: {
ps.println("MX Server: " + m_strData);
ps.println("MX Pref: " + Long.toString(m_lData));
} break;
case DNSQuery.TYPE_NS:
case DNSQuery.TYPE_MD:
case DNSQuery.TYPE_MF:
case DNSQuery.TYPE_CNAME:
case DNSQuery.TYPE_MB:
case DNSQuery.TYPE_MG:
case DNSQuery.TYPE_MR:
case DNSQuery.TYPE_PTR: {
ps.println("Domain: " + m_strData);
} break;
case DNSQuery.TYPE_HINFO: {
ps.println("CPU: " + m_strData);
ps.println("OS: " + m_strData1);
} break;
case DNSQuery.TYPE_SOA: {
ps.println("MNAME: " + m_strData);
ps.println("RNAME: " + m_strData1);
ps.println("SERIAL: " + Long.toString(m_lData));
ps.println("REFRESH: " + Long.toString(m_lData1));
ps.println("RETRY: " + Long.toString(m_lData2));
ps.println("EXPIRE: " + Long.toString(m_lData3));
ps.println("MINIMUM: " + Long.toString(m_lData4));
ps.println("UNKNOWN: " + Long.toString(m_lData4));
} break;
default: {
ps.println("Data: " + new String(m_abData));
dumpBytes(ps, m_abData);
}
}
}
private void dumpBytes(PrintStream ps, byte [] ab) {
int i;
String strTemp;
for (i = 0; i < ab.length; i++) {
strTemp = Integer.toHexString(ab[i]);
if (strTemp.length() < 2) {
strTemp = "0" + strTemp;
}
ps.print(strTemp + " ");
if (i > 0 && ((i % 8) == 0 || i == ab.length-1)) {
ps.println();
}
}
}
}

View File

@ -0,0 +1,80 @@
package de.hsadmin.core.util.dns;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
public class DNSService {
public static int DNS_SOCKET = 53;
private static InetAddress m_iaDNS = null;
private static Socket m_sockService = null;
private static byte[] m_abReceive = new byte[512];
private static int m_iQuerySerial = 0x1234;
public static void SetDNSAddress(InetAddress iaDNS) {
m_iaDNS = iaDNS;
if (m_sockService == null) {
try {
m_sockService = new Socket(m_iaDNS, DNS_SOCKET, false);
} catch (IOException ioe) {
System.err.println("exception: " + ioe.getMessage());
}
}
}
public static boolean PerformDNSQuery(DNSQuery dns) {
if (m_iaDNS == null || dns == null) {
return false;
}
ByteArrayOutputStream bas = new ByteArrayOutputStream();
dns.WriteQuery(bas);
try {
m_sockService.getOutputStream().write(bas.toByteArray());
} catch (IOException ioe) {
return false;
}
try {
BufferedInputStream bis = new BufferedInputStream(m_sockService.getInputStream(), 512);
int cRetry = 5;
int cbAvail = 0;
while (cRetry-- > 0 && ((cbAvail = bis.available()) <= 0)) {
try {
Thread.currentThread().sleep(200);
} catch (InterruptedException ie) {
System.err.println("exception: " + ie.getMessage());
}
}
if (cbAvail > 0) {
int cbRead = bis.read(m_abReceive, 0, cbAvail);
m_iQuerySerial++;
if (cbRead > 0) {
dns.ReadQuery(m_abReceive, cbRead);
} else {
return false;
}
} else {
return false;
}
} catch (IOException ioe) {
return false;
}
return true;
}
}

View File

@ -20,6 +20,7 @@ import javax.persistence.OneToOne;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.Transient;
import de.hsadmin.mods.pac.Pac;
import de.hsadmin.mods.user.UnixUser;
@ -40,6 +41,9 @@ public class Customer extends de.hsadmin.core.model.AbstractEntity implements Se
@Column(name = "member_code", columnDefinition = "character varying(20)")
private String name;
@Transient
private String password;
@Column(name = "member_since", columnDefinition = "date", nullable = true)
private Date memberSince;
@ -269,4 +273,12 @@ public class Customer extends de.hsadmin.core.model.AbstractEntity implements Se
public static String restriction() {
return "obj.name=:loginUserName";
}
public void setPassword(String password) {
this.password = password;
}
public String getPassword() {
return password;
}
}

View File

@ -1,7 +1,74 @@
package de.hsadmin.mods.cust;
import java.util.List;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.AbstractModuleImpl;
import de.hsadmin.core.model.GenericModuleImpl;
import de.hsadmin.core.model.HSAdminException;
import de.hsadmin.core.util.TextUtil;
import de.hsadmin.mods.user.UnixUser;
public class CustomerModuleImpl extends AbstractModuleImpl {
@Override
public AbstractEntity add(AbstractEntity newEntity) throws HSAdminException {
if (!getLoginUser().hasHostmasterRole()) {
throw new HSAdminException("role hostmaster required to create new customer");
}
Customer newCustomer = (Customer) newEntity;
assertNotNull("membercode", newCustomer.getName());
assertNotNull("password", newCustomer.getPassword());
Contact contact = newCustomer.getContacts().iterator().next();
assertNotNull("contact_lastname", contact.getLastName());
String custComment = contact.getLastName();
if (contact.getFirstName() != null && contact.getFirstName().length() > 0) {
custComment = contact.getFirstName() + " " + contact.getLastName();
}
GenericModuleImpl helperModule = new GenericModuleImpl(getTransaction());
UnixUser custAccount = new UnixUser();
custAccount.setComment(TextUtil.replaceUmlauts(custComment));
custAccount.setName(newCustomer.getName());
custAccount.setPassword(newCustomer.getPassword());
custAccount.setShell("/usr/bin/passwd");
custAccount.setQuotaSoftlimit(8);
custAccount.setQuotaHardlimit(12);
helperModule.add(custAccount);
return super.add(newEntity);
}
@Override
public List<AbstractEntity> search(
Class<? extends AbstractEntity> entityClass, String condition,
String orderBy) throws HSAdminException {
return super.search(entityClass, condition, orderBy);
}
@Override
public AbstractEntity update(AbstractEntity existingEntity)
throws HSAdminException {
if (!getLoginUser().hasHostmasterRole()) {
throw new HSAdminException("role hostmaster required to update customers");
}
return super.update(existingEntity);
}
@Override
public void delete(AbstractEntity existingEntity) throws HSAdminException {
if (!getLoginUser().hasHostmasterRole()) {
throw new HSAdminException("role hostmaster required to delete customers");
}
Customer cust = (Customer) existingEntity;
GenericModuleImpl helper = new GenericModuleImpl(getTransaction());
AbstractEntity custAccount = helper.findByString(UnixUser.class, cust.getName());
helper.delete(custAccount);
super.delete(existingEntity);
}
private void assertNotNull(String name, String value) throws HSAdminException {
if (value == null || value.length() < 1) {
throw new HSAdminException("field '" + name + "' is mandatory");
}
}
}

View File

@ -0,0 +1,232 @@
package de.hsadmin.mods.dom;
import static javax.persistence.FetchType.EAGER;
import static javax.persistence.GenerationType.SEQUENCE;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.EntityManager;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Temporal;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.mods.user.UnixUser;
@javax.persistence.Entity(name = "Domains")
@Table(name = "domain")
@SequenceGenerator(name = "DomainsSeqGen", sequenceName = "domain_domain_id_seq")
public class Domain extends AbstractEntity {
private static final long serialVersionUID = -7496110900868795840L;
@javax.persistence.Id
@javax.persistence.Column(name = "domain_id", columnDefinition = "integer")
@javax.persistence.GeneratedValue(strategy = SEQUENCE, generator = "DomainsSeqGen")
private long id;
@javax.persistence.Column(name = "domain_name", columnDefinition = "character varying(256)", nullable = false)
private String name;
@JoinColumn(name = "domain_owner", columnDefinition = "integer", nullable = false)
@ManyToOne(fetch = EAGER)
private UnixUser user;
@Column(name = "domain_status", columnDefinition = "character varying(12)", nullable = false)
private String status;
@Column(name = "domain_status_changed", columnDefinition = "date", nullable = false)
@Temporal(javax.persistence.TemporalType.DATE)
private Date statusChanged;
@Column(name = "domain_filed", columnDefinition = "date")
@Temporal(javax.persistence.TemporalType.DATE)
private Date filed;
@Column(name = "domain_since", columnDefinition = "date")
@Temporal(javax.persistence.TemporalType.DATE)
private Date since;
@Column(name = "domain_until", columnDefinition = "date")
@Temporal(javax.persistence.TemporalType.DATE)
private Date until;
@Column(name = "domain_dns_master", columnDefinition = "character varying(64)")
private String dnsMaster;
public Domain() {
}
public Domain(String name, UnixUser user) {
this.name = name;
this.user = user;
this.statusChanged = new java.util.Date();
this.status = Status.FILED.toString();
}
public static String createQueryFromStringKey(String humanKey) {
return "name = '" + humanKey + "'";
}
@Override
public String createStringKey() {
return getName();
}
@Override
public long id() {
return id;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public UnixUser getUser() {
return user;
}
public void setUser(UnixUser user) {
this.user = user;
}
@javax.persistence.Transient
public Status getStatus() {
return Status.valueFor(status);
}
public void setStatus(Status status) {
this.status = status.toString();
}
public Date getStatusChanged() {
return statusChanged;
}
public void setStatusChanged(Date statusChanged) {
this.statusChanged = statusChanged;
}
public Date getFiled() {
return filed;
}
public void setFiled(Date filed) {
this.filed = filed;
}
public Date getSince() {
return since;
}
public void setSince(Date since) {
this.since = since;
}
public Date getUntil() {
return until;
}
public void setUntil(Date until) {
this.until = until;
}
public String getDnsMaster() {
return dnsMaster;
}
public void setDnsMaster(String dnsMaster) {
this.dnsMaster = dnsMaster;
}
@Override
public boolean isNew() {
return id == 0;
}
public boolean isReadAllowedFor(UnixUser loginUser) {
return loginUser.hasHostmasterRole() || // hostmaster
user.getId() == loginUser.getId() || // dom-admin
user.getPac().getName().equals(loginUser.getName()) || // pac-admin
user.getPac().getCustomer().getName().equals(loginUser.getName()); // customer
}
public boolean isWriteAllowedFor(UnixUser loginUser) {
return isReadAllowedFor(loginUser);
}
@Override
public String getHiveName() {
if (isNew())
return null;
else
return getUser().getHiveName();
}
@Override
public UnixUser owningUser(EntityManager em) {
return user;
}
public static String restriction() {
return
// all doms of all pacs of customer
"obj.user.pac.customer.name=:loginUserName OR " +
// all doms of packet admin
"obj.user.pac.name=:loginUserName OR " +
// all domains of the user itself
"obj.user=:loginUser";
}
public static enum Status {
NONE(""),
ERROR("error"),
FILED("filed"),
SELF("self"),
REGISTERING("registering"),
REGISTERED("registered"),
TRANSFERRING("transferring"),
NACK_RECEIVED("KK-NACK"),
ACK_RECEIVED("KK-ACK"),
MANAGED("connected"),
LEAVE_SIGNALLED("KK-sig"),
LEAVING("leaving"),
GONE("gone"),
CLOSE_REQUESTED("CLO-req"),
CLOSING("closing"),
CLOSED("closed");
private Status(String aValue) {
this.aValue = aValue;
}
public String toString() {
return aValue;
}
private String aValue;
public static Status valueFor(String str) {
for (Status val : Status.values())
if (val.toString().equals(str))
return val;
return null;
}
}
}

View File

@ -0,0 +1,198 @@
package de.hsadmin.mods.dom;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import de.hsadmin.core.model.AbstractModuleImpl;
import de.hsadmin.core.model.AuthorisationException;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.HSAdminException;
import de.hsadmin.core.util.DNSCheck;
import de.hsadmin.mods.dom.Domain.Status;
import de.hsadmin.mods.email.EMailAddress;
import de.hsadmin.mods.pac.Pac;
import de.hsadmin.mods.user.UnixUser;
public class DomainModuleImpl extends AbstractModuleImpl {
private static final long serialVersionUID = -3991273357778898175L;
@Override
public AbstractEntity initialize(AbstractEntity newEntity) throws AuthorisationException {
AbstractEntity newDom = super.initialize(newEntity);
if (newDom instanceof Domain) {
((Domain) newDom).setUser(getLoginUser());
return newDom;
}
return null;
}
@Override
public AbstractEntity find(Class<? extends AbstractEntity> entityClass, Object key) throws HSAdminException {
// do query
AbstractEntity res = super.find(entityClass, key);
// check access rights
needsReadAccessOn(res, "find");
// return clean result
return res;
}
@Override
public AbstractEntity findByString(Class<? extends AbstractEntity> entityClass, String key)
throws HSAdminException {
// do query
AbstractEntity res = super.findByString(entityClass, key);
// check access rights
if (res != null)
needsReadAccessOn(res, "findByString");
// return clean result
return res;
}
@Override
public List<AbstractEntity> search(Class<? extends AbstractEntity> entityClass, String condition, String orderBy) throws HSAdminException {
// do query
if (orderBy == null || orderBy.length() == 0) {
orderBy = "ORDER BY obj.name ASC";
}
List<AbstractEntity> res = super.search(entityClass, condition, orderBy);
List<AbstractEntity> ret = new LinkedList<AbstractEntity>();
// remove entities where login user has no access rights
for (AbstractEntity entity : res) {
try {
needsReadAccessOn(entity, "search");
ret.add(entity);
} catch (AuthorisationException exc) {
} // ignore
}
// return clean result
return ret;
}
@Override
public AbstractEntity add(AbstractEntity newEntity) throws HSAdminException {
Domain dom = (Domain) newEntity;
Date now = new Date();
dom.setFiled(now);
dom.setStatus(Status.SELF);
dom.setStatusChanged(now);
dom.setDnsMaster("dns1.hostsharing.net");
if (dom.getName() == null || dom.getName().length() == 0) {
throw new HSAdminException("domain name required");
}
UnixUser admin = dom.getUser();
if (admin == null || admin.getName() == null || admin.getName().length() == 0) {
throw new HSAdminException("domain admin required");
}
EntityManager em = getTransaction().getEntityManager();
// search for domains superior to dom
Query domainQuery = em.createQuery("SELECT d FROM Domains d WHERE d.name = :domainName");
String superior = dom.getName();
while (superior.contains(".")) {
superior = superior.substring(superior.indexOf('.') + 1);
domainQuery.setParameter("domainName", superior);
if (domainQuery.getResultList().size() > 0) {
DNSCheck dnsCheck = new DNSCheck(dom.getDnsMaster());
if (dnsCheck.checkDomain(dom.getName())) {
break;
} else {
throw new HSAdminException("domain " + dom.getName() + " is not delegated to " + dom.getDnsMaster());
}
}
}
Query adminQuery = em.createQuery("SELECT u FROM UnixUsers u WHERE u.name = :adminName");
adminQuery.setParameter("adminName", admin.getName());
dom.setUser((UnixUser) adminQuery.getSingleResult());
needsWriteAccessOn(newEntity, "add");
// Entity addedEntity = super.add(dom);
// Domain addedDomain = (Domain) addedEntity;
em.persist(dom);
String[] emailAddresses = new String[] { "abuse", "postmaster", "webmaster" };
for (String emailLocalpart : emailAddresses) {
EMailAddress eMailAddress = new EMailAddress(emailLocalpart, "", dom, admin.getName());
em.persist(eMailAddress);
}
return super.add(dom);
}
@Override
public AbstractEntity update(AbstractEntity existingEntity) throws HSAdminException {
Domain dom = (Domain) existingEntity;
if (dom.getName() == null || dom.getName().length() == 0) {
throw new HSAdminException("domain name required");
}
UnixUser admin = dom.getUser();
if (admin == null || admin.getName() == null || admin.getName().length() == 0) {
throw new HSAdminException("domain admin required");
}
if (admin.getPac() == null) {
EntityManager em = getTransaction().getEntityManager();
Query query = em.createQuery("SELECT u FROM UnixUsers u WHERE u.name = :adminName");
query.setParameter("adminName", admin.getName());
dom.setUser((UnixUser) query.getSingleResult());
}
needsWriteAccessOn(existingEntity, "update");
throw new AuthorisationException(getLoginUser(), "update", existingEntity);
}
@Override
public void delete(AbstractEntity existingEntity) throws HSAdminException {
needsWriteAccessOn(existingEntity, "delete");
Domain dom = (Domain) existingEntity;
EntityManager em = getTransaction().getEntityManager();
Query query = em.createQuery("SELECT adr FROM " + EMailAddress.class.getAnnotation(javax.persistence.Entity.class).name()
+ " adr WHERE adr.domain.name='" + dom.getName() + "'");
List<?> resultList = query.getResultList();
for (Object obj : resultList) {
EMailAddress eMailAddress = (EMailAddress) obj;
em.remove(eMailAddress);
}
super.delete(existingEntity);
}
private void needsReadAccessOn(AbstractEntity ent, String method) throws AuthorisationException {
if (ent instanceof Domain) {
Domain dom = (Domain) ent;
String aLoginUserName = getLoginUser().getName();
UnixUser domUser = dom.getUser();
Pac domPac = domUser.getPac();
boolean isDomAdmin = aLoginUserName.equals(domUser.getName());
boolean isPacAdmin = aLoginUserName.equals(domPac.getName());
boolean isCustomer = aLoginUserName.equals(domPac.getCustomer().getName());
boolean isHostmaster = getLoginUser().hasHostmasterRole();
if (!isDomAdmin && !isPacAdmin && !isCustomer && !isHostmaster) {
throw new AuthorisationException(getLoginUser(), method, dom);
}
} else {
throw new AuthorisationException(getLoginUser(), method, ent);
}
}
private void needsWriteAccessOn(AbstractEntity ent, String method) throws AuthorisationException {
if (ent instanceof Domain) {
Domain dom = (Domain) ent;
String aLoginUserName = getLoginUser().getName();
UnixUser domUser = dom.getUser();
Pac domPac = domUser.getPac();
boolean isPacAdmin = aLoginUserName.equals(domPac.getName());
boolean isCustomer = aLoginUserName.equals(domPac.getCustomer().getName());
if (!isPacAdmin && !isCustomer)
throw new AuthorisationException(getLoginUser(), method, dom);
} else {
throw new AuthorisationException(getLoginUser(), method, ent);
}
}
}

View File

@ -0,0 +1,207 @@
package de.hsadmin.mods.dom;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.qserv.CompoundProcessor;
import de.hsadmin.core.qserv.CopyFileProcessor;
import de.hsadmin.core.qserv.CreateFileProcessor;
import de.hsadmin.core.qserv.EntityProcessorFactory;
import de.hsadmin.core.qserv.Processor;
import de.hsadmin.core.qserv.ProcessorException;
import de.hsadmin.core.qserv.ShellProcessor;
import de.hsadmin.core.qserv.TemplateProcessor;
import de.hsadmin.core.qserv.WaitingTasksProcessor;
import de.hsadmin.mods.email.EMailAddress;
import de.hsadmin.mods.email.EMailAddressProcessorFactory;
import de.hsadmin.mods.pac.Pac;
import de.hsadmin.mods.user.UnixUser;
public class DomainProcessorFactory implements EntityProcessorFactory {
/**
* @return a Processor which creates a domain
* @throws ProcessorException
*/
public <T extends AbstractEntity> Processor createCreateProcessor(EntityManager em, T entity) throws ProcessorException {
String hiveName = entity.getHiveName();
Domain dom = (Domain) entity;
UnixUser domUser = dom.getUser();
Pac pac = domUser.getPac();
String domName = dom.getName();
String zonefileTargetPath = "/etc/bind/pri." + domName;
Map<String, String> templateVars = new HashMap<String, String>();
templateVars.put("SIO", Long.toString(System.currentTimeMillis()/1000L));
templateVars.put("DOM_HOSTNAME", domName);
templateVars.put("PAC_HOSTNAME", pac.getName() + ".hostsharing.net");
templateVars.put("DOM_IPNUMBER", pac.getCurINetAddr().getInetAddr());
Processor zonefileTemplateProcessor =
new TemplateProcessor("/de/hsadmin/mods/dom/zonefile.jtpl", templateVars, zonefileTargetPath, false);
Processor zonefileACLProcessor =
new ShellProcessor("chown root:bind " + zonefileTargetPath + " && chmod 644 " + zonefileTargetPath);
Processor prizonesFileProcessor =
new ShellProcessor("echo 'zone \"" + domName + "\" { type master; file \"pri." + domName + "\"; };' >>/etc/bind/named.pri-zones" +
" && sort /etc/bind/named.pri-zones | uniq >/etc/bind/named.pri-zones.tmp" +
" && mv /etc/bind/named.pri-zones.tmp /etc/bind/named.pri-zones");
// zone "zweisprech.de" { type slave; file "sec.zweisprech.de"; masters { 83.223.95.31; }; };
String hiveInetAddr = pac.getHive().getInetAddr().getInetAddr();
Processor smtpTransportsProcessor =
new ShellProcessor("echo " + domName + " >> /etc/postfix/relaydomains" +
" && invoke-rc.d postfix reload");
Processor dnsReloadProcessor =
new ShellProcessor("invoke-rc.d bind9 reload");
EMailAddressProcessorFactory eMailAddressProcessorFactory = new EMailAddressProcessorFactory();
Processor dnsSetupProcessor =
new CompoundProcessor(zonefileTemplateProcessor, zonefileACLProcessor, prizonesFileProcessor, dnsReloadProcessor);
WaitingTasksProcessor mainProcessor = new WaitingTasksProcessor(dnsSetupProcessor);
CompoundProcessor emailAdrProcessor = new CompoundProcessor();
Query query = em.createQuery("SELECT adr FROM " + EMailAddress.class.getAnnotation(javax.persistence.Entity.class).name()
+ " adr WHERE adr.domain.name='" + domName + "'");
List<?> resultList = query.getResultList();
for (Object obj : resultList) {
EMailAddress eMailAddress = (EMailAddress) obj;
emailAdrProcessor.appendProcessor(eMailAddressProcessorFactory.createCreateProcessor(em, eMailAddress));
}
mainProcessor.appendProcessor(hiveName, emailAdrProcessor, "Setup EMail");
Processor seczonesFileProcessor = null;
String[] dnsServerQueues = { "dns1", "dns2", "dns3" };
for (String queueName : dnsServerQueues) {
seczonesFileProcessor =
new ShellProcessor("echo 'zone \"" + domName + "\" { type slave; file \"sec." + domName + "\"; masters { " + hiveInetAddr + "; }; };' >>/etc/bind/named-hsh.conf" +
" && sort /etc/bind/named-hsh.conf | uniq >/etc/bind/named-hsh.conf.tmp" +
" && mv /etc/bind/named-hsh.conf.tmp /etc/bind/named-hsh.conf" +
" && invoke-rc.d bind9 reload");
mainProcessor.appendProcessor(queueName, seczonesFileProcessor, queueName + ".hostsharing.net");
}
Processor relayDomainsProcessor = null;
String[] mailServerQueues = { "mail1", "mail2", "mail3" };
for (String queueName : mailServerQueues) {
relayDomainsProcessor = new ShellProcessor("postmap -r -i /etc/postfix/relaydomains", domName + " anything");
mainProcessor.appendProcessor(queueName, relayDomainsProcessor, queueName + ".hostsharing.net");
}
mainProcessor.appendProcessor("backupmx", smtpTransportsProcessor, "backupmx.hostsharing.net");
String domsDir = domUser.getHomedir() + "/doms";
String domainDir = domsDir + "/" + dom.getName();
String[] subDirs = new String[] { "htdocs", "htdocs-ssl", "subs", "subs/www", "subs-ssl", "subs-ssl/www", "cgi", "fastcgi", "cgi-ssl", "fastcgi-ssl", "etc", "var" };
String pacName = pac.getName();
String userName = domUser.getName();
Processor mkDomainDirProzessor =
new ShellProcessor(
"mkdir --mode=1550 --parents " + domsDir + " && " +
"chown httpd:" + pacName + " " + domsDir + " && " +
"mkdir --mode=750 " + domainDir + " && " +
"chown " + userName + ":httpd " + domainDir
);
CompoundProcessor domDirsProcessor = new CompoundProcessor(mkDomainDirProzessor);
for (String subDir : subDirs) {
domDirsProcessor.appendProcessor(new ShellProcessor(
"mkdir --mode=755 " + domainDir + "/" + subDir + " && " +
"chown " + userName + ":" + pacName + " " + domainDir + "/" + subDir
));
}
templateVars = new HashMap<String, String>();
templateVars.put("DOMAIN", domName);
templateVars.put("USER_NAME", domUser.getComment());
domDirsProcessor.appendProcessor(
new CreateFileProcessor("/de/hsadmin/mods/dom/htaccess.jtpl", templateVars, domainDir + "/htdocs/.htaccess", userName, pacName, "644")
);
domDirsProcessor.appendProcessor(
new CreateFileProcessor("/de/hsadmin/mods/dom/htaccess.jtpl", templateVars, domainDir + "/htdocs-ssl/.htaccess", userName, pacName, "644")
);
domDirsProcessor.appendProcessor(
new CreateFileProcessor("/de/hsadmin/mods/dom/index.html.jtpl", templateVars, domainDir + "/subs/www/index.html", userName, pacName, "644")
);
domDirsProcessor.appendProcessor(
new CreateFileProcessor("/de/hsadmin/mods/dom/index.html.jtpl", templateVars, domainDir + "/subs-ssl/www/index.html", userName, pacName, "644")
);
domDirsProcessor.appendProcessor(
new CreateFileProcessor("/de/hsadmin/mods/dom/test.cgi.jtpl", templateVars, domainDir + "/cgi/test.cgi", userName, pacName, "755")
);
domDirsProcessor.appendProcessor(
new CreateFileProcessor("/de/hsadmin/mods/dom/test.cgi.jtpl", templateVars, domainDir + "/cgi-ssl/test.cgi", userName, pacName, "755")
);
domDirsProcessor.appendProcessor(
new CopyFileProcessor("/usr/local/src/phpstub/phpstub", domainDir + "/fastcgi/phpstub", userName, pacName, "755")
);
domDirsProcessor.appendProcessor(
new CopyFileProcessor("/usr/local/src/phpstub/phpstub", domainDir + "/fastcgi-ssl/phpstub", userName, pacName, "755")
);
domDirsProcessor.appendProcessor(
new ShellProcessor("ln -s " + domainDir + " /home/doms/ && " +
"chown --no-dereference " + userName + ":" + pacName + " /home/doms/" + domName
+ " && " + "chown " + userName + ":httpd /home/doms/" + domName + "/")
);
mainProcessor.appendProcessor(hiveName, domDirsProcessor, "Setup doms/" + domName + "-Directory");
Processor domSetupProcessor =
new ShellProcessor("mk-httpd-conf " + pacName + " && invoke-rc.d apache2 reload >/dev/null 2>&1");
mainProcessor.appendProcessor(hiveName, domSetupProcessor, "Setup Apache VHost");
return mainProcessor;
}
/**
* @return a Processor which updates a domain
*/
public <T extends AbstractEntity> Processor createUpdateProcessor(EntityManager em, T entity) {
return null;
}
/**
* @return a Processor which deletes a domain
*/
public <T extends AbstractEntity> Processor createDeleteProcessor(EntityManager em, T entity) {
Domain dom = (Domain) entity;
String domName = dom.getName();
ShellProcessor emailAddressRemoveProcessor = new ShellProcessor("for KEY in $(postmap -s /etc/postfix/virtual|grep " + domName + "|cut -f1); do postmap -d $KEY /etc/postfix/virtual; done");
ShellProcessor dnsRemoveRemoveProcessor =
new ShellProcessor("grep -v pri." + domName + " /etc/bind/named.pri-zones > /etc/bind/named.pri-zones.tmp" +
" && mv /etc/bind/named.pri-zones.tmp /etc/bind/named.pri-zones" +
" && rm /etc/bind/pri." + domName +
" && invoke-rc.d bind9 reload");
WaitingTasksProcessor mainProcessor = new WaitingTasksProcessor(new CompoundProcessor(emailAddressRemoveProcessor, dnsRemoveRemoveProcessor));
Processor seczonesFileProcessor = null;
String[] dnsQueues = { "dns1", "dns2", "dns3" };
for (String queueName : dnsQueues) {
seczonesFileProcessor =
new ShellProcessor("grep -v sec." + domName + " /etc/bind/named-hsh.conf >/etc/bind/named-hsh.conf.tmp" +
" && mv /etc/bind/named-hsh.conf.tmp /etc/bind/named-hsh.conf" +
" && rm /var/cache/bind/sec." + domName +
" && invoke-rc.d bind9 reload");
mainProcessor.appendProcessor(queueName, seczonesFileProcessor, queueName + ".hostsharing.net");
}
Processor mailQueueProcessor = null;
String[] mailServerQueues = { "mail1", "mail2", "mail3" };
for (String queueName : mailServerQueues) {
mailQueueProcessor = new ShellProcessor("postmap -d '" + domName + "' /etc/postfix/relaydomains");
mainProcessor.appendProcessor(queueName, mailQueueProcessor, queueName + ".hostsharing.net");
}
Processor vhostDelProcessor =
new ShellProcessor("rm /home/doms/" + domName +
" && rm -rf " + dom.getUser().getHomedir() + "/doms/" + domName +
" && rm /etc/apache2/sites-generated/" + domName +
" && rm /etc/apache2/sites-*/`ls -1 /etc/apache2/sites-enabled/ | egrep \"^[01]+-" + domName + "$\"`" +
" && invoke-rc.d apache2 reload >/dev/null 2>&1");
mainProcessor.appendProcessor(dom.getHiveName(), vhostDelProcessor, "remove apache vhost");
Processor smtpRelayDelProcessor =
new ShellProcessor("grep -v " + domName + " /etc/postfix/relaydomains > /etc/postfix/relaydomains.tmp" +
" && mv /etc/postfix/relaydomains.tmp /etc/postfix/relaydomains" +
" && invoke-rc.d postfix reload");
mainProcessor.appendProcessor("backupmx", smtpRelayDelProcessor, "backupmx.hostsharing.net");
return mainProcessor;
}
}

View File

@ -0,0 +1,2 @@
<!-- BEGIN: main -->Redirect permanent / http://www.{DOMAIN}/
<!-- END: main -->

View File

@ -0,0 +1,22 @@
<!-- BEGIN: main --><html>
<head>
<title>Willkommen bei {DOMAIN}</title>
</head>
<body bgcolor="orange">
<h1>Willkommen bei {DOMAIN}</h1>
<p>Diese neue Website wurde gerade bei der
<a href="http://www.hostsharing.net">Hostsharing eG</a>
f&uuml;r {USER_NAME} eingerichtet. </p>
<p>Der Inhaber der Domain ist bereits per Email unter
<a href="mailto:webmaster(at){DOMAIN}">webmaster(at){DOMAIN}</a>
zu erreichen. </p>
</body>
</html>
<!-- END: main -->

View File

@ -0,0 +1,5 @@
<!-- BEGIN: main -->#!/bin/sh
echo Content-type: text/plain
echo
echo Hello, world
<!-- END: main -->

View File

@ -0,0 +1,29 @@
<!-- BEGIN: main -->; default - generated by hsadmin
$TTL 4H
{DOM_HOSTNAME}. IN SOA dns1.hostsharing.net. hostmaster.hostsharing.net. (
{SIO} ; serial secs since Jan 1 1970
6H ; refresh (>=10000)
1H ; retry (>=1800)
1W ; expire
1H ; minimum
)
; please read http://www.hostsharing.net/tech/descriptions/domains-zonefile.htm
IN NS dns1.hostsharing.net.
IN NS dns2.hostsharing.net.
IN NS dns3.hostsharing.net.
IN MX 30 {PAC_HOSTNAME}.
IN MX 80 backupmx.hostsharing.net.
IN A {DOM_IPNUMBER}
www IN A {DOM_IPNUMBER}
ftp IN A {DOM_IPNUMBER}
pop3 IN A {DOM_IPNUMBER}
mail IN A {DOM_IPNUMBER}
mysql IN A {DOM_IPNUMBER}
pgsql IN A {DOM_IPNUMBER}
*.{DOM_HOSTNAME}. IN A {DOM_IPNUMBER}
<!-- END: main -->

View File

@ -0,0 +1,208 @@
package de.hsadmin.mods.email;
import static javax.persistence.FetchType.EAGER;
import static javax.persistence.GenerationType.SEQUENCE;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.EntityInfo;
import de.hsadmin.core.model.HSAdminException;
import de.hsadmin.core.model.SearchFilter;
import de.hsadmin.mods.dom.Domain;
import de.hsadmin.mods.user.UnixUser;
/**
* Entity class for email addresses.
*/
@Entity(name = "EMailAddresses")
@Table(name = "emailaddr")
@SequenceGenerator(name = "EMailAddressesSeqGen", sequenceName = "emailaddr_emailaddr_id_seq")
@EntityInfo(name = "E-Mail-Adresse")
@SearchFilter("domain.user = :loginUser OR "
+ "domain.user.pac = :loginUserPac OR "
+ "domain.user.pac.customer.name = :loginUserName")
public class EMailAddress extends AbstractEntity implements Serializable {
private static final long serialVersionUID = -2265500181746604429L;
@Id
@GeneratedValue(strategy = SEQUENCE, generator = "EMailAddressesSeqGen")
@Column(name = "emailaddr_id", columnDefinition = "integer")
private long id;
@Column(name = "localpart", updatable = false, nullable= false)
private String localpart = "";
@Column(name = "subdomain")
private String subdomain;
@ManyToOne(fetch = EAGER)
@JoinColumn(name = "domain_id", columnDefinition = "integer", updatable = false)
private Domain domain;
@Column(name = "target", nullable= false)
private String target;
public EMailAddress() {
}
public EMailAddress(String localPart, String subdomain, Domain domain,
String target) {
this.localpart = localPart;
this.subdomain = subdomain;
this.domain = domain;
this.target = target;
}
public static String createQueryFromStringKey(String humanKey) throws HSAdminException {
String[] parts = humanKey.split("@", 2);
if (parts.length != 2) {
throw new HSAdminException("error in oid: " + humanKey);
}
String[] doms = parts[1].split("\\.");
StringBuilder query = new StringBuilder("localpart='" + parts[0]
+ "' AND ( ( subdomain IS NULL AND domain.name='" + parts[1]
+ "' )");
for (int subdomLevel = 1; subdomLevel < doms.length - 1; ++subdomLevel) {
String subdom = "";
for (int n = 0; n < subdomLevel; ++n)
subdom += "." + doms[n];
String domain = "";
for (int n = subdomLevel; n < doms.length; ++n)
domain += "." + doms[n];
query.append(" OR ( subdomain='" + subdom.substring(1)
+ "' AND domain.name='" + domain.substring(1) + "' )");
}
query.append(" )");
String queryString = query.toString();
return queryString;
}
@Override
public String createStringKey() {
String key = getDomain() != null ? (getLocalPart() + "@" + getFullDomain())
: "?@?";
return key;
}
@Override
public long id() {
return id;
}
public long getId() {
return id;
}
protected void setId(long id) {
this.id = id;
}
public String getLocalPart() {
return localpart == null ? "" : localpart;
}
public void setLocalPart(String localPart) {
this.localpart = trimToEmpty(localPart);
}
public String getSubdomain() {
return subdomain == null || subdomain.length() == 0 ? null : subdomain;
}
public void setSubdomain(String subdomain) {
this.subdomain = trimToNull(subdomain);
}
public Domain getDomain() {
return domain;
}
public void setDomain(Domain domain) {
this.domain = domain;
}
public String getTarget() {
return target;
}
public void setTarget(String target) {
this.target = trim(target);
}
@Transient
public String getEMailAddress() {
return createStringKey();
}
/**
* returns the full domain (subdomain + domain)
*/
@Transient
public String getFullDomain() {
return (getSubdomain() == null ? "" : (getSubdomain() + "."))
+ getDomain().getName();
}
public String toString() {
if (localpart != null && target != null)
return super.toString() + "{ id=" + id + "; address=" + localpart
+ subdomain + "; target=" + target + " }";
else
return super.toString();
}
@Override
public boolean isNew() {
return id == 0;
}
@Override
public String getHiveName() {
if (isNew())
return null;
else
return getDomain().getUser().getHiveName();
}
@Override
public UnixUser owningUser(EntityManager em) {
return domain.owningUser(em);
}
@Override
public boolean isReadAllowedFor(UnixUser loginUser) {
return getDomain().isReadAllowedFor(loginUser);
}
@Override
public boolean isWriteAllowedFor(UnixUser loginUser) {
return getDomain().isWriteAllowedFor(loginUser);
}
/**
* query restriction for this Entity
*/
public static String restriction() {
return "( " +
// domain-owner?
"obj.domain.user = :loginUser OR " +
// pac-admin? (TODO: Hostsharing name convention)
"obj.domain.user.pac.name = :loginUserName OR " +
// customer
"obj.domain.user.pac.customer.name = :loginUserName )";
}
}

View File

@ -0,0 +1,75 @@
package de.hsadmin.mods.email;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import de.hsadmin.core.model.AbstractModuleImpl;
import de.hsadmin.core.model.AuthorisationException;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.HSAdminException;
import de.hsadmin.mods.dom.Domain;
public class EMailAddressModuleImpl extends AbstractModuleImpl {
@Override
public List<AbstractEntity> search(Class<? extends AbstractEntity> entityClass,
String condition, String orderBy) throws HSAdminException {
if (orderBy == null || orderBy.length() == 0) {
orderBy = "ORDER BY obj.domain.name ASC, obj.subdomain ASC, obj.localpart ASC";
}
return super.search(entityClass, condition, orderBy);
}
@Override
public AbstractEntity add(AbstractEntity newEntity) throws HSAdminException {
EntityManager em = getTransaction().getEntityManager();
EMailAddress adr = (EMailAddress) newEntity;
if (adr.getTarget() == null || adr.getTarget().length() == 0) {
throw new HSAdminException("target required");
}
if (adr.getLocalPart() == null) {
adr.setLocalPart("");
}
if (adr.getDomain() == null
|| adr.getDomain().getName() == null
|| adr.getDomain().getName().length() == 0) {
throw new HSAdminException("domain required");
}
Query qDomain = em.createQuery("SELECT d FROM Domains d WHERE d.name = :domName");
qDomain.setParameter("domName", adr.getDomain().getName());
Domain dom = (Domain) qDomain.getSingleResult();
adr.setDomain(dom);
return super.add(newEntity);
}
@Override
public AbstractEntity update(AbstractEntity existingEntity) throws HSAdminException {
EMailAddress detachedAddr = (EMailAddress) existingEntity;
EntityManager em = getTransaction().getEntityManager();
EMailAddress attachedAddr = em.find(EMailAddress.class, detachedAddr.getId());
Domain domain = detachedAddr.getDomain();
if (domain != null && domain.getId() != attachedAddr.getDomain().getId()) {
detachedAddr.setDomain(attachedAddr.getDomain());
throw new AuthorisationException(getLoginUser(), "update", detachedAddr, "domain");
}
String subdomain = detachedAddr.getSubdomain();
if (subdomain != null && !subdomain.equals(attachedAddr.getSubdomain())) {
detachedAddr.setSubdomain(attachedAddr.getSubdomain());
throw new AuthorisationException(getLoginUser(), "update", detachedAddr, "subdomain");
}
String localPart = detachedAddr.getLocalPart();
if (localPart != null && !localPart.equals(attachedAddr.getLocalPart())) {
detachedAddr.setLocalPart(attachedAddr.getLocalPart());
throw new AuthorisationException(getLoginUser(), "update", detachedAddr, "localpart");
}
String target = detachedAddr.getTarget();
if (target == null) {
throw new HSAdminException("target required");
}
attachedAddr.setTarget(target);
return super.update(attachedAddr);
}
}

View File

@ -0,0 +1,70 @@
package de.hsadmin.mods.email;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.qserv.CompoundProcessor;
import de.hsadmin.core.qserv.EntityProcessorFactory;
import de.hsadmin.core.qserv.Processor;
import de.hsadmin.core.qserv.ShellProcessor;
/**
* System level implementation for EMailAdress module.
*/
public class EMailAddressProcessorFactory implements EntityProcessorFactory {
/**
* @return a Processor which creates an email address
*/
public <T extends AbstractEntity> Processor createCreateProcessor(EntityManager em, T entity) {
// TODO: combine both keys in a single call (optimization)
EMailAddress email = (EMailAddress) entity;
CompoundProcessor cp = new CompoundProcessor();
cp.appendProcessor(new ShellProcessor( "postmap -r -i /etc/postfix/virtual",
email.getFullDomain() + " -" ) );
cp.appendProcessor(new ShellProcessor( "postmap -r -i /etc/postfix/virtual",
email.getEMailAddress() + " " + email.getTarget() ) );
return cp;
}
/**
* @return a Processor which updates an email address
*/
public <T extends AbstractEntity> Processor createUpdateProcessor(EntityManager em, T entity) {
// TODO: if update is specified by primary-key or DB query instead of OID,
// a postmap -d might be neccessary
return createCreateProcessor(em, entity);
}
/**
* @return a Processor which deletes an email address
*/
public <T extends AbstractEntity> Processor createDeleteProcessor(EntityManager em, T entity) {
// TODO: combine both keys in a single call (optimization)
// remove the entry itself
CompoundProcessor cp = new CompoundProcessor();
EMailAddress email = (EMailAddress) entity;
cp.appendProcessor(
new ShellProcessor( "postmap -d '" + email.getEMailAddress() + "' /etc/postfix/virtual" ) );
// any other email addresses for this domain?
Query query;
if ( email.getSubdomain() != null ) {
query = em.createQuery("SELECT e FROM EMailAddresses e WHERE e.subdomain=:subdomain AND e.domain=:domain");
query.setParameter("subdomain", email.getSubdomain());
}
else {
query = em.createQuery("SELECT e FROM EMailAddresses e WHERE e.subdomain IS NULL AND e.domain=:domain");
}
query.setParameter("domain", email.getDomain());
List<?> result = query.getResultList();
if ( result == null || result.size() == 0 ) {
// remove the domain from virtual.db
cp.appendProcessor(
new ShellProcessor( "postmap -d '" + email.getFullDomain() + "' /etc/postfix/virtual" ) );
}
return cp;
}
}

View File

@ -0,0 +1,200 @@
package de.hsadmin.mods.email;
import static javax.persistence.GenerationType.SEQUENCE;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.EntityManager;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import de.hsadmin.core.model.AbstractModuleImpl;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.EntityInfo;
import de.hsadmin.core.model.SearchFilter;
import de.hsadmin.mods.pac.Pac;
import de.hsadmin.mods.user.UnixUser;
/**
* Entity class for email aliases.
*
*/
@javax.persistence.Entity(name = "EMailAliases")
@Table(name = "emailalias")
@SequenceGenerator(name = "EMailAliasesSeqGen", sequenceName = "emailalias_emailalias_id_seq")
@EntityInfo(name = "E-Mail-Alias")
@SearchFilter("pac = :loginUserPac OR "
+ "pac.customer.name = :loginUserName")
public class EMailAlias extends AbstractEntity implements Serializable {
private static final long serialVersionUID = -4711415079723587161L;
@Id
@GeneratedValue(strategy = SEQUENCE, generator = "EMailAliasesSeqGen")
@Column(name = "emailalias_id", columnDefinition = "integer", insertable=false, updatable=false)
private long id;
@ManyToOne()
@JoinColumn(name = "pac_id", columnDefinition = "integer")
private Pac pac;
@Column(updatable=false)
private String name;
@Column
private String target;
public EMailAlias() {
}
public EMailAlias(Pac pac, String name, String target) {
this.pac = pac;
this.name = name;
this.target = target;
}
@Override
public void initialize(EntityManager em, UnixUser loginUser) {
pac = loginUser.getPac();
name = pac.getName() + "-";
target = "";
}
@Override
public void complete(EntityManager em, UnixUser loginUser) {
if (pac == null && name != null && name.length() > 0) {
// TODO: it's ugly having this code here, needs refactoring
String pacName = name.substring(0, 5);
try {
// get the entities name (query part from FROM to WHERE)
javax.persistence.Entity entityAnnot = Pac.class
.getAnnotation(javax.persistence.Entity.class);
String queryString = "FROM " + entityAnnot.name() + " WHERE "
+ Pac.createQueryFromStringKey(pacName);
// set parameters
Query query = em.createQuery(queryString);
AbstractModuleImpl.setQueryParameter(query, queryString,
"loginUser", loginUser);
AbstractModuleImpl.setQueryParameter(query, queryString,
"loginUserName", loginUser.getName());
AbstractModuleImpl.setQueryParameter(query, queryString,
"loginUserPac", loginUser.getPac());
pac = (Pac) query.getSingleResult();
} catch (NoResultException exc) {
throw new SecurityException("packet '" + pacName
+ "' not found or access denied");
}
}
}
public static String createQueryFromStringKey(String humanKey) {
return "name='" + humanKey + "'";
}
@Override
public String createStringKey() {
return name;
}
@Override
public long id() {
return id;
}
public long getId() {
return id;
}
protected void setId(long id) {
this.id = id;
}
public Pac getPac() {
return pac;
}
public void setPac(Pac pac) {
this.pac = pac;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTarget() {
return target;
}
public void setTarget(String target) {
this.target = target;
}
@Override
public boolean isNew() {
return id == 0;
}
@Override
public String getHiveName() {
if (isNew())
return null;
else
return getPac().getHiveName();
}
@Override
public UnixUser owningUser(EntityManager em) {
return pac.owningUser(em);
}
public AbstractEntity merge(EntityManager em, UnixUser loginUser) {
EMailAlias attachedEntity = em.find(getClass(), id());
Pac attachedPacket = attachedEntity.getPac();
if (pac.getId() != attachedPacket.getId())
throw new SecurityException(
"changing the Packet of an EMailAlias is not allowed");
if (!name.equals(attachedPacket.getName())
&& !name.startsWith(attachedPacket.getName() + "-"))
throw new SecurityException(
"changing the Packet of an EMailAlias is not allowed");
attachedEntity.setName(name);
attachedEntity.setTarget(target);
return attachedEntity;
}
@Override
public boolean isReadAllowedFor(UnixUser loginUser) {
return loginUser.hasPacAdminRoleFor(getPac());
}
@Override
public boolean isWriteAllowedFor(UnixUser loginUser) {
String pacName = pac.getName();
if (!name.equals(pacName) && !name.startsWith(pacName + "-"))
return false;
return loginUser.hasPacAdminRoleFor(getPac());
}
public static String restriction() {
return
// all aliases of all pacs of customer
"pac.customer.name=:loginUserName OR " +
// all aliases of packet admin
"pac.name=:loginUserName";
}
}

View File

@ -0,0 +1,20 @@
package de.hsadmin.mods.email;
import java.util.List;
import de.hsadmin.core.model.AbstractModuleImpl;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.model.HSAdminException;
public class EMailAliasModuleImpl extends AbstractModuleImpl {
@Override
public List<AbstractEntity> search(Class<? extends AbstractEntity> entityClass,
String condition, String orderBy) throws HSAdminException {
if (orderBy == null || orderBy.length() == 0) {
orderBy = "ORDER BY name ASC";
}
return super.search(entityClass, condition, orderBy);
}
}

View File

@ -0,0 +1,46 @@
package de.hsadmin.mods.email;
import javax.persistence.EntityManager;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.core.qserv.EntityProcessorFactory;
import de.hsadmin.core.qserv.Processor;
import de.hsadmin.core.qserv.ShellProcessor;
/**
* System level implementation for EMailAlias module.
*/
public class EMailAliasProcessorFactory implements EntityProcessorFactory {
// TODO: execution of any of these processors needs to be synchronized
/**
* @return a Processor which creates an email alias
*/
public <T extends AbstractEntity> Processor createCreateProcessor(EntityManager em,
T entity) {
EMailAlias alias = (EMailAlias) entity;
return new ShellProcessor("postalias -r -i /etc/postfix/aliases",
alias.getName() + ": " + alias.getTarget());
}
/**
* @return a Processor which updates an email alias
*/
public <T extends AbstractEntity> Processor createUpdateProcessor(EntityManager em,
T entity) {
EMailAlias alias = (EMailAlias) entity;
return new ShellProcessor("postalias -r -i /etc/postfix/aliases",
alias.getName() + ": " + alias.getTarget());
}
/**
* @return a Processor which deletes an email alias
*/
public <T extends AbstractEntity> Processor createDeleteProcessor(EntityManager em,
T entity) {
EMailAlias alias = (EMailAlias) entity;
return new ShellProcessor(
"postalias -d '" + alias.getName() + "' /etc/postfix/aliases");
}
}

View File

@ -99,10 +99,14 @@ public class UnixUserModuleImpl extends AbstractModuleImpl {
}
if (passWord.indexOf(':') >= 0) {
throw new AuthorisationException(getLoginUser(), "add", newUnixUser, "userId");
}
if (newUnixUser.getPac() == null || newUnixUser.getPac().getNew()) {
}
Query qPac = em.createQuery("SELECT obj FROM Pacs obj WHERE obj.name = :pacName");
qPac.setParameter("pacName", userName.substring(0, 5));
Pac pac = (Pac) qPac.getSingleResult();
Object singleResult = qPac.getSingleResult();
Pac pac = (Pac) singleResult;
newUnixUser.setName(userName);
newUnixUser.setHomedir("/home/pacs/" + userName.substring(0, 5) + "/users/" + userName.substring(6));
@ -138,10 +142,6 @@ public class UnixUserModuleImpl extends AbstractModuleImpl {
return super.add(newEntity);
}
private EntityManager getEntityManager() {
return getTransaction().getEntityManager();
}
@Override
public AbstractEntity update(AbstractEntity existingEntity) throws HSAdminException {
// get the entity from the database
@ -218,6 +218,10 @@ public class UnixUserModuleImpl extends AbstractModuleImpl {
super.delete(attachedUnixUser);
}
private EntityManager getEntityManager() {
return getTransaction().getEntityManager();
}
// throws an AuthorisationException if the login user has no write acess
// on the pac of the given UnixUser
private boolean hasFullAccessOnPacOf(UnixUser user) {

View File

@ -150,7 +150,7 @@ public abstract class AbstractRemote implements IRemote {
"better safe than sorry: no where parameter found");
}
List<AbstractEntity> list = module.search(getEntityClass(),
queryCondition, "ORDER BY obj.name ASC");
queryCondition, getOrderBy());
transaction.beginTransaction();
for (AbstractEntity update : list) {
if (update.isWriteAllowedFor(unixUser)) {
@ -178,6 +178,10 @@ public abstract class AbstractRemote implements IRemote {
}
}
public String getOrderBy() {
return "ORDER BY obj.name ASC";
}
protected boolean assertNotNull(String string) {
return string != null && string.length() > 0;
}

View File

@ -94,6 +94,10 @@ public class CustomerRemote extends AbstractRemote {
if (assertNotNull(memberCode)) {
cust.setName(memberCode);
}
String password = setParams.get("password");
if (assertNotNull(password)) {
cust.setPassword(password);
}
String memberNo = setParams.get("memberno");
if (assertNotNull(memberNo)) {
cust.setMemberNo(Integer.parseInt(memberNo));

View File

@ -0,0 +1,63 @@
package de.hsadmin.remote;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.mods.dom.Domain;
import de.hsadmin.mods.user.UnixUser;
public class DomainRemote extends AbstractRemote {
private static final DateFormat df = SimpleDateFormat.getDateInstance(DateFormat.SHORT);
@Override
protected Class<? extends AbstractEntity> getEntityClass() {
return Domain.class;
}
@Override
protected void entity2map(AbstractEntity entity, Map<String, String> resultMap) {
Domain dom = (Domain) entity;
String id = Long.toString(dom.getId());
resultMap.put("id", id);
String name = dom.getName();
resultMap.put("name", name);
String user = dom.getUser().getName();
resultMap.put("user", user);
String hive = dom.getHiveName();
resultMap.put("hive", hive);
String pac = dom.getUser().getPac().getName();
resultMap.put("pac", pac);
Date sDate = dom.getSince();
if (assertNotNull(sDate)) {
String since = df.format(sDate);
resultMap.put("since", since);
}
}
@Override
protected void map2entity(Map<String, String> setParams, AbstractEntity entity) {
Domain dom = (Domain) entity;
String name = setParams.get("name");
String user = setParams.get("user");
if (assertNotNull(name)) {
dom.setName(name);
}
if (assertNotNull(user)) {
UnixUser u = new UnixUser();
u.setName(user);
dom.setUser(u);
}
}
@Override
protected void regularizeKeys(Map<String, String> whereParams) {
replaceKey(whereParams, "user", "user.name");
replaceKey(whereParams, "pac", "user.pac.name");
replaceKey(whereParams, "hive", "hiveName");
}
}

View File

@ -0,0 +1,74 @@
package de.hsadmin.remote;
import java.util.Map;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.mods.dom.Domain;
import de.hsadmin.mods.email.EMailAddress;
public class EMailAddressRemote extends AbstractRemote {
@Override
protected void entity2map(AbstractEntity entity, Map<String, String> map) {
EMailAddress adr = (EMailAddress) entity;
long id = adr.getId();
String domain = adr.getDomain().getName();
String admin = adr.getDomain().getUser().getName();
String pac = adr.getDomain().getUser().getPac().getName();
String target = adr.getTarget();
String localpart = adr.getLocalPart();
String subdomain = adr.getSubdomain();
String emailaddress = adr.getEMailAddress();
String fulldomain = adr.getFullDomain();
map.put("id", Long.toString(id));
map.put("domain", domain);
map.put("admin", admin);
map.put("pac", pac);
map.put("target", target);
map.put("localpart", localpart);
map.put("subdomain", subdomain);
map.put("emailaddress", emailaddress);
map.put("fulldomain", fulldomain);
}
@Override
protected void map2entity(Map<String, String> map, AbstractEntity entity) {
EMailAddress adr = (EMailAddress) entity;
String localPart = map.get("localpart");
if (assertNotNull(localPart)) {
adr.setLocalPart(localPart);
}
String subdomain = map.get("subdomain");
if (assertNotNull(subdomain)) {
adr.setSubdomain(subdomain);
}
String target = map.get("target");
if (assertNotNull(target)) {
adr.setTarget(target);
}
String domain = map.get("domain");
if (assertNotNull(domain)) {
Domain dom = new Domain();
dom.setName(domain);
adr.setDomain(dom);
}
}
@Override
protected Class<? extends AbstractEntity> getEntityClass() {
return EMailAddress.class;
}
@Override
protected void regularizeKeys(Map<String, String> whereParams) {
replaceKey(whereParams, "domain", "domain.name");
replaceKey(whereParams, "pac", "domain.user.pac.name");
replaceKey(whereParams, "admin", "domain.user.name");
}
@Override
public String getOrderBy() {
return "ORDER BY obj.domain.name ASC, obj.subdomain ASC, obj.localpart ASC";
}
}

View File

@ -0,0 +1,46 @@
package de.hsadmin.remote;
import java.util.Map;
import de.hsadmin.core.model.AbstractEntity;
import de.hsadmin.mods.email.EMailAlias;
public class EMailAliasRemote extends AbstractRemote {
@Override
protected void entity2map(AbstractEntity entity, Map<String, String> map) {
EMailAlias alias = (EMailAlias) entity;
String id = Long.toString(alias.getId());
String name = alias.getName();
String pac = alias.getPac().getName();
String target = alias.getTarget();
map.put("id", id);
map.put("name", name);
map.put("pac", pac);
map.put("target", target);
}
@Override
protected Class<? extends AbstractEntity> getEntityClass() {
return EMailAlias.class;
}
@Override
protected void map2entity(Map<String, String> map, AbstractEntity entity) {
EMailAlias alias = (EMailAlias) entity;
String name = map.get("name");
String target = map.get("target");
if (assertNotNull(name)) {
alias.setName(name);
}
if (assertNotNull(target)) {
alias.setTarget(target);
}
}
@Override
protected void regularizeKeys(Map<String, String> whereParams) {
replaceKey(whereParams, "pac", "pac.name");
}
}

View File

@ -1,3 +1,6 @@
member=de.hsadmin.remote.CustomerRemote
user=de.hsadmin.remote.UnixUserRemote
domain=de.hsadmin.remote.DomainRemote
emailalias=de.hsadmin.remote.EMailAliasRemote
emailaddress=de.hsadmin.remote.EMailAddressRemote
q=de.hsadmin.remote.QueueTaskRemote

View File

@ -44,12 +44,13 @@ public class CustomerTest {
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> setParams = new HashMap<String, String>();
setParams.put("membercode", "hsh00-aaa");
setParams.put("password", "geheimnIs");
setParams.put("memberno", "20001");
setParams.put("membersince", "01.10.2010");
setParams.put("contact_salut", "Herr");
setParams.put("contact_title", "Dr.");
setParams.put("contact_firstname", "Rainer");
setParams.put("contact_lastname", "Mustermann");
setParams.put("contact_firstname", "Ömer Günther");
setParams.put("contact_lastname", "Janßen-Müller");
setParams.put("contact_salut", "Herr");
setParams.put("contact_street", "Hauptstr. 1");
setParams.put("contact_zipcode", "99998");
@ -58,7 +59,7 @@ public class CustomerTest {
setParams.put("contact_phone_private", "+49 9999 123456");
setParams.put("contact_email", "rainer.mustermann@example.org");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
setParams };
try {
client.execute(MODULE + ".add", params);
@ -77,7 +78,7 @@ public class CustomerTest {
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
try {
Object execute = client.execute(MODULE + ".search", params);
@ -94,7 +95,7 @@ public class CustomerTest {
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
try {
Object execute = client.execute(MODULE + ".search", params);
@ -111,7 +112,7 @@ public class CustomerTest {
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
try {
Object execute = client.execute(MODULE + ".search", params);
@ -128,7 +129,7 @@ public class CustomerTest {
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
try {
Object execute = client.execute(MODULE + ".search", params);
@ -140,25 +141,57 @@ public class CustomerTest {
}
@Test
public void testDeleteAsMember() {
public void testUpdateAsMember() {
String user = "hsh00-aaa";
int membersCount = -9999;
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
Map<String, String> setParams = new HashMap<String, String>();
whereParams.put("membercode", "hsh00-aaa");
setParams.put("contact_firstname", "Hugo");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
setParams, whereParams };
try {
membersCount = getMembersCount(user);
client.execute(MODULE + ".update", params);
fail("exception erwartet");
} catch (XmlRpcException e) {
// Exception erwartet
}
}
@Test
public void testUpdateAsHostmaster() {
String user = "pe";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
Map<String, String> setParams = new HashMap<String, String>();
whereParams.put("membercode", "hsh00-aaa");
setParams.put("contact_title", "Prof.");
setParams.put("membersince", "Hugo");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
setParams, whereParams };
try {
client.execute(MODULE + ".update", params);
} catch (XmlRpcException e) {
fail(e.getMessage());
}
}
@Test
public void testDeleteAsMember() {
String user = "hsh00-aaa";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
whereParams.put("membercode", "hsh00-aaa");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
try {
client.execute(MODULE + ".delete", params);
assertEquals(membersCount - 1, getMembersCount(user));
fail("exception erwartet");
} catch (XmlRpcException e) {
fail(e.getMessage());
// Exception erwartet
}
}
@ -175,7 +208,7 @@ public class CustomerTest {
Map<String, String> whereParams = new HashMap<String, String>();
whereParams.put("membercode", "hsh00-aaa");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
try {
client.execute(MODULE + ".delete", params);
@ -189,7 +222,7 @@ public class CustomerTest {
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
Object execute = client.execute(MODULE + ".search", params);
Object[] result = (Object[]) execute;

View File

@ -0,0 +1,140 @@
package de.hsadmin.remote;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.HashMap;
import java.util.Map;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class DomainTest {
private static final String MODULE = "domain";
private XmlRpcClient client;
private RemoteCASHelper cas;
@Before
public void setUp() throws Exception {
client = RemoteTestHelper.getClient();
cas = new RemoteCASHelper();
}
@After
public void tearDown() throws Exception {
client = null;
cas = null;
}
@Test
public void testSearchAllAsPacAdmin() {
String user = "peh00";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
try {
Object execute = client.execute(MODULE + ".search", params);
Object[] result = (Object[]) execute;
assertEquals(36, result.length);
for (Object o : result) {
if (o instanceof Map<?, ?>) {
Map<?, ?> row = (Map<?, ?>) o;
assertEquals("peh00", row.get("user"));
} else {
fail("map expected");
}
}
} catch (XmlRpcException e) {
fail(e.getMessage());
}
}
@Test
public void testUpdate() {
String user = "peh00";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> setParams = new HashMap<String, String>();
Map<String, String> whereParams = new HashMap<String, String>();
setParams.put("user", "peh00-phor");
whereParams.put("name", "i2null.de");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
setParams, whereParams };
try {
Object execute = client.execute(MODULE + ".update", params);
assertNotNull(execute);
fail("exception expected");
} catch (XmlRpcException e) {
// System.out.println(e.getMessage());
}
}
@Test
public void testCreate() {
int count = getDomsCount();
String user = "peh00";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> setParams = new HashMap<String, String>();
setParams.put("name", "f6n.de");
setParams.put("user", "peh00");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
setParams };
try {
Object execute = client.execute(MODULE + ".add", params);
assertTrue(execute instanceof Map<?, ?>);
} catch (XmlRpcException e) {
fail(e.getMessage());
}
assertEquals(count + 1, getDomsCount());
}
@Test
public void testDelete() {
int count = getDomsCount();
String user = "peh00";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
whereParams.put("name", "f6n.de");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
try {
Object execute = client.execute(MODULE + ".delete", params);
assertNull(execute);
} catch (XmlRpcException e) {
fail(e.getMessage());
}
assertEquals(count - 1, getDomsCount());
}
private int getDomsCount() {
int count = 0;
String user = "peh00";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
try {
Object execute = client.execute(MODULE + ".search", params);
Object[] result = (Object[]) execute;
count = result.length;
} catch (XmlRpcException e) {
fail(e.getMessage());
}
return count;
}
}

View File

@ -0,0 +1,246 @@
package de.hsadmin.remote;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.HashMap;
import java.util.Map;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class EMailAddressTest {
private static final String MODULE = "emailaddress";
private XmlRpcClient client;
private RemoteCASHelper cas;
@Before
public void setUp() throws Exception {
client = RemoteTestHelper.getClient();
cas = new RemoteCASHelper();
}
@After
public void tearDown() throws Exception {
client = null;
cas = null;
}
@Test
public void testSearchAllAsPacAdmin() {
String user = "peh00";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
try {
Object execute = client.execute(MODULE + ".search", params);
Object[] result = (Object[]) execute;
assertEquals(262, result.length);
for (Object o : result) {
if (o instanceof Map<?, ?>) {
Map<?, ?> row = (Map<?, ?>) o;
assertEquals("peh00", row.get("pac"));
} else {
fail("map expected");
}
}
} catch (XmlRpcException e) {
fail(e.getMessage());
}
}
@Test
public void testSearchAsPacAdmin() {
String user = "peh00";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
whereParams.put("domain", "herzensklaenge.de");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
try {
Object execute = client.execute(MODULE + ".search", params);
Object[] result = (Object[]) execute;
assertEquals(2, result.length);
for (Object o : result) {
if (o instanceof Map<?, ?>) {
Map<?, ?> row = (Map<?, ?>) o;
assertEquals("peh00", row.get("pac"));
} else {
fail("map expected");
}
}
} catch (XmlRpcException e) {
fail(e.getMessage());
}
}
@Test
public void testUpdate() {
int count = getTargetCount();
String user = "peh00";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> setParams = new HashMap<String, String>();
Map<String, String> whereParams = new HashMap<String, String>();
setParams.put("target", "peh00-phor");
whereParams.put("domain", "jalin.de");
whereParams.put("localpart", "fax");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
setParams, whereParams };
try {
Object execute = client.execute(MODULE + ".update", params);
Object[] result = (Object[]) execute;
assertEquals(1, result.length);
} catch (XmlRpcException e) {
fail(e.getMessage());
}
assertEquals(count + 1, getTargetCount());
setParams = new HashMap<String, String>();
whereParams = new HashMap<String, String>();
setParams.put("target", "peh00-hotline");
whereParams.put("domain", "jalin.de");
whereParams.put("localpart", "fax");
params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
setParams, whereParams };
try {
Object execute = client.execute(MODULE + ".update", params);
Object[] result = (Object[]) execute;
assertEquals(1, result.length);
} catch (XmlRpcException e) {
fail(e.getMessage());
}
assertEquals(count, getTargetCount());
}
@Test
public void testSearchAsDomAdmin() {
String user = "peh00";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
whereParams.put("domain", "herzensklaenge.de");
whereParams.put("admin", "peh00");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
try {
Object execute = client.execute(MODULE + ".search", params);
Object[] result = (Object[]) execute;
assertEquals(2, result.length);
for (Object o : result) {
if (o instanceof Map<?, ?>) {
Map<?, ?> row = (Map<?, ?>) o;
assertEquals("peh00", row.get("admin"));
} else {
fail("map expected");
}
}
} catch (XmlRpcException e) {
fail(e.getMessage());
}
}
@Test
public void testCreateAsPacAdminFails() {
int count = getObjectCount();
String user = "peh00";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> setParams = new HashMap<String, String>();
setParams.put("localpart", "f6n");
setParams.put("domain", "f6n.de");
setParams.put("target", "peh00-phor");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
setParams };
try {
Object execute = client.execute(MODULE + ".add", params);
assertTrue(execute instanceof Map<?, ?>);
fail("exception expected");
} catch (XmlRpcException e) {
}
assertEquals(count, getObjectCount());
}
@Test
public void testCreateAndDelete() {
int count = getObjectCount();
String user = "peh00";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> setParams = new HashMap<String, String>();
setParams.put("localpart", "f6n");
setParams.put("domain", "jalin.de");
setParams.put("target", "peh00-phor");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
setParams };
try {
Object execute = client.execute(MODULE + ".add", params);
assertTrue(execute instanceof Map<?, ?>);
} catch (XmlRpcException e) {
fail(e.getMessage());
}
assertEquals(count + 1, getObjectCount());
count = getObjectCount();
Map<String, String> whereParams = new HashMap<String, String>();
whereParams.put("localpart", "f6n");
whereParams.put("domain", "jalin.de");
params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
try {
Object execute = client.execute(MODULE + ".delete", params);
assertNull(execute);
} catch (XmlRpcException e) {
fail(e.getMessage());
}
assertEquals(count - 1, getObjectCount());
}
private int getObjectCount() {
int count = -1;
try {
String user = "peh00";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
Object execute = client.execute(MODULE + ".search", params);
Object[] result = (Object[]) execute;
count = result.length;
} catch (XmlRpcException e) {
fail(e.getMessage());
}
return count;
}
private int getTargetCount() {
int count = -1;
try {
String user = "peh00";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
whereParams.put("target", "peh00-phor");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
Object execute = client.execute(MODULE + ".search", params);
Object[] result = (Object[]) execute;
count = result.length;
} catch (XmlRpcException e) {
fail(e.getMessage());
}
return count;
}
}

View File

@ -0,0 +1,61 @@
package de.hsadmin.remote;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.HashMap;
import java.util.Map;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class EMailAliasTest {
private static final String MODULE = "emailalias";
private XmlRpcClient client;
private RemoteCASHelper cas;
@Before
public void setUp() throws Exception {
client = RemoteTestHelper.getClient();
cas = new RemoteCASHelper();
}
@After
public void tearDown() throws Exception {
client = null;
cas = null;
}
@Test
public void testSearchAllAsPacAdmin() {
String user = "peh00";
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
try {
Object execute = client.execute(MODULE + ".search", params);
Object[] result = (Object[]) execute;
assertEquals(262, result.length);
for (Object o : result) {
if (o instanceof Map<?, ?>) {
Map<?, ?> row = (Map<?, ?>) o;
assertEquals("peh00", row.get("pac"));
} else {
fail("map expected");
}
}
} catch (XmlRpcException e) {
fail(e.getMessage());
}
}
}

View File

@ -39,7 +39,7 @@ public class QueueTaskTest {
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
try {
Object execute = client.execute(MODULE + ".search", params);
@ -67,7 +67,7 @@ public class QueueTaskTest {
setParams.put("details", "Test");
whereParams.put("user", "peh00");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
setParams, whereParams };
try {
Object execute = client.execute(MODULE + ".update", params);
@ -93,7 +93,7 @@ public class QueueTaskTest {
setParams.put("details", "Blupp");
setParams.put("exception", "f6n");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
setParams };
try {
Object execute = client.execute(MODULE + ".add", params);
@ -111,7 +111,7 @@ public class QueueTaskTest {
Map<String, String> whereParams = new HashMap<String, String>();
whereParams.put("user", "peh00");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
try {
Object execute = client.execute(MODULE + ".delete", params);

View File

@ -2,40 +2,33 @@ package de.hsadmin.remote;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Properties;
import javax.net.ssl.HttpsURLConnection;
import de.hsadmin.core.util.Config;
public class RemoteCASHelper {
private static String LOGIN_URL = "https://login.hostsharing.net:443/cas/v1/tickets";
private String loginURL;
private Properties config;
public RemoteCASHelper() {
initConfig();
}
private void initConfig() {
config = new Properties();
try {
config.load(new FileInputStream( new File(System.getProperty("user.home"), ".hsadmin.conf")));
} catch (IOException e) {
}
loginURL = config.getProperty("loginURL", LOGIN_URL);
loginURL = Config.getInstance().getProperty("loginURL", LOGIN_URL);
}
public String getGrantingTicketURL(String user) {
String pw = config.getProperty(user + ".passWord", "-");
String pw = Config.getInstance().getProperty(user + ".passWord", "-");
try {
String encodedParams = URLEncoder.encode("username", "UTF-8")
+ "=" + URLEncoder.encode(user, "UTF-8")

View File

@ -10,8 +10,9 @@ import org.junit.runners.Suite;
// MySqlDatabaseTest.class,
// MySqlUserTest.class,
// PgSqlUserTest.class,
// EMailAddressTest.class,
// DomainTest.class,
EMailAliasTest.class,
EMailAddressTest.class,
DomainTest.class,
// HostmasterTest.class,
QueueTaskTest.class
})

View File

@ -5,16 +5,19 @@ import java.net.URL;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
import de.hsadmin.core.util.Config;
public class RemoteTestHelper {
public static String BACKEND_URL = "https://agnes.ostwall195.de:9443/hsar/backend";
private static final String XMLRPC_URL = "https://admin.hostsharing.net:443/hsar/xmlrpc/hsadmin";
private static final String BACKEND_URL = "https://admin.hostsharing.net:443/hsar/backend";
private static XmlRpcClient client;
public static XmlRpcClient getClient() throws Exception {
if (client == null) {
XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
config.setServerURL(new URL("https://agnes.ostwall195.de:9443/hsar/xmlrpc/hsadmin"));
config.setServerURL(new URL(getXmlrpcURL()));
config.setEnabledForExtensions(true);
client = new XmlRpcClient();
client.setConfig(config);
@ -22,4 +25,11 @@ public class RemoteTestHelper {
return client;
}
public static String getBackendURL() {
return Config.getInstance().getProperty("backendURL", BACKEND_URL);
}
public static String getXmlrpcURL() {
return Config.getInstance().getProperty("xmlrpcURL", XMLRPC_URL);
}
}

View File

@ -38,7 +38,7 @@ public class UnixUserTest {
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
try {
Object execute = client.execute(MODULE + ".search", params);
@ -69,7 +69,7 @@ public class UnixUserTest {
setParams.put("quota", "128");
setParams.put("quotalimit", "192");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
setParams };
Object execute = client.execute(MODULE + ".add", params);
if (execute instanceof Map<?, ?>) {
@ -96,7 +96,7 @@ public class UnixUserTest {
setParams.put("name", "peh01-testfail");
setParams.put("password", "test123");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
setParams };
Object execute = client.execute(MODULE + ".add", params);
assertNull(execute);
@ -117,7 +117,7 @@ public class UnixUserTest {
setParams.put("name", "peh00-langer-name");
setParams.put("password", "test123");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
setParams };
Object execute = client.execute(MODULE + ".add", params);
assertNull(execute);
@ -139,7 +139,7 @@ public class UnixUserTest {
whereParams.put("name", "peh00-test2");
setParams.put("password", "test1234");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
setParams, whereParams };
Object execute = client.execute(MODULE + ".update", params);
if (execute instanceof Object[]) {
@ -171,7 +171,7 @@ public class UnixUserTest {
Map<String, String> whereParams = new HashMap<String, String>();
whereParams.put("name", "peh00-langer-name");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
Object execute = client.execute(MODULE + ".delete", params);
assertNull(execute);
@ -190,7 +190,7 @@ public class UnixUserTest {
Map<String, String> whereParams = new HashMap<String, String>();
whereParams.put("name", "peh00-test2");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
Object execute = client.execute(MODULE + ".delete", params);
assertNull(execute);
@ -209,7 +209,7 @@ public class UnixUserTest {
Map<String, String> whereParams = new HashMap<String, String>();
whereParams.put("name", "peh00-test2");
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
Object execute = client.execute(MODULE + ".delete", params);
assertNull(execute);
@ -226,7 +226,7 @@ public class UnixUserTest {
String grantingTicketURL = cas.getGrantingTicketURL(user);
Map<String, String> whereParams = new HashMap<String, String>();
Object[] params = new Object[] { user,
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.BACKEND_URL),
cas.getServiceTicket(grantingTicketURL, RemoteTestHelper.getBackendURL()),
whereParams };
Object execute = client.execute(MODULE + ".search", params);
Object[] result = (Object[]) execute;

View File

@ -27,7 +27,7 @@
</init-param>
<init-param>
<param-name>Components</param-name>
<param-value>user,member,contact,bankaccount,pac,paccomponent,hive,ipaddr,basepac,basecomponent,component,q</param-value>
<param-value>user,domain,member,contact,bankaccount,emailaddress,emailalias,pac,paccomponent,hive,ipaddr,basepac,basecomponent,component,q</param-value>
</init-param>
<init-param>
<param-name>ComponentClass_user</param-name>
@ -37,6 +37,14 @@
<param-name>ComponentDescription_user</param-name>
<param-value>Unix User</param-value>
</init-param>
<init-param>
<param-name>ComponentClass_domain</param-name>
<param-value>de.hsadmin.mods.dom.Domain</param-value>
</init-param>
<init-param>
<param-name>ComponentDescription_domain</param-name>
<param-value>Domains</param-value>
</init-param>
<init-param>
<param-name>ComponentClass_member</param-name>
<param-value>de.hsadmin.mods.cust.Customer</param-value>
@ -61,6 +69,22 @@
<param-name>ComponentDescription_bankaccount</param-name>
<param-value>Bankverbindungen</param-value>
</init-param>
<init-param>
<param-name>ComponentClass_emailaddress</param-name>
<param-value>de.hsadmin.mods.email.EMailAddress</param-value>
</init-param>
<init-param>
<param-name>ComponentDescription_emailaddress</param-name>
<param-value>e-Mail Adressen</param-value>
</init-param>
<init-param>
<param-name>ComponentClass_emailalias</param-name>
<param-value>de.hsadmin.mods.email.EMailAlias</param-value>
</init-param>
<init-param>
<param-name>ComponentDescription_emailalias</param-name>
<param-value>e-Mail Aliases</param-value>
</init-param>
<init-param>
<param-name>ComponentClass_pac</param-name>
<param-value>de.hsadmin.mods.pac.Pac</param-value>