blob: daf89e116104ea73be555f2b586d68f0a3a466b6 [file] [log] [blame]
package login
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import (
"context"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/config"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/tocookie"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/trafficvault"
"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/trafficvault/backends/disabled"
"github.com/jmoiron/sqlx"
sqlmock "gopkg.in/DATA-DOG/go-sqlmock.v1"
)
var testUser = auth.CurrentUser{
UserName: "admin",
ID: 1,
PrivLevel: 30,
TenantID: 1,
Role: 1,
Capabilities: nil,
}
func TestLogout(t *testing.T) {
mockDB, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("Failed to initialize mock database: %v", err)
}
defer mockDB.Close()
db := sqlx.NewDb(mockDB, "sqlmock")
defer db.Close()
cols := []string{
"priv_level",
"role",
"id",
"username",
"tenant_id",
"capabilities",
}
mock.ExpectBegin()
rows := sqlmock.NewRows(cols)
rows.AddRow(
testUser.PrivLevel,
testUser.Role,
testUser.ID,
testUser.UserName,
testUser.TenantID,
testUser.Capabilities,
)
mock.ExpectQuery("SELECT").WillReturnRows(rows)
mock.ExpectCommit()
cookie := tocookie.GetCookie(testUser.UserName, 24*time.Hour, "secret")
rr := httptest.NewRecorder()
req, err := http.NewRequest(http.MethodPost, "/api/4.0/logout", nil)
if err != nil {
t.Fatalf("Failed to create a request: %v", err)
}
ctx := req.Context()
ctx = context.WithValue(ctx, api.DBContextKey, db)
conf := config.Config{}
conf.ConfigTrafficOpsGolang.DBQueryTimeoutSeconds = 100
ctx = context.WithValue(ctx, api.ConfigContextKey, &conf)
ctx = context.WithValue(ctx, api.ReqIDContextKey, uint64(1))
ctx = context.WithValue(ctx, api.APIRespWrittenKey, false)
ctx = context.WithValue(ctx, auth.CurrentUserKey, testUser)
ctx = context.WithValue(ctx, api.PathParamsKey, map[string]string{})
var tv trafficvault.TrafficVault = &disabled.Disabled{}
ctx = context.WithValue(ctx, api.TrafficVaultContextKey, tv)
ctx, cancelTx := context.WithDeadline(ctx, time.Now().Add(24*time.Hour))
defer cancelTx()
req = req.WithContext(ctx)
req.AddCookie(cookie)
LogoutHandler("test")(rr, req)
if rr.Code != http.StatusOK {
t.Errorf("Expected response code %d, got %d", http.StatusOK, rr.Code)
}
expected := `{"alerts":[{"text":"You are logged out.","level":"success"}]}
`
if rr.Body.String() != expected {
t.Errorf("Expected response body:\n\t%sbut got:\n\t%s", expected, rr.Body.String())
}
cookieFound := false
for _, c := range rr.Result().Cookies() {
if c.Name != tocookie.Name {
continue
}
cookieFound = true
if c.Path != "/" {
t.Errorf("Expected cookie path to be '/', but got: %s", c.Path)
}
if !c.HttpOnly {
t.Errorf("Expected cookie to be HTTP-only, but it wasn't")
}
if time.Second < time.Since(c.Expires) || -time.Second > time.Since(c.Expires) {
t.Errorf("Expected cookie expiration to be within one second of now, but was %s", time.Since(c.Expires))
break
}
parsedCookie, err := tocookie.Parse("test", c.Value)
if err != nil {
t.Errorf("Failed to parse cookie value: %v", err)
break
}
if parsedCookie.ExpiresUnix != c.Expires.Unix() {
t.Errorf("Expected encoded expiration to be %d, but it was %d", c.Expires.Unix(), parsedCookie.ExpiresUnix)
}
if parsedCookie.AuthData != testUser.UserName {
t.Errorf("Incorrect user parsed from cookie; expected '%s' but got: %s", testUser.UserName, parsedCookie.AuthData)
}
}
if !cookieFound {
t.Errorf("Expected handler to set the '%s' cookie, but it didn't", tocookie.Name)
}
}