Skip to content

Commit

Permalink
web authentication working
Browse files Browse the repository at this point in the history
Signed-off-by: kanishkarj <kanishkarj@hotmail.com>
  • Loading branch information
kanishkarj committed May 19, 2020
1 parent 86edcf7 commit 9d72c5a
Show file tree
Hide file tree
Showing 15 changed files with 381 additions and 295 deletions.
9 changes: 8 additions & 1 deletion Makefile
Expand Up @@ -19,4 +19,11 @@ build-web:
cd web && docker build -t layer5io/dockercon-2020-web:dev .

build-api:
cd api && docker build -t layer5io/dockercon-2020-api:dev .
cd api && docker build -t layer5io/dockercon-2020-api:dev .

dev-run-api: build-api deploy

dev-run-web:
cd web && yarn serve


59 changes: 28 additions & 31 deletions api/main.go
Expand Up @@ -6,58 +6,55 @@ import (
"net/http"
)

func CORSMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Our middleware logic goes here...
// Set CORS headers for the preflight request
if r.Method == http.MethodOptions {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "*")
w.Header().Set("Access-Control-Allow-Headers", "*")
w.Header().Set("Access-Control-Max-Age", "3600")
w.WriteHeader(http.StatusNoContent)
return
}
// Set CORS headers for the main request.
w.Header().Set("Access-Control-Allow-Origin", "*")
next.ServeHTTP(w, r)
})
}

func hello(w http.ResponseWriter, req *http.Request) {
ck, err := req.Cookie("token")
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
return
}
token := ck.Value
if token == "" {
w.WriteHeader(http.StatusUnauthorized)
return
}
token := req.Header.Get("Authorization")
w.Write([]byte("Hello, " + token + ", welcome to dockercon 2020!"))
}

