Skip to content

Commit

Permalink
Basic Authentication - #399
Browse files Browse the repository at this point in the history
Code review points.

Add `Dockerfile`

See <#399> for further information.
  • Loading branch information
Mohamed Bana committed Jun 8, 2022
1 parent c4145f8 commit 6489695
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ spec:
app: ext-authz-http-service
spec:
containers:
- image: banaioltd/envoy-auth-basic-http-service:latest
- image: banaioltd/ext-authz-http-service:latest
name: ext-authz-http-service
resources:
limits:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apiVersion: gateway.kusk.io/v1alpha1
kind: StaticRoute
metadata:
name: httpbin
name: ext-authz-http-service
spec:
# should work with localhost, example.org
hosts: ["localhost", "*"]
Expand Down
9 changes: 9 additions & 0 deletions examples/ext-authz/http-service/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM docker.io/library/node:16.14.0-alpine3.15

COPY . /app
WORKDIR /app/http-service
RUN npm install

EXPOSE 9002

CMD ["node", "/app/http-service/server"]
3 changes: 3 additions & 0 deletions examples/ext-authz/http-service/HTTP-SERVICE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# `HTTP-SERVICE`

Taken from <https://github.com/envoyproxy/envoy/tree/main/examples/ext_authz> in particular <https://github.com/envoyproxy/envoy/blob/main/examples/ext_authz/auth/http-service/server.js>.
59 changes: 59 additions & 0 deletions examples/ext-authz/http-service/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const express = require('express')
const auth = require('basic-auth')
const app = express()
const port = process.env.PORT || 9002;

app.use((req, res, next) => {
console.log("headers=", req.headers)
console.log("auth(req)=", auth(req))

const { name: user, pass } = auth(req)
console.log("user=", user)
console.log("pass=", pass)

if (user === 'kubeshop' && pass === 'kubeshop') {
// res.status(200)
// res.writeHead(200);
res.writeHead(200, { "x-current-user": user });

res.end()
} else {
res.status(401)
// res.status(403)

res.end('Unauthorized - hint: credentials are kubeshop:kubeshop')
}
})

app.listen(port, () => console.log(`ext-authz-http-service: server.js listening on port ${port}!`))

//// Taken from https://github.com/envoyproxy/envoy/blob/main/examples/ext_authz/auth/http-service/server.js
// const Http = require("http");
// const path = require("path");

// const tokens = require(process.env.USERS ||
// path.join(__dirname, "..", "users.json"));

// const server = new Http.Server((req, res) => {
// const authorization = req.headers["authorization"] || "";
// const extracted = authorization.split(" ");
// if (extracted.length === 2 && extracted[0] === "Bearer") {
// const user = checkToken(extracted[1]);
// if (user !== undefined) {
// // The authorization server returns a response with "x-current-user" header for a successful
// // request.
// res.writeHead(200, { "x-current-user": user });
// return res.end();
// }
// }
// res.writeHead(403);
// res.end();
// });

// const port = process.env.PORT || 9002;
// server.listen(port);
// console.log(`starting HTTP server on: ${port}`);

// function checkToken(token) {
// return tokens[token];
// }
11 changes: 11 additions & 0 deletions examples/ext-authz/image-build-publish.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env sh
set -euf

docker build --no-cache \
-t kubeshop/kusk-ext-authz-http-service:v0.0.1 \
-t kubeshop/kusk-ext-authz-http-service:latest \
-t kusk-ext-authz-http-service:latest \
-t kusk-ext-authz-http-service:v0.0.1 \
--file ./http-service/Dockerfile .

docker push kubeshop/kusk-ext-authz-http-service:latest
10 changes: 5 additions & 5 deletions pkg/options/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ type AuthOptions struct {

func (o AuthOptions) Validate() error {
return validation.ValidateStruct(&o,
validation.Field(&o.Scheme, validation.In("basic")),
validation.Field(&o.AuthUpstream),
validation.Field(&o.Scheme, validation.Required, validation.In("basic")),
validation.Field(&o.AuthUpstream, validation.Required),
)
}

Expand All @@ -58,7 +58,7 @@ type AuthUpstream struct {

func (o AuthUpstream) Validate() error {
return validation.ValidateStruct(&o,
validation.Field(&o.Host),
validation.Field(&o.Host, validation.Required),
)
}

Expand All @@ -69,7 +69,7 @@ type AuthUpstreamHost struct {

func (o AuthUpstreamHost) Validate() error {
return validation.ValidateStruct(&o,
validation.Field(&o.Hostname, is.Host),
// validation.Field(&o.Port, is.Port), // Do not attempt to validate, otherwise this error, `port: must be either a string or byte slice` occurs.
validation.Field(&o.Hostname, validation.Required, is.Host),
validation.Field(&o.Port, validation.Required), // Do not attempt to validate using `is.Port`, otherwise this error, `port: must be either a string or byte slice` occurs.
)
}
57 changes: 51 additions & 6 deletions pkg/options/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,10 @@ import (
"gopkg.in/yaml.v2"
)

func Test_AuthOptions(t *testing.T) {
func Test_AuthOptions_UnmarshalStrict(t *testing.T) {
t.Parallel()
assert := assert.New(t)

stringToPtr := func(str string) *string {
strPtr := &str
return strPtr
}

input := `
auth:
scheme: basic
Expand Down Expand Up @@ -67,3 +62,53 @@ auth:
assert.NoError(err)
assert.Equal(expected, options.Auth)
}

func Test_AuthOptions_Validate_OK(t *testing.T) {
t.Parallel()
assert := assert.New(t)

authOptions := &AuthOptions{
Scheme: "basic",
PathPrefix: stringToPtr("/login"),
AuthUpstream: AuthUpstream{
Host: AuthUpstreamHost{
Hostname: "example.com",
Port: 80,
},
},
}

options := &SubOptions{
Auth: authOptions,
}

assert.NoError(options.Validate())
// assert.Equal(expected, options.Auth)
}

func Test_AuthOptions_Validate_Error(t *testing.T) {
t.Parallel()
assert := assert.New(t)

authOptions := &AuthOptions{
Scheme: "basic",
PathPrefix: stringToPtr("/login"),
AuthUpstream: AuthUpstream{
Host: AuthUpstreamHost{
// Hostname: "example.com",
// Port: 80,
},
},
}

options := &SubOptions{
Auth: authOptions,
}

assert.EqualError(options.Validate(), "auth: (auth-upstream: (host: (hostname: cannot be blank; port: cannot be blank.).).).")
}

func stringToPtr(str string) *string {
strPtr := &str
return strPtr
}

0 comments on commit 6489695

Please sign in to comment.