Merge branch 'main' into 18842-arv-mount-disk-config
[arvados.git] / lib / controller / localdb / login.go
index 3c7b01baad1361735ebe37b4ef6df7157d1eb750..a1ac2c55b02657462ce1c78d860df4a4fdc94186 100644 (file)
@@ -10,6 +10,7 @@ import (
        "encoding/json"
        "errors"
        "fmt"
+       "net"
        "net/http"
        "net/url"
        "strings"
@@ -147,13 +148,13 @@ func (conn *Conn) CreateAPIClientAuthorization(ctx context.Context, rootToken st
                        tokensecret = tokenparts[2]
                }
        }
-       var exp sql.NullString
+       var exp sql.NullTime
        var scopes []byte
        err = tx.QueryRowxContext(ctx, "select uuid, api_token, expires_at, scopes from api_client_authorizations where api_token=$1", tokensecret).Scan(&resp.UUID, &resp.APIToken, &exp, &scopes)
        if err != nil {
                return
        }
-       resp.ExpiresAt = exp.String
+       resp.ExpiresAt = exp.Time
        if len(scopes) > 0 {
                err = json.Unmarshal(scopes, &resp.Scopes)
                if err != nil {
@@ -162,3 +163,39 @@ func (conn *Conn) CreateAPIClientAuthorization(ctx context.Context, rootToken st
        }
        return
 }
+
+func validateLoginRedirectTarget(cluster *arvados.Cluster, returnTo string) error {
+       u, err := url.Parse(returnTo)
+       if err != nil {
+               return err
+       }
+       u, err = u.Parse("/")
+       if err != nil {
+               return err
+       }
+       if u.Port() == "80" && u.Scheme == "http" {
+               u.Host = u.Hostname()
+       } else if u.Port() == "443" && u.Scheme == "https" {
+               u.Host = u.Hostname()
+       }
+       if _, ok := cluster.Login.TrustedClients[arvados.URL(*u)]; ok {
+               return nil
+       }
+       if u.String() == cluster.Services.Workbench1.ExternalURL.String() ||
+               u.String() == cluster.Services.Workbench2.ExternalURL.String() {
+               return nil
+       }
+       if cluster.Login.TrustPrivateNetworks {
+               if u.Hostname() == "localhost" {
+                       return nil
+               }
+               if ip := net.ParseIP(u.Hostname()); len(ip) > 0 {
+                       for _, n := range privateNetworks {
+                               if n.Contains(ip) {
+                                       return nil
+                               }
+                       }
+               }
+       }
+       return fmt.Errorf("requesting site is not listed in TrustedClients config")
+}