func auth(w http.ResponseWriter, req *http.Request) {
defer req.Body.Close()
data, err := ioutil.ReadAll(req.Body)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
http.SetCookie(w, &http.Cookie{
Name: "token",
MaxAge: 0,
})
w.WriteHeader(http.StatusBadRequest)
return
}
var mp map[string]string
err = json.Unmarshal(data, &mp)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
http.SetCookie(w, &http.Cookie{
Name: "token",
MaxAge: 0,
})
w.WriteHeader(http.StatusInternalServerError)
return
}
username := mp["username"]
if username == "" {
w.WriteHeader(http.StatusUnauthorized)
http.SetCookie(w, &http.Cookie{
Name: "token",
MaxAge: 0,
})
w.WriteHeader(http.StatusBadRequest)
return
}
http.SetCookie(w, &http.Cookie{
Name: "token",
Value: username,
json.NewEncoder(w).Encode(map[string]string{
"token": username,
})
}

func main() {
http.HandleFunc("/hello", hello)
http.HandleFunc("/auth", auth)
http.ListenAndServe(":8080", nil)
mux := http.NewServeMux()
mux.Handle("/hello", CORSMiddleware(http.HandlerFunc(hello)))
mux.Handle("/auth", CORSMiddleware(http.HandlerFunc(auth)))
http.ListenAndServe(":9091", mux)
}
95 changes: 95 additions & 0 deletions config/app.yaml
@@ -0,0 +1,95 @@
# Service to expose web frontend

apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
type: NodePort
selector:
app: web
ports:
- name: http
protocol: TCP
port: 8080
targetPort: 8080
nodePort: 30007
---
# Web frontend

apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
labels:
app: web
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
annotations:
"consul.hashicorp.com/connect-inject": "true"
"consul.hashicorp.com/connect-service-upstreams": "api:9091"
"consul.hashicorp.com/connect-service-protocol": "http"
spec:
containers:
- name: web
image: layer5io/dockercon-2020-web:dev
ports:
- containerPort: 8080
env:
- name: "LISTEN_ADDR"
value: "0.0.0.0:8080"
- name: "UPSTREAM_URIS"
value: "http://localhost:9091"
- name: "NAME"
value: "web"
- name: "MESSAGE"
value: "Hello World"
- name: "HTTP_CLIENT_KEEP_ALIVES"
value: "false"
- name: "TRACING_ZIPKIN"
value: "http://jaeger-collector:9411"

---
# API service version 2

apiVersion: apps/v1
kind: Deployment
metadata:
name: api-deployment-v1
labels:
app: api-v1
spec:
replicas: 1
selector:
matchLabels:
app: api-v1
template:
metadata:
labels:
app: api-v1
annotations:
"consul.hashicorp.com/connect-inject": "true"
"consul.hashicorp.com/service-meta-version": "1"
"consul.hashicorp.com/service-tags": "v1"
"consul.hashicorp.com/connect-service-protocol": "http"
"consul.hashicorp.com/connect-wasm-filter-add_header": "/filters/optimized.wasm"
spec:
containers:
- name: api
image: layer5io/dockercon-2020-api:dev
ports:
- containerPort: 8080
env:
- name: "LISTEN_ADDR"
value: "0.0.0.0:9090"
- name: "NAME"
value: "api-v1"
- name: "MESSAGE"
value: "Response from API v1"
63 changes: 63 additions & 0 deletions config/consul-values.yaml
@@ -0,0 +1,63 @@
global:
image: nicholasjackson/consul-envoy:dev-dev
imageK8S: nicholasjackson/consul-k8s-dev:latest

# Available parameters and their default values for the Consul chart.
# Server, when enabled, configures a server cluster to run. This should
# be disabled if you plan on connecting to a Consul cluster external to
# the Kube cluster.
server:
replicas: 1
bootstrapExpect: 1 # Should <= replicas count

# storage and storageClass are the settings for configuring stateful
# storage for the server pods. storage should be set to the disk size of
# the attached volume. storageClass is the class of storage which defaults
# to null (the Kube cluster will pick the default).
storage: 64Mi
# storageClass: local-path

# Client, when enabled, configures Consul clients to run on every node
# within the Kube cluster. The current deployment model follows a traditional
# DC where a single agent is deployed per node.
client:
enabled: true

# grpc should be set to true if the gRPC listener should be enabled.
# This should be set to true if connectInject or meshGateway is enabled.
grpc: true

ui:
# True if you want to enable the Consul UI. The UI will run only
# on the server nodes. This makes UI access via the service below (if
# enabled) predictable rather than "any node" if you're running Consul
# clients as well.
enabled: true

# True if you want to create a Service entry for the Consul UI.
#
# serviceType can be used to control the type of service created. For
# example, setting this to "LoadBalancer" will create an external load
# balancer (for supported K8S installations) to access the UI.
service:
enabled: true
type: 'NodePort'

# ConnectInject will enable the automatic Connect sidecar injector.
connectInject:
enabled: true
default: false # true will inject by default, otherwise requires annotation

# Requires Consul v1.5+ and consul-k8s v0.8.1+
centralConfig:
enabled: "true"

# defaultProtocol allows you to specify a convenience default protocol if
# most of your services are of the same protocol type. The individual annotation
# on any given pod will override this value. A protocol must be provided,
# either through this setting or individual annotation, for a service to be
# registered correctly. Valid values are "http", "http2", "grpc" and "tcp".
defaultProtocol: "http"

# Specify a container which has Envoy and any referenced filters
imageEnvoy: "nicholasjackson/example-wasm-filter:dev"
23 changes: 5 additions & 18 deletions docker-compose.yaml
Expand Up @@ -14,32 +14,19 @@ services:
- "80"
- "8001"
ports:
- "18000:80"
- "9091:80"
- "18001:8001"

web_service:
image: hashicorp/http-echo
command:
- '-text="Wasm filter test"'
image: layer5io/dockercon-2020-api:dev
networks:
envoymesh:
aliases:
- web_service
expose:
- "5678"
- "9091"
ports:
- "18080:5678"

# wasm_upstream:
# image: wasm-upstream:latest
# networks:
# envoymesh:
# aliases:
# - wasm_upstream
# expose:
# - "8080"
# ports:
# - "8080:8080"
- "9000:9091"

networks:
envoymesh: {}
envoymesh: {}
4 changes: 2 additions & 2 deletions envoy.yaml
Expand Up @@ -71,7 +71,7 @@ static_resources:
hosts:
- socket_address:
address: web_service
port_value: 5678
port_value: 9091
# - name: wasm_upstream
# connect_timeout: 0.25s
# type: STRICT_DNS
Expand All @@ -85,4 +85,4 @@ admin:
address:
socket_address:
address: 0.0.0.0
port_value: 8001
port_value: 8001
12 changes: 12 additions & 0 deletions rate-limit-filter/src/lib.rs
Expand Up @@ -27,8 +27,20 @@ impl UpstreamCall {
}
}

static ALLOWED_PATHS: [&str; 1] = ["/auth"];

impl HttpContext for UpstreamCall {
fn on_http_request_headers(&mut self, _num_headers: usize) -> Action {
if let Some(method) = self.get_http_request_header(":method") {
if method == "OPTIONS" {
return Action::Continue
}
}
if let Some(path) = self.get_http_request_header(":path") {
if ALLOWED_PATHS.binary_search(&path.as_str()).is_ok() {
return Action::Continue
}
}
if let Some(header) = self.get_http_request_header("Authorization") {
let curr = self.get_current_time();
let tm = curr.duration_since(SystemTime::UNIX_EPOCH).unwrap();
Expand Down
2 changes: 2 additions & 0 deletions web/package.json
Expand Up @@ -11,11 +11,13 @@
"axios": "^0.19.2",
"core-js": "^3.6.4",
"vue": "^2.6.11",
"vue-router": "^3.1.6",
"vuetify": "^2.2.11"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.3.0",
"@vue/cli-plugin-eslint": "~4.3.0",
"@vue/cli-plugin-router": "~4.3.0",
"@vue/cli-service": "~4.3.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
Expand Down

0 comments on commit 9d72c5a

Please sign in to comment.