Skip to content
Snippets Groups Projects
Commit 5955a73a authored by Rohith's avatar Rohith
Browse files

Merge pull request #12 from gambol99/units

- adding more units tests
parents 41485b55 0d5d0127
No related branches found
No related tags found
No related merge requests found
......@@ -3,6 +3,8 @@
bin/
release/
tests/
cover.html
cover.out
*.iml
config.yml
......
......@@ -79,6 +79,11 @@ format:
@echo "--> Running go fmt"
@go fmt $(PACKAGES)
coverage:
@echo "--> Running go coverage"
@go test -coverprofile cover.out
@go tool cover -html=cover.out -o cover.html
cover:
@echo "--> Running go cover"
@go test --cover
......
package main
const buildID = "v0.0.5, git+sha: 4c3ee98"
const buildID = "v0.0.5, git+sha: 81b7def"
......@@ -21,6 +21,12 @@ import (
"testing"
)
func TestNewDefaultConfig(t *testing.T) {
if config := newDefaultConfig(); config == nil {
t.Errorf("we should have recieved a config")
}
}
func TestReadConfiguration(t *testing.T) {
testCases := []struct {
Content string
......@@ -60,6 +66,97 @@ redirection_url: http://127.0.0.1:3000
}
}
func TestIsConfig(t *testing.T) {
tests := []struct {
Config *Config
Ok bool
}{
{
Config: &Config{},
},
{
Config: &Config{
DiscoveryURL: "http://127.0.0.1:8080",
},
},
{
Config: &Config{
DiscoveryURL: "http://127.0.0.1:8080",
ClientID: "client",
Secret: "client",
},
},
{
Config: &Config{
Listen: ":8080",
DiscoveryURL: "http://127.0.0.1:8080",
ClientID: "client",
Secret: "client",
RedirectionURL: "http://120.0.0.1",
},
},
{
Config: &Config{
Listen: ":8080",
DiscoveryURL: "http://127.0.0.1:8080",
ClientID: "client",
Secret: "client",
RedirectionURL: "http://120.0.0.1",
Upstream: "http://120.0.0.1",
},
Ok: true,
},
{
Config: &Config{
Listen: ":8080",
SkipTokenVerification: true,
Upstream: "http://120.0.0.1",
},
Ok: true,
},
{
Config: &Config{
DiscoveryURL: "http://127.0.0.1:8080",
ClientID: "client",
Secret: "client",
RedirectionURL: "http://120.0.0.1",
Upstream: "http://120.0.0.1",
},
},
{
Config: &Config{
Listen: ":8080",
DiscoveryURL: "http://127.0.0.1:8080",
ClientID: "client",
Secret: "client",
RedirectionURL: "http://120.0.0.1",
},
},
{
Config: &Config{
Listen: ":8080",
DiscoveryURL: "http://127.0.0.1:8080",
ClientID: "client",
Secret: "client",
RedirectionURL: "http://120.0.0.1",
Upstream: "this should fail",
},
},
}
for i, c := range tests {
if err := c.Config.isValid(); err != nil && c.Ok {
t.Errorf("test case %d, the config should not have errored, error: %s", i, err)
}
}
}
func TestGetOptions(t *testing.T) {
if flags := getOptions(); flags == nil {
t.Errorf("we should have received some flags options")
}
}
func writeFakeConfigFile(t *testing.T, content string) *os.File {
f, err := ioutil.TempFile("", "node_label_file")
if err != nil {
......
package keycloak_proxy
/*
Copyright 2015 All rights reserved.
Licensed 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.
*/
package main
......@@ -27,7 +27,7 @@ import (
const (
prog = "keycloak-proxy"
version = "v0.0.5"
version = "v0.0.6"
author = "Rohith"
email = "gambol99@gmail.com"
description = "is a proxy using the keycloak service for auth and authorization"
......@@ -72,8 +72,6 @@ type Resource struct {
// Config is the configuration for the proxy
type Config struct {
// Verbose switches on debug logging
Verbose bool `json:"verbose" yaml:"verbose"`
// LogRequests indicates if we should log all the requests
LogRequests bool `json:"log_requests" yaml:"log_requests"`
// LogFormat is the logging format
......@@ -116,6 +114,10 @@ type Config struct {
ForbiddenPage string `json:"forbidden_page" yaml:"forbidden_page"`
// SkipTokenVerification tells the service to skipp verifying the access token - for testing purposes
SkipTokenVerification bool
// Verbose switches on debug logging
Verbose bool `json:"verbose" yaml:"verbose"`
// Hostname is a list of hostnames the service should response to
Hostnames []string `json:"hostnames" yaml:"hostname"`
}
// KeycloakProxy is the server component
......
package keycloak_proxy
/*
Copyright 2015 All rights reserved.
Licensed 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.
*/
package main
import (
"net/http"
"testing"
"github.com/gambol99/go-oidc/jose"
"github.com/gin-gonic/gin"
)
func TestEntrypointHandler(t *testing.T) {
proxy := newFakeKeycloakProxy(t)
handler := proxy.entrypointHandler()
tests := []struct {
Context *gin.Context
Secure bool
}{
{
Context: newFakeGinContext("GET", fakeAdminRoleURL), Secure: true,
},
{
Context: newFakeGinContext("GET", fakeAdminRoleURL+"/sso"), Secure: true,
},
{
Context: newFakeGinContext("GET", fakeAdminRoleURL+"/../sso"), Secure: true,
},
{
Context: newFakeGinContext("GET", "/not_secure"),
},
{
Context: newFakeGinContext("GET", oauthURL),
},
}
for i, c := range tests {
handler(c.Context)
if _, found := c.Context.Get(cxEnforce); c.Secure && !found {
t.Errorf("test case %d should have been set secure", i)
}
}
}
func TestAdmissionHandler(t *testing.T) {
proxy := newFakeKeycloakProxy(t)
handler := proxy.admissionHandler()
tests := []struct {
Context *gin.Context
Resource *Resource
UserContext *userContext
HTTPCode int
}{
{
Context: newFakeGinContext("GET", ""),
HTTPCode: http.StatusOK,
},
{
Context: newFakeGinContext("GET", "/admin"),
HTTPCode: http.StatusForbidden,
Resource: &Resource{
URL: fakeAdminRoleURL,
Methods: []string{"GET"},
RolesAllowed: []string{fakeAdminRole},
},
UserContext: &userContext{
roles: []string{},
},
},
{
Context: newFakeGinContext("GET", fakeAdminRoleURL),
HTTPCode: http.StatusOK,
Resource: &Resource{
URL: fakeAdminRoleURL,
Methods: []string{"GET"},
RolesAllowed: []string{fakeAdminRole},
},
UserContext: &userContext{
roles: []string{fakeAdminRole},
claims: jose.Claims{"aud": fakeClientID},
},
},
{
Context: newFakeGinContext("GET", fakeAdminRoleURL+"/sso"),
HTTPCode: http.StatusOK,
Resource: &Resource{
URL: fakeAdminRoleURL,
Methods: []string{"GET"},
RolesAllowed: []string{fakeAdminRole},
},
UserContext: &userContext{
roles: []string{fakeTestRole, fakeAdminRole},
claims: jose.Claims{"aud": fakeClientID},
},
},
{
Context: newFakeGinContext("GET", fakeTestRoleURL),
HTTPCode: http.StatusForbidden,
Resource: &Resource{
URL: fakeAdminRoleURL,
Methods: []string{"GET"},
RolesAllowed: []string{fakeTestRole, "test"},
},
UserContext: &userContext{
roles: []string{fakeTestRole, fakeAdminRole},
claims: jose.Claims{"aud": fakeClientID},
},
},
{
Context: newFakeGinContext("GET", fakeAdminRoleURL),
HTTPCode: http.StatusForbidden,
Resource: &Resource{
URL: fakeAdminRoleURL,
Methods: []string{"GET"},
RolesAllowed: []string{fakeTestRole, "test"},
},
UserContext: &userContext{
roles: []string{fakeTestRole, fakeAdminRole},
},
},
}
for i, c := range tests {
if c.Resource != nil {
c.Context.Set(cxEnforce, c.Resource)
}
if c.UserContext != nil {
c.Context.Set(userContextName, c.UserContext)
}
handler(c.Context)
if c.Context.Writer.Status() != c.HTTPCode {
t.Errorf("test case %d should have recieved code: %d, got %d", i, c.HTTPCode, c.Context.Writer.Status())
}
}
}
......@@ -51,6 +51,15 @@ func TestIsValid(t *testing.T) {
}
}
func TestResourceString(t *testing.T) {
resource := &Resource{
RolesAllowed: []string{"1", "2", "3"},
}
if s := resource.String(); s == "" {
t.Errorf("we should have recieved a string")
}
}
func TestGetRoles(t *testing.T) {
resource := &Resource{
RolesAllowed: []string{"1", "2", "3"},
......
......@@ -16,25 +16,145 @@ limitations under the License.
package main
import (
"bufio"
"io/ioutil"
"net"
"net/http"
"testing"
log "github.com/Sirupsen/logrus"
"github.com/gin-gonic/gin"
"net/url"
)
const (
fakeClientID = "test"
fakeSecret = fakeClientID
fakeAdminRoleURL = "/admin"
fakeTestRoleURL = "/test_role"
fakeTestAdminRolesURL = "/test_admin_roles"
fakeAdminRole = "role:admin"
fakeTestRole = "role:test"
)
func newFakeKeycloakProxy(t *testing.T) *KeycloakProxy {
log.SetOutput(ioutil.Discard)
return &KeycloakProxy{
config: &Config{
DiscoveryURL: "127.0.0.1:",
ClientID: "test_client",
Secret: "test_secret",
ClientID: fakeClientID,
Secret: fakeSecret,
EncryptionKey: "AgXa7xRcoClDEU0ZDSH4X0XhL5Qy2Z2j",
SkipTokenVerification: true,
Scopes: []string{},
RefreshSession: false,
ClaimsMatch: map[string]string{
"aud": fakeClientID,
},
Resources: []*Resource{
&Resource{
URL: "/protect",
URL: fakeAdminRoleURL,
Methods: []string{"GET"},
RolesAllowed: []string{"test_role"},
RolesAllowed: []string{fakeAdminRole},
},
&Resource{
URL: fakeTestRoleURL,
Methods: []string{"GET"},
RolesAllowed: []string{fakeTestRole},
},
&Resource{
URL: fakeTestAdminRolesURL,
Methods: []string{"GET"},
RolesAllowed: []string{fakeAdminRole, fakeTestRole},
},
},
},
}
}
func TestRedirectToAuthorization(t *testing.T) {
context := newFakeGinContext("GET", "/admin")
proxy := newFakeKeycloakProxy(t)
proxy.config.SkipTokenVerification = false
proxy.redirectToAuthorization(context)
if context.Writer.Status() != http.StatusTemporaryRedirect {
t.Errorf("we should have been given a temporary redirect")
}
proxy.config.SkipTokenVerification = true
proxy.redirectToAuthorization(context)
if context.Writer.Status() != http.StatusForbidden {
t.Errorf("we should have been given a forbidden code")
}
}
func TestRedirectURL(t *testing.T) {
context := newFakeGinContext("GET", "/admin")
proxy := newFakeKeycloakProxy(t)
if proxy.redirectToURL("http://127.0.0.1", context); context.Writer.Status() != http.StatusTemporaryRedirect {
t.Errorf("we should have recieved a redirect")
}
if !context.IsAborted() {
t.Errorf("the context should have been aborted")
}
}
func TestAccessForbidden(t *testing.T) {
context := newFakeGinContext("GET", "/admin")
proxy := newFakeKeycloakProxy(t)
proxy.config.SkipTokenVerification = false
if proxy.accessForbidden(context); context.Writer.Status() != http.StatusForbidden {
t.Errorf("we should have recieved a forbidden access")
}
proxy.config.SkipTokenVerification = true
if proxy.accessForbidden(context); context.Writer.Status() != http.StatusForbidden {
t.Errorf("we should have recieved a forbidden access")
}
}
func newFakeResponse() *fakeResponse {
return &fakeResponse{
status: http.StatusOK,
headers: make(http.Header, 0),
}
}
func newFakeGinContext(method, uri string) *gin.Context {
return &gin.Context{
Request: &http.Request{
Method: method,
RequestURI: uri,
URL: &url.URL{
Scheme: "http",
Host: "127.0.0.1",
Path: "uri",
},
},
Writer: newFakeResponse(),
}
}
type fakeResponse struct {
size int
status int
headers http.Header
}
func (r *fakeResponse) Flush() {}
func (r *fakeResponse) Written() bool { return false }
func (r *fakeResponse) WriteHeaderNow() {}
func (r *fakeResponse) Size() int { return r.size }
func (r *fakeResponse) Status() int { return r.status }
func (r *fakeResponse) Header() http.Header { return r.headers }
func (r *fakeResponse) WriteHeader(code int) { r.status = code }
func (r *fakeResponse) Write(content []byte) (int, error) { return len(content), nil }
func (r *fakeResponse) WriteString(s string) (int, error) { return len(s), nil }
func (r *fakeResponse) Hijack() (net.Conn, *bufio.ReadWriter, error) { return nil, nil, nil }
func (r *fakeResponse) CloseNotify() <-chan bool { return make(chan bool, 0) }
......@@ -32,7 +32,7 @@ func TestIsAudience(t *testing.T) {
}
}
func TestGetROles(t *testing.T) {
func TestGetUserRoles(t *testing.T) {
user := &userContext{
roles: []string{"1", "2", "3"},
}
......@@ -52,3 +52,12 @@ func TestIsExpired(t *testing.T) {
t.Errorf("we should have been false")
}
}
func TestIsBearerToken(t *testing.T) {
user := &userContext{
bearerToken: true,
}
if !user.isBearerToken() {
t.Errorf("the bearer token should have been true")
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment