mirror of
https://github.com/argoproj/argo-cd
synced 2026-05-24 09:50:08 +00:00
* Issue #2659 - Fix 1.3 login regressions * Add server.go tests
This commit is contained in:
parent
4facca0ae7
commit
f4400b9493
4 changed files with 70 additions and 29 deletions
|
|
@ -492,16 +492,17 @@ func (a *ArgoCDServer) translateGrpcCookieHeader(ctx context.Context, w http.Res
|
|||
}
|
||||
token := sessionResp.Token
|
||||
if token != "" {
|
||||
token, err := zjwt.ZJWT(token)
|
||||
var err error
|
||||
token, err = zjwt.ZJWT(token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cookie, err := httputil.MakeCookieMetadata(common.AuthCookieName, token, flags...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w.Header().Set("Set-Cookie", cookie)
|
||||
}
|
||||
cookie, err := httputil.MakeCookieMetadata(common.AuthCookieName, token, flags...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w.Header().Set("Set-Cookie", cookie)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,10 +4,13 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/argoproj/argo-cd/pkg/apiclient/session"
|
||||
|
||||
"google.golang.org/grpc/metadata"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
|
|
@ -479,3 +482,31 @@ func Test_getToken(t *testing.T) {
|
|||
assert.Equal(t, token, getToken(metadata.New(map[string]string{"grpcgateway-cookie": "argocd.token=" + token})))
|
||||
})
|
||||
}
|
||||
|
||||
func TestTranslateGrpcCookieHeader(t *testing.T) {
|
||||
argoCDOpts := ArgoCDServerOpts{
|
||||
Namespace: test.FakeArgoCDNamespace,
|
||||
KubeClientset: fake.NewSimpleClientset(test.NewFakeConfigMap(), test.NewFakeSecret()),
|
||||
AppClientset: apps.NewSimpleClientset(),
|
||||
}
|
||||
argocd := NewServer(context.Background(), argoCDOpts)
|
||||
|
||||
t.Run("TokenIsNotEmpty", func(t *testing.T) {
|
||||
recorder := httptest.NewRecorder()
|
||||
err := argocd.translateGrpcCookieHeader(context.Background(), recorder, &session.SessionResponse{
|
||||
Token: "xyz",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "argocd.token=xyz; path=/; SameSite=lax; httpOnly; Secure", recorder.Result().Header.Get("Set-Cookie"))
|
||||
})
|
||||
|
||||
t.Run("TokenIsEmpty", func(t *testing.T) {
|
||||
recorder := httptest.NewRecorder()
|
||||
err := argocd.translateGrpcCookieHeader(context.Background(), recorder, &session.SessionResponse{
|
||||
Token: "",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "argocd.token=; path=/; SameSite=lax; httpOnly; Secure", recorder.Result().Header.Get("Set-Cookie"))
|
||||
})
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,18 +67,25 @@ async function isExpiredSSO() {
|
|||
|
||||
requests.onError.subscribe(async err => {
|
||||
if (err.status === 401) {
|
||||
if (!history.location.pathname.startsWith('/login')) {
|
||||
// Query for basehref and remove trailing /.
|
||||
// If basehref is the default `/` it will become an empty string.
|
||||
const basehref = document
|
||||
.querySelector('head > base')
|
||||
.getAttribute('href')
|
||||
.replace(/\/$/, '');
|
||||
if (await isExpiredSSO()) {
|
||||
window.location.href = `${basehref}/auth/login?return_url=${encodeURIComponent(location.href)}`;
|
||||
} else {
|
||||
history.push(`${basehref}/login?return_url=${encodeURIComponent(location.href)}`);
|
||||
}
|
||||
if (history.location.pathname.startsWith('/login')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isSSO = await isExpiredSSO();
|
||||
// location might change after async method call, so we need to check again.
|
||||
if (history.location.pathname.startsWith('/login')) {
|
||||
return;
|
||||
}
|
||||
// Query for basehref and remove trailing /.
|
||||
// If basehref is the default `/` it will become an empty string.
|
||||
const basehref = document
|
||||
.querySelector('head > base')
|
||||
.getAttribute('href')
|
||||
.replace(/\/$/, '');
|
||||
if (isSSO) {
|
||||
window.location.href = `${basehref}/auth/login?return_url=${encodeURIComponent(location.href)}`;
|
||||
} else {
|
||||
history.push(`${basehref}/login?return_url=${encodeURIComponent(location.href)}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import {DataLoader, Page as ArgoPage, Toolbar, Utils} from 'argo-ui';
|
||||
import {parse} from 'cookie';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import * as React from 'react';
|
||||
import {Observable} from 'rxjs';
|
||||
|
|
@ -21,16 +20,19 @@ export class Page extends React.Component<{title: string; toolbar?: Toolbar | Ob
|
|||
toolbar = toolbar || {};
|
||||
toolbar.tools = [
|
||||
toolbar.tools,
|
||||
// this is a crummy check, as the token maybe expired, but it is better than flashing user interface
|
||||
parse(document.cookie)['argocd.token'] ? (
|
||||
<a key='logout' onClick={() => this.goToLogin(true)}>
|
||||
Logout
|
||||
</a>
|
||||
) : (
|
||||
<a key='login' onClick={() => this.goToLogin(false)}>
|
||||
Login
|
||||
</a>
|
||||
)
|
||||
<DataLoader key='loginPanel' load={() => services.users.get()}>
|
||||
{info =>
|
||||
info.loggedIn ? (
|
||||
<a key='logout' onClick={() => this.goToLogin(true)}>
|
||||
Logout
|
||||
</a>
|
||||
) : (
|
||||
<a key='login' onClick={() => this.goToLogin(false)}>
|
||||
Login
|
||||
</a>
|
||||
)
|
||||
}
|
||||
</DataLoader>
|
||||
];
|
||||
return toolbar;
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue