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();
}
}