--- /dev/null
+# Pre-set Tmp-String-2 to check correct operator behaviour
+update {
+ &control:Tmp-String-2 := "foo"
+}
+
+# Test "authorize" rest call. Uses http to a GET end point
+rest
+
+debug_control
+
+if (!(&reply:REST-HTTP-Status-Code == 200)) {
+ test_fail
+}
+
+if (!(&control:Tmp-String-0 == "authorize")) {
+ test_fail
+}
+
+if (!(&control:Tmp-String-1 == "GET")) {
+ test_fail
+}
+
+if (!(&control:Tmp-String-1[*] == "/user/<username>/mac/<client>")) {
+ test_fail
+}
+
+if (!(&control:User-Name == "Bob")) {
+ test_fail
+}
+
+# The "op" for setting Tmp-String-2 is ^=
+if (!(&control:Tmp-String-2[0] == "Bob") || !(&control:Tmp-String-2[1] == "foo")) {
+ test_fail
+}
+
+# Reset control attributes
+update control {
+ &Tmp-String-0[*] !* ANY
+ &Tmp-String-1[*] !* ANY
+ &User-Name[*] !* ANY
+}
+
+# Pre-fill NAS-IP-Address to check operator behaviour
+update {
+ &control:NAS-IP-Address := "10.0.0.10"
+}
+
+# Clear previous status code and body
+update reply {
+ &REST-HTTP-Status-Code !* ANY
+ &REST-HTTP-Body !* ANY
+}
+
+# Test "accounting" rest call. Uses https to a POST end point
+rest.accounting
+
+if (!(&reply:REST-HTTP-Status-Code == 200)) {
+ test_fail
+}
+
+if (!(&control:Tmp-String-0 == "accounting")) {
+ test_fail
+}
+
+if (!(&control:Tmp-String-1 == "POST")) {
+ test_fail
+}
+
+if (!(&control:Tmp-String-1[*] == "/user/<username>/mac/<client>")) {
+ test_fail
+}
+
+if (!(&control:User-Name == "Bob")) {
+ test_fail
+}
+
+if (!(&control:Tmp-String-2[0] == "Bob") || !(&control:Tmp-String-2[1] == "Bob") || !(&control:Tmp-String-2[2] == "foo")) {
+ test_fail
+}
+
+# NAS IP Address is passed in body data
+if (!(&control:NAS-IP-Address[0] == "10.0.0.10") || !(&control:NAS-IP-Address[1] == "192.168.1.1")) {
+ test_fail
+}
+
+debug_control
+
+# Clear previous status code and body
+update reply {
+ &REST-HTTP-Status-Code !* ANY
+ &REST-HTTP-Body !* ANY
+}
+
+# Test "authenticate" rest call. Uses http basic authentication
+rest.authenticate
+
+if (!(&reply:REST-HTTP-Status-Code == 200)) {
+ test_fail
+}
+
+if (!(&reply:REST-HTTP-Body == "Section: authenticate, User: Bob, Authenticated: true\n")) {
+ test_fail
+}
+
+# Clear up reply
+update reply {
+ &REST-HTTP-Status-Code !* ANY
+ &REST-HTTP-Body !* ANY
+}
+
+test_pass
--- /dev/null
+#
+# PRE rest_module eval
+#
+# Largely a back port of the rlm_rest tests from v4, with v4 specific functionality removed.
+#
+
+update {
+ &Tmp-String-0 := "$ENV{REST_TEST_SERVER}"
+ &Tmp-Integer-0 := "$ENV{REST_TEST_SERVER_PORT}"
+ &Tmp-Integer-1 := "$ENV{REST_TEST_SERVER_SSL_PORT}"
+ &Tmp-String-1 := "notfound"
+}
+
+# Retrieve a plain text file
+update {
+ &control:Tmp-String-1 := "%{rest:GET http://%{Tmp-String-0}:%{Tmp-Integer-0}/test.txt}"
+}
+
+if (!(&reply:REST-HTTP-Status-Code == 200)) {
+ test_fail
+}
+
+if (!(&control:Tmp-String-1 == "Sample text response\n")) {
+ test_fail
+}
+
+# Clear previous status code and body
+update reply {
+ &REST-HTTP-Status-Code !* ANY
+ &REST-HTTP-Body !* ANY
+}
+
+# Take host from incomming packet
+update {
+ &control:Tmp-String-1 := "%{rest:http://%{Login-IP-Host}:%{Tmp-Integer-0}/test.txt}"
+}
+
+if (!(&reply:REST-HTTP-Status-Code == 200) || !(&control:Tmp-String-1 == "Sample text response\n")) {
+ test_fail
+}
+
+# Clear previous status code and body
+update reply {
+ &REST-HTTP-Status-Code !* ANY
+ &REST-HTTP-Body !* ANY
+}
+
+# Check a "not found" gives a 404 status code
+update {
+ &control:Tmp-String-1 := "%{rest:GET http://%{Tmp-String-0}:%{Tmp-Integer-0}/%{Tmp-String-1}}"
+}
+
+if (!(&reply:REST-HTTP-Status-Code == 404)) {
+ test_fail
+}
+
+# Clear previous status code and body
+update reply {
+ &REST-HTTP-Status-Code !* ANY
+ &REST-HTTP-Body !* ANY
+}
+
+# GET with URL parameters
+update {
+ &Tmp-String-2 := "%{rest:GET http://%{Tmp-String-0}:%{Tmp-Integer-0}/user/%{User-Name}/mac/%{Called-Station-Id}}"
+}
+
+if (!(&reply:REST-HTTP-Status-Code == 200)) {
+ test_fail
+}
+
+if (!(&Tmp-String-2 =~ /"control:Tmp-String-1":\["GET","\\\/user\\\/<username>\\\/mac\\\/<client>"\]/)) {
+ test_fail
+}
+
+if (&Tmp-String-2 =~ /"control:User-Name":\{([^}]+)\}/) {
+ if (!("%{1}" =~ /"value":"Bob"/)) {
+ test_fail
+ }
+} else {
+ test_fail
+}
+
+update {
+ &control:Tmp-String-3 := 'dummy'
+}
+
+update {
+ &control:Tmp-String-2 = "%{json_encode:&NAS-IP-Address}"
+}
+
+# Clear previous status code and body
+update reply {
+ &REST-HTTP-Status-Code !* ANY
+ &REST-HTTP-Body !* ANY
+}
+
+# POST to https with JSON body data
+update {
+ &Tmp-String-2 := "%{rest:POST https://%{Tmp-String-0}:%{Tmp-Integer-1}/user/%{User-Name}/mac/%{Called-Station-Id}?section=accounting %{control:Tmp-String-2}}"
+}
+
+if (!(&reply:REST-HTTP-Status-Code == 200)) {
+ test_fail
+}
+
+if (!(&Tmp-String-2 =~ /"control:Tmp-String-1":\["POST","\\\/user\\\/<username>\\\/mac\\\/<client>"\]/)) {
+ test_fail
+}
+
+if (&Tmp-String-2 =~ /"control:User-Name":\{([^}]+)\}/) {
+ if (!("%{1}" =~ /"value":"Bob"/)) {
+ test_fail
+ }
+} else {
+ test_fail
+}
+
+update {
+ &control:Tmp-String-2 := "NAS=%{NAS-IP-Address}&user=%{User-Name}"
+}
+
+# Clear previous status code and body
+update reply {
+ &REST-HTTP-Status-Code !* ANY
+ &REST-HTTP-Body !* ANY
+}
+
+# POST to https with POST body data
+update {
+ &Tmp-String-2 := "%{rest:POST https://%{Tmp-String-0}:%{Tmp-Integer-1}/post/test?section=dummy %{control:Tmp-String-2}}"
+}
+
+if (!(&reply:REST-HTTP-Status-Code == 200)) {
+ test_fail
+}
+
+if (!(&Tmp-String-2 == "Section: dummy, User: Bob\n")) {
+ test_fail
+}
+
+# Clear previous status code and body
+update reply {
+ &REST-HTTP-Status-Code !* ANY
+ &REST-HTTP-Body !* ANY
+}
+
+# URI with tainted values in the arguments - input argument includes URI argument
+# separator - make sure this doesn't end up generating extra arguments, but gets escaped.
+update {
+ &Tmp-String-2 := "%{rest:GET http://%{Tmp-String-0}:%{Tmp-Integer-0}/user/%{User-Name}/reflect/?station=%{Calling-Station-Id}}"
+}
+
+if (!(&Tmp-String-2 == "{\"station\":\"dummy&unsafe=escaped\"}\n" )) {
+ test_fail
+}
+
+# Zero length untainted value - check parsing doesn't break on zero length string
+update {
+ &Tmp-String-8 := ""
+}
+update {
+ &Tmp-String-2 := "%{rest:http://%{Tmp-String-0}:%{Tmp-Integer-0}/user/%{User-Name}/reflect/%{Tmp-String-8}?station=%{User-Name}}"
+}
+
+if (!(&Tmp-String-2 == "{\"station\":\"Bob\"}\n" )) {
+ test_fail
+}
+
+# Clear previous status code and body
+update reply {
+ &REST-HTTP-Status-Code !* ANY
+ &REST-HTTP-Body !* ANY
+}
+
+# Zero length tainted value - check escaping doesn't break on zero length string
+update {
+ &Tmp-String-2 := "%{rest:http://%{Tmp-String-0}:%{Tmp-Integer-0}/user/%{User-Name}/reflect/%{Tmp-String-9}?station=%{Called-Station-Id}}"
+}
+
+if (!(&Tmp-String-2 == "{\"station\":\"aa:bb:cc:dd:ee:ff\"}\n" )) {
+ test_fail
+}
+
+# Clear previous status code and body
+update reply {
+ REST-HTTP-Status-Code !* ANY
+ REST-HTTP-Body !* ANY
+}
+
+test_pass