Beispiel #1
0
func TestX509(t *testing.T) {
	testCases := map[string]struct {
		Insecure bool
		Certs    []*x509.Certificate

		Opts x509.VerifyOptions
		User UserConversion

		ExpectUserName string
		ExpectOK       bool
		ExpectErr      bool
	}{
		"non-tls": {
			Insecure: true,

			ExpectOK:  false,
			ExpectErr: false,
		},

		"tls, no certs": {
			ExpectOK:  false,
			ExpectErr: false,
		},

		"self signed": {
			Opts:  getDefaultVerifyOptions(t),
			Certs: getCerts(t, selfSignedCert),
			User:  CommonNameUserConversion,

			ExpectErr: true,
		},

		"server cert": {
			Opts:  getDefaultVerifyOptions(t),
			Certs: getCerts(t, serverCert),
			User:  CommonNameUserConversion,

			ExpectErr: true,
		},
		"server cert allowing non-client cert usages": {
			Opts:  x509.VerifyOptions{Roots: getRootCertPool(t)},
			Certs: getCerts(t, serverCert),
			User:  CommonNameUserConversion,

			ExpectUserName: "******",
			ExpectOK:       true,
			ExpectErr:      false,
		},

		"common name": {
			Opts:  getDefaultVerifyOptions(t),
			Certs: getCerts(t, clientCNCert),
			User:  CommonNameUserConversion,

			ExpectUserName: "******",
			ExpectOK:       true,
			ExpectErr:      false,
		},

		"empty dns": {
			Opts:  getDefaultVerifyOptions(t),
			Certs: getCerts(t, clientCNCert),
			User:  DNSNameUserConversion,

			ExpectOK:  false,
			ExpectErr: false,
		},
		"dns": {
			Opts:  getDefaultVerifyOptions(t),
			Certs: getCerts(t, clientDNSCert),
			User:  DNSNameUserConversion,

			ExpectUserName: "******",
			ExpectOK:       true,
			ExpectErr:      false,
		},

		"empty email": {
			Opts:  getDefaultVerifyOptions(t),
			Certs: getCerts(t, clientCNCert),
			User:  EmailAddressUserConversion,

			ExpectOK:  false,
			ExpectErr: false,
		},
		"email": {
			Opts:  getDefaultVerifyOptions(t),
			Certs: getCerts(t, clientEmailCert),
			User:  EmailAddressUserConversion,

			ExpectUserName: "******",
			ExpectOK:       true,
			ExpectErr:      false,
		},

		"custom conversion error": {
			Opts:  getDefaultVerifyOptions(t),
			Certs: getCerts(t, clientCNCert),
			User: UserConversionFunc(func(chain []*x509.Certificate) (user.Info, bool, error) {
				return nil, false, errors.New("custom error")
			}),

			ExpectOK:  false,
			ExpectErr: true,
		},
		"custom conversion success": {
			Opts:  getDefaultVerifyOptions(t),
			Certs: getCerts(t, clientCNCert),
			User: UserConversionFunc(func(chain []*x509.Certificate) (user.Info, bool, error) {
				return &user.DefaultInfo{Name: "custom"}, true, nil
			}),

			ExpectUserName: "******",
			ExpectOK:       true,
			ExpectErr:      false,
		},

		"future cert": {
			Opts: x509.VerifyOptions{
				CurrentTime: time.Now().Add(time.Duration(-100 * time.Hour * 24 * 365)),
				Roots:       getRootCertPool(t),
			},
			Certs: getCerts(t, clientCNCert),
			User:  CommonNameUserConversion,

			ExpectOK:  false,
			ExpectErr: true,
		},
		"expired cert": {
			Opts: x509.VerifyOptions{
				CurrentTime: time.Now().Add(time.Duration(100 * time.Hour * 24 * 365)),
				Roots:       getRootCertPool(t),
			},
			Certs: getCerts(t, clientCNCert),
			User:  CommonNameUserConversion,

			ExpectOK:  false,
			ExpectErr: true,
		},
	}

	for k, testCase := range testCases {
		req, _ := http.NewRequest("GET", "/", nil)
		if !testCase.Insecure {
			req.TLS = &tls.ConnectionState{PeerCertificates: testCase.Certs}
		}

		a := New(testCase.Opts, testCase.User)

		user, ok, err := a.AuthenticateRequest(req)

		if testCase.ExpectErr && err == nil {
			t.Errorf("%s: Expected error, got none", k)
			continue
		}
		if !testCase.ExpectErr && err != nil {
			t.Errorf("%s: Got unexpected error: %v", k, err)
			continue
		}

		if testCase.ExpectOK != ok {
			t.Errorf("%s: Expected ok=%v, got %v", k, testCase.ExpectOK, ok)
			continue
		}

		if testCase.ExpectOK {
			if testCase.ExpectUserName != user.GetName() {
				t.Errorf("%s: Expected user.name=%v, got %v", k, testCase.ExpectUserName, user.GetName())
				continue
			}
		}
	}
}
func TestBasicAuth(t *testing.T) {
	testCases := map[string]struct {
		Header   string
		Password testPassword

		ExpectedCalled   bool
		ExpectedUsername string
		ExpectedPassword string

		ExpectedUser string
		ExpectedOK   bool
		ExpectedErr  bool
	}{
		"no header": {
			Header: "",
		},
		"non-basic header": {
			Header: "Bearer foo",
		},
		"empty value basic header": {
			Header: "Basic",
		},
		"whitespace value basic header": {
			Header: "Basic  ",
		},
		"non base-64 basic header": {
			Header:      "Basic !@#$",
			ExpectedErr: true,
		},
		"malformed basic header": {
			Header:      "Basic " + base64.StdEncoding.EncodeToString([]byte("user_without_password")),
			ExpectedErr: true,
		},
		"empty password basic header": {
			Header:           "Basic " + base64.StdEncoding.EncodeToString([]byte("user_with_empty_password:"******"user_with_empty_password",
			ExpectedPassword: "",
		},
		"valid basic header": {
			Header:           "Basic " + base64.StdEncoding.EncodeToString([]byte("myuser:mypassword:withcolon")),
			ExpectedCalled:   true,
			ExpectedUsername: "******",
			ExpectedPassword: "******",
		},
		"password auth returned user": {
			Header:           "Basic " + base64.StdEncoding.EncodeToString([]byte("myuser:mypw")),
			Password:         testPassword{User: &user.DefaultInfo{Name: "returneduser"}, OK: true},
			ExpectedCalled:   true,
			ExpectedUsername: "******",
			ExpectedPassword: "******",
			ExpectedUser:     "******",
			ExpectedOK:       true,
		},
		"password auth returned error": {
			Header:           "Basic " + base64.StdEncoding.EncodeToString([]byte("myuser:mypw")),
			Password:         testPassword{Err: errors.New("auth error")},
			ExpectedCalled:   true,
			ExpectedUsername: "******",
			ExpectedPassword: "******",
			ExpectedErr:      true,
		},
	}

	for k, testCase := range testCases {
		password := testCase.Password
		auth := authenticator.Request(New(&password))

		req, _ := http.NewRequest("GET", "/", nil)
		if testCase.Header != "" {
			req.Header.Set("Authorization", testCase.Header)
		}

		user, ok, err := auth.AuthenticateRequest(req)

		if testCase.ExpectedCalled != password.Called {
			t.Fatalf("%s: Expected called=%v, got %v", k, testCase.ExpectedCalled, password.Called)
			continue
		}
		if testCase.ExpectedUsername != password.Username {
			t.Fatalf("%s: Expected called with username=%v, got %v", k, testCase.ExpectedUsername, password.Username)
			continue
		}
		if testCase.ExpectedPassword != password.Password {
			t.Fatalf("%s: Expected called with password=%v, got %v", k, testCase.ExpectedPassword, password.Password)
			continue
		}

		if testCase.ExpectedErr != (err != nil) {
			t.Fatalf("%s: Expected err=%v, got err=%v", k, testCase.ExpectedErr, err)
			continue
		}
		if testCase.ExpectedOK != ok {
			t.Fatalf("%s: Expected ok=%v, got ok=%v", k, testCase.ExpectedOK, ok)
			continue
		}
		if testCase.ExpectedUser != "" && testCase.ExpectedUser != user.GetName() {
			t.Fatalf("%s: Expected user.GetName()=%v, got %v", k, testCase.ExpectedUser, user.GetName())
			continue
		}
	}
}