/* * Created on 28.05.2005 * Author: Moritz Kroll */ package jplagWebService.serverAccess; import java.io.File; import java.io.FileInputStream; import java.text.DateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.Locale; import java.util.TimeZone; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import jplagWebService.server.JPlagException; import jplagWebService.server.RequestData; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; public class RequestAdmin { private Document doc = null; private Element rootElement = null; private Element nonValidatedRequestsElement = null; private Element validatedRequestsElement = null; private File requestFile = null; public RequestAdmin(String jplagHome) { requestFile = new File(jplagHome + File.separator + "account_requests.xml"); if(!requestFile.exists()) create(); else parse(); } /** * Writes the "account-requests" data to an XML file */ private synchronized void writeXMLFile() { try { // Prepare the DOM document for writing Source source = new DOMSource(doc); // Prepare the output file Result result = new StreamResult(requestFile); // Write the DOM document to the file Transformer xformer = TransformerFactory.newInstance() .newTransformer(); xformer.transform(source, result); } catch (TransformerConfigurationException e) { e.printStackTrace(); } catch (TransformerException e) { e.printStackTrace(); } } /** * Creates a new "account-request database" XML file */ private void create() { DocumentBuilderFactory docBFac; DocumentBuilder docBuild; try { docBFac = DocumentBuilderFactory.newInstance(); docBuild = docBFac.newDocumentBuilder(); doc = docBuild.newDocument(); } catch (Exception ex) { ex.printStackTrace(); return; } rootElement = doc.createElement("account-requests"); doc.appendChild(rootElement); nonValidatedRequestsElement = doc.createElement("nonvalidated-requests"); validatedRequestsElement = doc.createElement("validated-requests"); rootElement.appendChild(nonValidatedRequestsElement); rootElement.appendChild(validatedRequestsElement); writeXMLFile(); } /** * Loads an existing "account-request database" into memory */ private void parse() { try { FileInputStream xmlStream = new FileInputStream(requestFile); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setIgnoringComments(true); DocumentBuilder builder = factory.newDocumentBuilder(); doc = builder.parse(xmlStream); xmlStream.close(); rootElement = doc.getDocumentElement(); NodeList nodes=rootElement.getElementsByTagName( "nonvalidated-requests"); nonValidatedRequestsElement=(Element) nodes.item(0); nodes=rootElement.getElementsByTagName("validated-requests"); validatedRequestsElement=(Element) nodes.item(0); } catch (javax.xml.parsers.ParserConfigurationException e) { // throw new RuntimeException("Failed to create DocumentBuilder"); e.printStackTrace(); } catch (org.xml.sax.SAXException e) { // throw new RuntimeException("Error parsing users.xml"); e.printStackTrace(); } catch (Exception e) { System.out.println("File error!"); e.printStackTrace(); } } private void setString(Element elem, String attr, String str) { if(str!=null && str.length()!=0) elem.setAttribute(attr,str); } public static String getRandomCode() { char[] code=new char[11]; for(int i=0;i<11;i++) { if((i&3)==3) code[i]=(char)((Math.random()*10)+'0'); else code[i]=(char)((Math.random()*26)+'A'); } return new String(code); } private String formatCalendar(Calendar cal) { DateFormat df=DateFormat.getDateInstance(DateFormat.MEDIUM,Locale.GERMAN); return df.format(cal.getTime()); } /* private void setCalendar(Element user, Calendar cal, String attr) { user.setAttribute(attr,formatCalendar(cal)); }*/ private Calendar parseCalendar(String str) { Calendar cal=new GregorianCalendar(TimeZone.getTimeZone("GMT")); try { cal.setTime(DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.GERMAN).parse(str)); } catch(java.text.ParseException ex) { ex.printStackTrace(); System.out.println("Illegal date: " + str); cal.set(1970,0,1); // set an error date (1.1.1970) System.out.println("Set to " + formatCalendar(cal)); } return cal; } private Calendar parseCalendar(Element elem, String attrname) { return parseCalendar(elem.getAttribute(attrname)); } public synchronized String addRequest(RequestData rd) { Element elem=doc.createElement("request"); setString(elem,"username",rd.getUsername()); setString(elem,"password",rd.getPassword()); setString(elem,"realname",rd.getRealName()); setString(elem,"email",rd.getEmail()); setString(elem,"emailSecond",rd.getEmailSecond()); setString(elem,"homepage",rd.getHomepage()); setString(elem,"reason",rd.getReason()); setString(elem,"notes",rd.getNotes()); String code=getRandomCode() + rd.getUsername(); setString(elem,"code",code); Calendar cal=Calendar.getInstance(TimeZone.getTimeZone("GMT")); elem.setAttribute("requested",formatCalendar(cal)); nonValidatedRequestsElement.appendChild(elem); writeXMLFile(); return code; } /** * Checks the email verification and moves the request from "non-validated" * to "validated" status, if the verification is valid. Otherwise it throws * an exception. * * @return The username corresponding to the verification code * @throws JPlagException when the username wasn't found, the code is not * correct or the request has already been verified */ public synchronized String validateRequest(String code) throws JPlagException { if(code.length()<12) // username must be at least one character { throw new JPlagException("validateRequest", "Wrong verification code given: " + code, "Please check the correct spelling of the code!"); } String username=code.substring(11); System.out.println("[" + new Date() + "] validateRequest: username=" + username + " code=" + code); NodeList reqs=nonValidatedRequestsElement.getElementsByTagName("request"); for(int i=0;i<reqs.getLength();i++) { Element elem=(Element) reqs.item(i); if(elem.getAttribute("username").equals(username)) { if(elem.getAttribute("code").equals(code)) { nonValidatedRequestsElement.removeChild(elem); elem.removeAttribute("code"); elem.setAttribute("validated",new Date()+""); validatedRequestsElement.appendChild(elem); writeXMLFile(); return username; } else throw new JPlagException("validateRequest", "Wrong verification code given: " + code, "Please check the correct spelling of the code!"); } } reqs=validatedRequestsElement.getElementsByTagName("request"); for(int i=0;i<reqs.getLength();i++) { Element elem=(Element) reqs.item(i); if(elem.getAttribute("username").equals(username)) { throw new JPlagException("validateRequest", "The request's email address has already been " + "verified!", "Please wait until the administrator has" + " decided on your request!"); } } throw new JPlagException("validateRequest", "No request for user \"" + username + "\" found!", "Please check the correct spelling of the username! " + "The request may also have expired."); } public synchronized void removeRequest(String username) { NodeList reqs=validatedRequestsElement.getElementsByTagName("request"); for(int i=0;i<reqs.getLength();i++) { Element elem=(Element) reqs.item(i); if(elem.getAttribute("username").equals(username)) { validatedRequestsElement.removeChild(elem); writeXMLFile(); return; } } } public synchronized void removeExpiredUnvalidatedRequests() { boolean changed=false; NodeList reqs=nonValidatedRequestsElement.getElementsByTagName("request"); Calendar cal=Calendar.getInstance(TimeZone.getTimeZone("GMT")); cal.add(Calendar.DATE,-3); for(int i=reqs.getLength()-1;i>=0;i--) { Element elem=(Element) reqs.item(i); Calendar curcal=parseCalendar(elem,"requested"); if(cal.after(curcal)) { System.out.println("[" + new Date() + "] Non-validated request" + " for username " + elem.getAttribute("username") + " for " + elem.getAttribute("realname") + " with email " + elem.getAttribute("email") + " expired!"); nonValidatedRequestsElement.removeChild(elem); changed=true; } } if(changed) writeXMLFile(); } private String parseNillableString(Element elem, String attrname) { String str=elem.getAttribute(attrname); if(str.length()==0) return null; else return str; } private RequestData getRequestDataFromElement(Element elem) { RequestData rd=new RequestData(); rd.setValidateTime(elem.getAttribute("validated")); rd.setUsername(elem.getAttribute("username")); rd.setPassword(elem.getAttribute("password")); rd.setRealName(elem.getAttribute("realname")); rd.setEmail(elem.getAttribute("email")); rd.setEmailSecond(parseNillableString(elem,"emailSecond")); rd.setHomepage(parseNillableString(elem,"homepage")); rd.setReason(elem.getAttribute("reason")); rd.setNotes(parseNillableString(elem,"notes")); return rd; } public synchronized RequestData getRequestData(String username) { NodeList reqs=validatedRequestsElement.getElementsByTagName("request"); for(int i=0;i<reqs.getLength();i++) { Element elem=(Element) reqs.item(i); if(elem.getAttribute("username").equals(username)) return getRequestDataFromElement(elem); } return null; } public synchronized RequestData[] getRequests(boolean lengthOnly) { NodeList reqs=validatedRequestsElement.getElementsByTagName("request"); RequestData[] rds=new RequestData[reqs.getLength()]; if(!lengthOnly) { for(int i=0;i<reqs.getLength();i++) { Element elem=(Element) reqs.item(i); rds[i]=getRequestDataFromElement(elem); } } else { for(int i=0;i<reqs.getLength();i++) { rds[i]=new RequestData(); } } return rds; } /** * @return whether there is a request for the given username */ public synchronized boolean exists(String username) { NodeList reqs=nonValidatedRequestsElement.getElementsByTagName("request"); for(int i=0;i<reqs.getLength();i++) { Element elem=(Element) reqs.item(i); if(elem.getAttribute("username").equals(username)) return true; } reqs=validatedRequestsElement.getElementsByTagName("request"); for(int i=0;i<reqs.getLength();i++) { Element elem=(Element) reqs.item(i); if(elem.getAttribute("username").equals(username)) return true; } return false; } }