Skip to content

Commit 73ec440

Browse files
committed
Add security test
1 parent 873bba1 commit 73ec440

File tree

3 files changed

+110
-1
lines changed

3 files changed

+110
-1
lines changed

deps.edn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
; https://opensource.org/licenses/MIT.
66

77
{:deps {io.swagger.parser.v3/swagger-parser {:mvn/version "2.1.25"}}
8+
:paths ["resources" "src"]
89
:aliases {:test {:extra-paths ["test"]
910
:extra-deps {io.github.cognitect-labs/test-runner {:git/tag "v0.5.1" :git/sha "dfb30dd"}
1011
metosin/malli {:mvn/version "0.17.0"}}

resources/security-users.yml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
openapi: 3.1.0
2+
info:
3+
title: Simple User Listing API
4+
version: "1.0.0"
5+
6+
paths:
7+
/users:
8+
get:
9+
operationId: listUsers
10+
security:
11+
- sessionCookieAuth: ["read:user"]
12+
- test: ["one:two"]
13+
responses:
14+
'200':
15+
description: A list of user objects
16+
'401':
17+
description: Unauthorized
18+
/users-single-scheme:
19+
get:
20+
operationId: listUsersSingle
21+
security:
22+
- sessionCookieAuth: ["read:user"]
23+
responses:
24+
'200':
25+
description: OK
26+
/users-no-scope:
27+
get:
28+
operationId: listUsersNoScope
29+
security:
30+
- sessionCookieAuth: []
31+
responses:
32+
'200':
33+
description: OK
34+
/users-no-security:
35+
get:
36+
operationId: listUsersNoSecurity
37+
responses:
38+
'200':
39+
description: OK
40+
41+
components:
42+
securitySchemes:
43+
sessionCookieAuth:
44+
type: apiKey
45+
in: cookie
46+
name: session
47+
description: >
48+
A session-based authentication scheme. The cookie must contain
49+
a valid session ID that identifies the user.
50+
schemas:
51+
User:
52+
type: object
53+
required:
54+
- id
55+
properties:
56+
id:
57+
type: string
58+
format: uuid
59+
description: The unique identifier for a user
60+
email:
61+
type: string
62+
description: Optional email address of the user
63+
name:
64+
type: string
65+
description: Optional name of the user

test/navi/impl_test.clj

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
(ns navi.impl-test
88
(:require
99
[clojure.test :refer [deftest is testing]]
10-
[navi.impl :as i])
10+
[navi.core :as navi]
11+
[navi.impl :as i]
12+
[clojure.java.io :as io])
1113
(:import
1214
[clojure.lang ExceptionInfo]
1315
[io.swagger.v3.oas.models Operation PathItem]
@@ -142,3 +144,44 @@
142144
(is (= {:get {:handler "a handler"
143145
:parameters {:path [:map [:x int?]]}}}
144146
(i/path-item->data path-item handlers))))))
147+
(defn find-route [rts path method]
148+
(some (fn [[p r]]
149+
(when (= p path)
150+
(get r method)))
151+
rts))
152+
153+
(deftest security-requirements-test
154+
(testing "Verifying security requirements from security-users.yml"
155+
;; A dummy map of operationId to handler (the actual function doesn't matter for this test).
156+
(let [handlers {"listUsers" (constantly :ok)
157+
"listUsersSingle" (constantly :ok)
158+
"listUsersNoScope" (constantly :ok)
159+
"listUsersNoSecurity" (constantly :ok)}
160+
api-spec (slurp (io/resource "security-users.yml"))
161+
routes (navi/routes-from api-spec handlers)]
162+
163+
(testing "multiple security schemes"
164+
(let [route (find-route routes "/users" :get)]
165+
(is (some? route) "Should have found /users GET route")
166+
(is (= [["sessionCookieAuth" ["read:user"]]
167+
["test" ["one:two"]]]
168+
(:security route)))))
169+
170+
(testing "single security scheme with scopes"
171+
(let [route (find-route routes "/users-single-scheme" :get)]
172+
(is (some? route) "Should have found /users-single-scheme GET route")
173+
(is (= [["sessionCookieAuth" ["read:user"]]]
174+
(:security route)))))
175+
176+
(testing "single security scheme without scopes"
177+
(let [route (find-route routes "/users-no-scope" :get)]
178+
(is (some? route) "Should have found /users-no-scope GET route")
179+
(is (= [["sessionCookieAuth" []]]
180+
(:security route))
181+
"No scopes should yield an empty vector for that scheme")))
182+
183+
(testing "no security block"
184+
(let [route (find-route routes "/users-no-security" :get)]
185+
(is (some? route) "Should have found /users-no-security GET route")
186+
(is (nil? (:security route))
187+
"Route with no security block should not have :security key"))))))

0 commit comments

Comments
 (0)