19296: Fix remove(recursive=True) for depth>1.
[arvados.git] / lib / controller / localdb / login_testuser.go
index 5a3d803b89960df03dce638291af9cb338560d78..9988f6997a1b6f03ceb1d46505bbd4b84e7acee2 100644 (file)
@@ -5,9 +5,10 @@
 package localdb
 
 import (
+       "bytes"
        "context"
-       "errors"
        "fmt"
+       "html/template"
 
        "git.arvados.org/arvados.git/lib/controller/rpc"
        "git.arvados.org/arvados.git/sdk/go/arvados"
@@ -16,16 +17,25 @@ import (
 )
 
 type testLoginController struct {
-       Cluster    *arvados.Cluster
-       RailsProxy *railsProxy
+       Cluster *arvados.Cluster
+       Parent  *Conn
 }
 
 func (ctrl *testLoginController) Logout(ctx context.Context, opts arvados.LogoutOptions) (arvados.LogoutResponse, error) {
-       return noopLogout(ctrl.Cluster, opts)
+       return logout(ctx, ctrl.Cluster, opts)
 }
 
 func (ctrl *testLoginController) Login(ctx context.Context, opts arvados.LoginOptions) (arvados.LoginResponse, error) {
-       return arvados.LoginResponse{}, errors.New("interactive login is not available")
+       tmpl, err := template.New("form").Parse(loginform)
+       if err != nil {
+               return arvados.LoginResponse{}, err
+       }
+       var buf bytes.Buffer
+       err = tmpl.Execute(&buf, opts)
+       if err != nil {
+               return arvados.LoginResponse{}, err
+       }
+       return arvados.LoginResponse{HTML: buf}, nil
 }
 
 func (ctrl *testLoginController) UserAuthenticate(ctx context.Context, opts arvados.UserAuthenticateOptions) (arvados.APIClientAuthorization, error) {
@@ -35,7 +45,7 @@ func (ctrl *testLoginController) UserAuthenticate(ctx context.Context, opts arva
                                "username": username,
                                "email":    user.Email,
                        }).Debug("test authentication succeeded")
-                       return createAPIClientAuthorization(ctx, ctrl.RailsProxy, ctrl.Cluster.SystemRootToken, rpc.UserSessionAuthInfo{
+                       return ctrl.Parent.CreateAPIClientAuthorization(ctx, ctrl.Cluster.SystemRootToken, rpc.UserSessionAuthInfo{
                                Username: username,
                                Email:    user.Email,
                        })
@@ -43,3 +53,52 @@ func (ctrl *testLoginController) UserAuthenticate(ctx context.Context, opts arva
        }
        return arvados.APIClientAuthorization{}, fmt.Errorf("authentication failed for user %q with password len=%d", opts.Username, len(opts.Password))
 }
+
+const loginform = `
+<!doctype html>
+<html>
+  <head><title>Arvados test login</title>
+    <script>
+      async function authenticate(event) {
+        event.preventDefault()
+       document.getElementById('error').innerHTML = ''
+       const resp = await fetch('/arvados/v1/users/authenticate', {
+         method: 'POST',
+         mode: 'same-origin',
+         headers: {'Content-Type': 'application/json'},
+         body: JSON.stringify({
+           username: document.getElementById('username').value,
+           password: document.getElementById('password').value,
+         }),
+       })
+       if (!resp.ok) {
+         document.getElementById('error').innerHTML = '<p>Authentication failed.</p><p>The "test login" users are defined in Clusters.[ClusterID].Login.Test.Users section of config.yml</p><p>If you are using arvbox, use "arvbox adduser" to add users.</p>'
+         return
+       }
+       var redir = document.getElementById('return_to').value
+       if (redir.indexOf('?') > 0) {
+         redir += '&'
+       } else {
+         redir += '?'
+       }
+        const respj = await resp.json()
+       document.location = redir + "api_token=v2/" + respj.uuid + "/" + respj.api_token
+      }
+    </script>
+  </head>
+  <body>
+    <h3>Arvados test login</h3>
+    <form method="POST">
+      <input id="return_to" type="hidden" name="return_to" value="{{.ReturnTo}}">
+      username <input id="username" type="text" name="username" autofocus size=16>
+      password <input id="password" type="password" name="password" size=16>
+      <input type="submit" value="Log in">
+      <br>
+      <p id="error"></p>
+    </form>
+  </body>
+  <script>
+    document.getElementsByTagName('form')[0].onsubmit = authenticate
+  </script>
+</html>
+`