package cx.ath.hoenicke.otp.client; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.http.client.Request; import com.google.gwt.http.client.RequestBuilder; import com.google.gwt.http.client.RequestCallback; import com.google.gwt.http.client.RequestException; import com.google.gwt.http.client.Response; import com.google.gwt.http.client.URL; import cx.ath.hoenicke.gwt.md5.client.MD5; /** * Entry point classes define onModuleLoad(). */ public class Client implements EntryPoint { public static final boolean readonly = false; String user, password, salt; int seq = -1; int oldseq; int userid; boolean admin; LoginDialog loginDialog; AlertBox alertBox; /** * Basic JSON wrapper for reply of the server. There are subclasses * for each specific reply a server may send. This handles just * the authentication layer. */ static class ServerReply extends JavaScriptObject { protected ServerReply() {} public final native boolean isAuth() /*-{ return this.auth; }-*/; public final native int authSeq() /*-{ return this.seq; }-*/; public final native String authSalt() /*-{ return this.salt; }-*/; } /** * Handles reply for "user" queries. */ static class UserReply extends ServerReply { protected UserReply() {} public static native UserReply fromJSONString(String jsonString) /*-{ return eval('('+jsonString+')'); }-*/; public final native boolean isAdmin() /*-{ return this.admin; }-*/; public final native int getId() /*-{ return this.id; }-*/; public final native JSArray getUsers() /*-{ return this.users; }-*/; } class UserHandler implements RequestCallback { public UserHandler() { post(); } public void post() { try { RequestBuilder request = new RequestBuilder(RequestBuilder.POST, BASE_URL+"user.php"); request.setHeader("Content-Type", "application/x-www-form-urlencoded"); request.sendRequest(getAuth(), this); } catch (RequestException ex) { alert(ex.toString()); } } public void onResponseReceived(Request request, Response response) { if (response.getStatusCode() == 200) { UserReply reply = UserReply.fromJSONString(response.getText()); if (!reply.isAuth()) { if (updateSalt(reply)) post(); return; } userid = reply.getId(); admin = reply.isAdmin(); /* handle user info */ ... } else { alert(""+response.getStatusCode()+":"+response.getText()); } } public void onError(Request request, Throwable exception) { alert("Error while requesting UserInfo"); } } public String getAuth() { return getAuth(password); } public String getAuth(String newpw) { String pw; if (salt == null) pw = ""; else pw = "&pw="+MD5.otpjoho(password, seq, salt); oldseq = seq; if (newpw != password || (seq >= 0 && seq < 146)) { seq = 400; salt = MD5.md5(user+salt+seq+Math.random()).substring(0,16); pw += "&nseq="+seq+"&nsalt="+salt +"&npw="+MD5.otpjoho(newpw, seq+1, salt); } else { seq--; } return "user="+user+pw; } public boolean updateSalt(ServerReply reply) { salt = reply.authSalt(); seq = reply.authSeq(); if (oldseq == reply.authSeq()) { login(); return false; } return true; } public void setAuth(String user, String pw) { this.user = URL.encodeComponent(user); this.password = pw; refresh(); } public void refresh() { new UserHandler(); } public void login() { loginDialog.center(); } private void logOut() { user = password = salt = null; seq = -1; loginDialog.loginField.setText(""); loginDialog.pwField.setText(""); } public void alert(String s) { alertBox.alert(s); } /** * This is the entry point method. */ public void onModuleLoad() { loginDialog = new LoginDialog(this); alertBox = new AlertBox(); login(); } }