Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / jigsaw / src / org / w3c / www / protocol / http / auth / AuthFilter.java
diff --git a/JMCR-Stable/real-world application/jigsaw/src/org/w3c/www/protocol/http/auth/AuthFilter.java b/JMCR-Stable/real-world application/jigsaw/src/org/w3c/www/protocol/http/auth/AuthFilter.java
new file mode 100644 (file)
index 0000000..612aeff
--- /dev/null
@@ -0,0 +1,400 @@
+// AuthFilter.java\r
+// $Id: AuthFilter.java,v 1.1 2010/06/15 12:27:25 smhuang Exp $\r
+// (c) COPYRIGHT MIT and INRIA, 1996.\r
+// Please first read the full copyright statement in file COPYRIGHT.html\r
+\r
+package org.w3c.www.protocol.http.auth;\r
+\r
+import java.awt.Button;\r
+import java.awt.Component;\r
+import java.awt.Container;\r
+import java.awt.Event;\r
+import java.awt.Frame;\r
+import java.awt.GridBagConstraints;\r
+import java.awt.GridBagLayout;\r
+import java.awt.Label;\r
+import java.awt.Panel;\r
+import java.awt.TextComponent;\r
+import java.awt.TextField;\r
+import java.awt.Window;\r
+\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+\r
+import java.util.Hashtable;\r
+\r
+import org.w3c.tools.codec.Base64Encoder;\r
+\r
+import org.w3c.www.protocol.http.HttpException;\r
+import org.w3c.www.protocol.http.HttpManager;\r
+import org.w3c.www.protocol.http.PropRequestFilter;\r
+import org.w3c.www.protocol.http.Reply;\r
+import org.w3c.www.protocol.http.Request;\r
+\r
+import org.w3c.www.http.HTTP;\r
+import org.w3c.www.http.HttpChallenge;\r
+import org.w3c.www.http.HttpCredential;\r
+import org.w3c.www.http.HttpFactory;\r
+import org.w3c.www.http.HttpReplyMessage;\r
+import org.w3c.www.http.HttpRequestMessage;\r
+\r
+class UserField extends TextField {\r
+    PasswordPrompter prompter = null;\r
+\r
+    public boolean keyDown(Event evt, int key) {\r
+       if ( key == '\t' ) {\r
+           prompter.focusPassword();\r
+           return true;\r
+       }\r
+       return super.keyDown(evt, key);\r
+    }\r
+\r
+    UserField(PasswordPrompter prompter, String txt, int len) {\r
+       super(txt, len);\r
+       this.prompter = prompter;\r
+    }\r
+\r
+}\r
+\r
+class PasswordField extends TextField {\r
+    PasswordPrompter prompter = null;\r
+\r
+    public boolean keyDown(Event evt, int key) {\r
+       if ((key == '\n') || (key == '\r')) {\r
+           prompter.done(PasswordPrompter.EVT_OK);\r
+           return true;\r
+       }\r
+       return super.keyDown(evt, key);\r
+    }\r
+\r
+    PasswordField(PasswordPrompter prompter, String txt, int len) {\r
+       super(txt, len);\r
+       setEchoCharacter('*');\r
+       this.prompter = prompter;\r
+    }\r
+}\r
+\r
+class PasswordPrompter extends Panel {\r
+    TextField txtUser     = null;\r
+    TextField txtPassword = null;\r
+    Button    butOk       = null;\r
+    Button    butCancel   = null;\r
+\r
+    String user     = null;\r
+    String password = null;\r
+\r
+    static final int EVT_OK     = 1;\r
+    static final int EVT_CANCEL = 2;\r
+    int evt = -1;\r
+\r
+    protected synchronized boolean waitForCompletion() {\r
+       while ( true ) {\r
+           // Wait for next event:\r
+           while ( evt < 0 ) {\r
+               try {\r
+                   wait();\r
+               } catch (InterruptedException ex) {\r
+               }\r
+           }\r
+           // Handle the event:\r
+           switch(evt) {\r
+             case EVT_OK:\r
+                 return true;\r
+             case EVT_CANCEL:\r
+                 return false;\r
+           }\r
+       }\r
+    }\r
+\r
+    protected synchronized void done(int evt) {\r
+       this.evt = evt;\r
+       notifyAll();\r
+    }\r
+\r
+    protected void focusPassword() {\r
+       txtPassword.requestFocus();\r
+    }\r
+\r
+    public boolean action(Event evt, Object what) {\r
+       int e = -1;\r
+       if ( evt.target == butOk ) {\r
+           e = EVT_OK;\r
+       } else if ( evt.target == butCancel ) {\r
+           e = EVT_CANCEL;\r
+       } else {\r
+           return super.action(evt, what);\r
+       }\r
+       // We are done with this dialog:\r
+       done(e);\r
+       return true;\r
+    }\r
+\r
+    /**\r
+     * Get the entered user name.\r
+     * @return The user name as a String.\r
+     */\r
+\r
+    public String getUser() {\r
+       return user;\r
+    }\r
+\r
+    /**\r
+     * Get the entered password.\r
+     * @return The password as a String.\r
+     */\r
+\r
+    public String getPassword() {\r
+       return password;\r
+    }\r
+\r
+    /**\r
+     * Run the dialog, as if modal.\r
+     * @return A boolean <strong>false</strong> if interaction was canceled,\r
+     * <strong>true</strong> otherwise.\r
+     */\r
+\r
+    public boolean prompt() {\r
+       Frame toplevel = new Frame("Authentication Required");\r
+       toplevel.add("Center", this);\r
+       toplevel.pack();\r
+       toplevel.show();\r
+       // Set focus to the user name:\r
+       txtUser.requestFocus();\r
+       // Wait for completion, pack up the result, and delete GUI:\r
+       boolean result = waitForCompletion();\r
+       this.user      = txtUser.getText();\r
+       this.password  = txtPassword.getText();\r
+       toplevel.hide();\r
+       toplevel.dispose();\r
+       return result;\r
+    }\r
+\r
+    PasswordPrompter(Request request, Reply reply) {\r
+       // Setup the layout:\r
+       super();\r
+       GridBagLayout gb = new GridBagLayout();\r
+       setLayout(gb);\r
+       // Create the title label:\r
+       HttpChallenge challenge = (request.hasProxy()\r
+                                  ? reply.getProxyAuthenticate()\r
+                                  : reply.getWWWAuthenticate());\r
+       Label label = new Label(challenge.getScheme()\r
+                               + " authentication for "\r
+                                + challenge.getAuthParameter("realm"));\r
+       GridBagConstraints row = new GridBagConstraints();\r
+       row.gridwidth = GridBagConstraints.REMAINDER;\r
+       row.anchor    = GridBagConstraints.WEST;\r
+       gb.setConstraints(label, row);\r
+       add(label);\r
+       // Create the entries:\r
+       GridBagConstraints ct = new GridBagConstraints();\r
+       ct.gridx   = GridBagConstraints.RELATIVE ;\r
+       ct.anchor  = GridBagConstraints.EAST ;\r
+       ct.weighty = 1.0 ;\r
+       GridBagConstraints cv = new GridBagConstraints() ;\r
+       cv.gridx     = GridBagConstraints.RELATIVE ;\r
+       cv.gridwidth = GridBagConstraints.REMAINDER ;\r
+       cv.fill      = GridBagConstraints.HORIZONTAL ;\r
+       cv.anchor    = GridBagConstraints.WEST ;\r
+       cv.weightx   = 1.0 ;\r
+       cv.weighty   = 1.0 ;\r
+       // Create user entry:\r
+       label = new Label("User:", Label.LEFT);\r
+       gb.setConstraints(label, ct);\r
+       add(label);\r
+       txtUser = new UserField(this, "", 32);\r
+       gb.setConstraints(txtUser, cv);\r
+       add(txtUser);\r
+       // Create password entry:\r
+       label = new Label("Password:", Label.LEFT);\r
+       gb.setConstraints(label, ct);\r
+       add(label);\r
+       txtPassword = new PasswordField(this, "", 32);\r
+       gb.setConstraints(txtPassword, cv);\r
+       add(txtPassword);\r
+       // Add the row of buttons:\r
+       butOk = new Button("Ok");\r
+       row.anchor    = GridBagConstraints.EAST;\r
+       row.weightx   = 1.0;\r
+       row.gridwidth = GridBagConstraints.RELATIVE;\r
+       gb.setConstraints(butOk, row);\r
+       add(butOk);\r
+       butCancel = new Button("Cancel");\r
+       row.anchor    = GridBagConstraints.WEST;\r
+       row.gridwidth = GridBagConstraints.REMAINDER;\r
+       gb.setConstraints(butCancel, row);\r
+       add(butCancel);\r
+    }\r
+}\r
+\r
+class CachedRealm {\r
+    public String         realm       = null;\r
+    public HttpCredential credentials = null;\r
+\r
+    CachedRealm(String realm, HttpCredential credentials) {\r
+       this.realm       = realm;\r
+       this.credentials = credentials;\r
+    }\r
+}\r
+\r
+public class AuthFilter implements PropRequestFilter {\r
+    /**\r
+     * The per-server realms we know about.\r
+     */\r
+    protected static Hashtable realms = new Hashtable(13);\r
+    /**\r
+     * the HttpManager that installed us.\r
+     */\r
+    protected HttpManager manager = null;\r
+\r
+    protected static void registerRealm(Request request\r
+                                       , Reply reply\r
+                                       , HttpCredential credentials) {\r
+       // Do we already know about that realm ?\r
+       if ( lookupRealm(request, reply) != null )\r
+           return;\r
+       // Register the realm:\r
+       String      srvkey  = request.getManager().getServerKey(request);\r
+       String      realm   = ((request.hasProxy()\r
+                               ? reply.getProxyAuthenticate()\r
+                               : reply.getWWWAuthenticate())\r
+                              .getAuthParameter("realm"));\r
+       CachedRealm cache[] = (CachedRealm[]) realms.get(srvkey);\r
+       if ( cache == null ) {\r
+           cache    = new CachedRealm[1];\r
+           cache[0] = new CachedRealm(realm, credentials);\r
+       } else {\r
+           CachedRealm nc[] = new CachedRealm[cache.length+1];\r
+           System.arraycopy(cache, 0, nc, 0, cache.length);\r
+           nc[cache.length] = new CachedRealm(realm, credentials);\r
+           cache = nc;\r
+       }\r
+       realms.put(srvkey, cache);\r
+    }\r
+\r
+    protected static HttpCredential lookupRealm(Request request\r
+                                               , Reply reply) {\r
+       // Lookup known realms on target server:\r
+       String      srvkey  = request.getManager().getServerKey(request);\r
+       CachedRealm cache[] = (CachedRealm[]) realms.get(srvkey);\r
+       if ( cache == null )\r
+           return null;\r
+       // Found something, check:\r
+       HttpChallenge challenge = (request.hasProxy()\r
+                                  ? reply.getProxyAuthenticate()\r
+                                  : reply.getWWWAuthenticate());\r
+       String realm = challenge.getAuthParameter("realm");\r
+       for (int i = 0 ; i < cache.length ; i++) {\r
+           if ( cache[i].realm.equalsIgnoreCase(realm) )\r
+               return cache[i].credentials;\r
+       }\r
+       return null;\r
+    }\r
+\r
+    /**\r
+     * PropRequestFilter implementation - Initialize the filter.\r
+     * Time to register ourself to the HttpManager.\r
+     * @param manager The HTTP manager that is initializing ourself.\r
+     */\r
+\r
+    public void initialize(HttpManager manager) {\r
+       this.manager = manager;\r
+       // We install ourself as a global filter, we are cool !\r
+       manager.setFilter(this);\r
+       manager.setAllowUserInteraction(true);\r
+    }\r
+\r
+    /**\r
+     * This filter doesn't handle exceptions.\r
+     * @param request The request that triggered the exception.\r
+     * @param ex The triggered exception.\r
+     * @return Always <strong>false</strong>.\r
+     */\r
+\r
+    public boolean exceptionFilter(Request request, HttpException ex) {\r
+       return false;\r
+    }\r
+\r
+    /**\r
+     * On the way out, we let the request fly through.\r
+     * @param request The request about to be emitted.\r
+     */\r
+\r
+    public Reply ingoingFilter(Request request) {\r
+       return null;\r
+    }\r
+\r
+    /**\r
+     * Catch any authentication requirement, and fullfill it with user's help.\r
+     * This method trap all request for authentication, and pops up a\r
+     * dialog prompting for the user's name and password.\r
+     * <p>It then retries the request with the provided authentication\r
+     * informations.\r
+     * @param request The request that requires authentication.\r
+     * @param reply The original reply.\r
+     * @exception HttpException If some HTTP error occurs.\r
+     */\r
+\r
+    public Reply outgoingFilter(Request request, Reply reply) \r
+       throws HttpException\r
+    {\r
+       // Is this really for us to catch ?\r
+       if ((reply.getStatus() != HTTP.UNAUTHORIZED)\r
+           && (reply.getStatus() != HTTP.PROXY_AUTH_REQUIRED))\r
+           return null;\r
+       // Do we know about this realm ?\r
+       HttpCredential credentials = null;\r
+       if ((credentials = lookupRealm(request, reply)) == null) {\r
+           // If we can't interact, we can't help:\r
+           if ( ! request.getAllowUserInteraction() ) \r
+               return null;\r
+           // Great ! Now we can indeed help:\r
+           PasswordPrompter prompter = new PasswordPrompter(request, reply);\r
+           if ( ! prompter.prompt() )\r
+               return null;\r
+           String user     = prompter.getUser();\r
+           String password = prompter.getPassword();\r
+           // Compute credentials:\r
+           credentials = HttpFactory.makeCredential("Basic");\r
+           Base64Encoder encoder = new Base64Encoder(user+":"+password);\r
+           credentials.setAuthParameter("cookie", encoder.processString());\r
+       }\r
+       // Now restart the request we the right auth infos:\r
+       if ( request.hasProxy() )\r
+           request.setProxyAuthorization(credentials);\r
+       else\r
+           request.setAuthorization(credentials);\r
+       Reply retry = request.getManager().runRequest(request);\r
+       if ( retry.getStatus() / 100 != 4 ) {\r
+           // We did succeed, register server/realm infos:\r
+           registerRealm(request, reply, credentials);\r
+           // Create the local auth filter:\r
+           if ( request.hasProxy() ) {\r
+               LocalAuthFilter.installProxyAuth(manager, credentials);\r
+           } else {\r
+               LocalAuthFilter.installLocalAuth(manager\r
+                                                , request.getURL()\r
+                                                , credentials);\r
+           }\r
+           // Swallow input stream of original reply:\r
+           try {\r
+               InputStream in = reply.getInputStream();\r
+               if ( in != null )\r
+                   in.close();\r
+           } catch (IOException ex) {\r
+           }\r
+           // Return the right reply:\r
+           return retry;\r
+       } else {\r
+           return null;\r
+       }\r
+    }\r
+\r
+    /**\r
+     * We don't maintain cached informations.\r
+     */\r
+\r
+    public void sync() {\r
+    }\r
+\r
+}\r