Skip to content

Commit 2dab6d5

Browse files
committed
Added integration tests for OIDC v2 endpoint
1 parent 96d7694 commit 2dab6d5

16 files changed

Lines changed: 191 additions & 40 deletions

File tree

ci/configure_v5.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#!/bin/bash -e
22

3+
source ./ci/oauth/keycloak/keycloak_functions.sh
4+
35
cat << "CONFIGURE" | docker exec -i $(docker-compose ps -q conjur_5) bash
46
set -e
57
@@ -11,5 +13,7 @@ done
1113
1214
# So we fail if the server isn't up yet:
1315
curl -o /dev/null -fs -X OPTIONS http://localhost > /dev/null
14-
/scripts/fetch_certificate
1516
CONFIGURE
17+
18+
fetch_keycloak_certificate
19+
create_keycloak_users

ci/oauth/keycloak/create_client

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/sh
2+
3+
4+
keycloak/bin/kcreg.sh config credentials \
5+
--server http://localhost:8080/auth \
6+
--realm master \
7+
--user "$KEYCLOAK_USER" \
8+
--password "$KEYCLOAK_PASSWORD"
9+
10+
keycloak/bin/kcreg.sh create \
11+
-s clientId="$KEYCLOAK_CLIENT_ID" \
12+
-s "redirectUris=[\"$KEYCLOAK_REDIRECT_URI\"]" \
13+
-s "secret=$KEYCLOAK_CLIENT_SECRET"
14+
15+
# Enable direct access to get an id token with username & password
16+
keycloak/bin/kcreg.sh update conjurClient -s directAccessGrantsEnabled=true
17+
18+
keycloak/bin/kcreg.sh get "$KEYCLOAK_CLIENT_ID" | jq '.secret'

ci/oauth/keycloak/create_user

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/sh
2+
3+
echo "login as admin with user $KEYCLOAK_USER"
4+
5+
keycloak/bin/kcadm.sh config credentials \
6+
--server http://localhost:8080/auth \
7+
--realm master \
8+
--user "$KEYCLOAK_USER" \
9+
--password "$KEYCLOAK_PASSWORD"
10+
11+
echo "creating user $1 with email $3"
12+
13+
keycloak/bin/kcadm.sh create users \
14+
-s username="$1" \
15+
-s email="$3" \
16+
-s enabled=true
17+
18+
echo "setting password of user $1 to $2"
19+
keycloak/bin/kcadm.sh set-password \
20+
--username "$1" \
21+
-p "$2"

ci/oauth/keycloak/keycloak_functions.sh

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -55,24 +55,6 @@ function create_keycloak_users() {
5555
'$KEYCLOAK_APP_USER' \
5656
'$KEYCLOAK_APP_USER_PASSWORD' \
5757
'$KEYCLOAK_APP_USER_EMAIL'
58-
59-
echo "Creating second user 'bob' in Keycloak"
60-
61-
# Note: We want to pass the bash command thru without expansion here.
62-
# shellcheck disable=SC2016
63-
_create_keycloak_user \
64-
'$KEYCLOAK_SECOND_APP_USER' \
65-
'$KEYCLOAK_SECOND_APP_USER_PASSWORD' \
66-
'$KEYCLOAK_SECOND_APP_USER_EMAIL'
67-
68-
echo "Creating user in Keycloak that will not exist in conjur"
69-
70-
# Note: We want to pass the bash command thru without expansion here.
71-
# shellcheck disable=SC2016
72-
_create_keycloak_user \
73-
'$KEYCLOAK_NON_CONJUR_APP_USER' \
74-
'$KEYCLOAK_NON_CONJUR_APP_USER_PASSWORD' \
75-
'$KEYCLOAK_NON_CONJUR_APP_USER_EMAIL'
7658
}
7759

7860
function wait_for_keycloak_server() {
@@ -85,5 +67,5 @@ function fetch_keycloak_certificate() {
8567
# Fetch SSL cert to communicate with keycloak (OIDC provider).
8668
echo "Initialize keycloak certificate in conjur server"
8769
docker-compose exec -T \
88-
conjur /oauth/keycloak/scripts/fetch_certificate
70+
conjur_5 /scripts/fetch_certificate
8971
}

ci/oauth/keycloak/wait_for_server

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env bash
2+
3+
SERVER_HEALTH_CHECK_URL="http://localhost:8080/"
4+
SERVER_IS_READY="N0"
5+
6+
function print_help() {
7+
cat << EOF
8+
Wait for keycloak server to start, the script should run from inside keycloak container
9+
Example:
10+
./wait_for_server <service-name>
11+
EOF
12+
}
13+
14+
function input_validation() {
15+
local args_number="$#"
16+
if [[ ${args_number} -ne 0 ]] ; then
17+
echo "Error: invalid arguments"
18+
print_help
19+
exit 1
20+
fi
21+
}
22+
23+
function wait_for_keycloak() {
24+
for i in {1..40}; do
25+
sleep=5
26+
set_server_readiness
27+
28+
if [[ "${SERVER_IS_READY}" == "YES" ]] ; then
29+
echo "Keycloak server is up and ready"
30+
return 0
31+
fi
32+
33+
echo "Keycloak not ready yet sleep number $i for $sleep seconds"
34+
sleep "$sleep"
35+
done
36+
37+
echo "Error with keycloak server start or it is too slow"
38+
exit 1
39+
}
40+
41+
function set_server_readiness()
42+
{
43+
curl --silent --output /dev/null "${SERVER_HEALTH_CHECK_URL}"
44+
local ret_code=$?
45+
echo "Return code of accessing ${SERVER_HEALTH_CHECK_URL} is: ${ret_code}"
46+
if [[ "${ret_code}" -eq 0 ]] ; then
47+
SERVER_IS_READY="YES"
48+
fi
49+
}
50+
51+
function main() {
52+
input_validation "$@"
53+
wait_for_keycloak
54+
}
55+
56+
main "$@"

conjur-api.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,5 @@ Gem::Specification.new do |gem|
3737
gem.add_development_dependency 'yard'
3838
gem.add_development_dependency 'fakefs'
3939
gem.add_development_dependency 'pry-byebug'
40+
gem.add_development_dependency 'nokogiri'
4041
end

docker-compose.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ services:
44
image: postgres:9.3
55

66
conjur_5:
7-
image: cyberark/conjur
7+
image: cyberark/conjur:edge
88
command: server -a cucumber
99
environment:
1010
DATABASE_URL: postgres://postgres@pg/postgres
@@ -26,7 +26,7 @@ services:
2626
- KEYCLOAK_APP_USER_EMAIL=alice@conjur.net
2727
- DB_VENDOR=H2
2828
- KEYCLOAK_CLIENT_ID=conjurClient
29-
- KEYCLOAK_REDIRECT_URI=http://conjur:3000/authn-oidc/keycloak/cucumber/authenticate
29+
- KEYCLOAK_REDIRECT_URI=http://conjur_5/authn-oidc/keycloak/cucumber/authenticate
3030
- KEYCLOAK_CLIENT_SECRET=1234
3131
- KEYCLOAK_SCOPE=openid
3232
ports:
@@ -54,6 +54,7 @@ services:
5454
- ./features/reports:/src/conjur-api/features/reports
5555
- ./coverage:/src/conjur-api/coverage
5656
- authn_local_5:/run/authn-local-5
57+
- ./ci/oauth/keycloak:/scripts
5758
environment:
5859
CONJUR_APPLIANCE_URL: http://conjur_5
5960
CONJUR_VERSION: 5

features/authn.feature

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Feature: Authenticate with Conjur
2+
3+
Background:
4+
Given I setup a keycloak authenticator
5+
6+
Scenario: Authenticate with OIDC state and code
7+
When I retrieve the login url for OIDC authenticator "keycloak"
8+
And I retrieve auth info for the OIDC provider with username: "alice" and password: "alice"
9+
And I run the code:
10+
"""
11+
$conjur.authenticator_enable "authn-oidc", "keycloak"
12+
Conjur::API.authenticator_authenticate("authn-oidc", "keycloak", options: @auth_body)
13+
"""
14+
Then the JSON should have "payload"

features/step_definitions/api_steps.rb

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,37 @@
1616
fail "The provided block did not raise an error"
1717
end
1818
end
19+
20+
Given(/^I retrieve the login url for OIDC authenticator "([^"]+)"$/) do |service_id|
21+
provider = $conjur.authentication_providers("authn-oidc").select {|provider_details| provider_details["service_id"] == service_id}
22+
@login_url = provider[0]["redirect_uri"]
23+
puts @login_url
24+
end
25+
26+
Given(/^I retrieve auth info for the OIDC provider with username: "([^"]+)" and password: "([^"]+)"$/) do |username, password|
27+
res = Net::HTTP.get_response(URI(@login_url))
28+
raise res if res.is_a?(Net::HTTPError) || res.is_a?(Net::HTTPClientError)
29+
30+
all_cookies = res.get_fields('set-cookie')
31+
puts all_cookies
32+
cookies_arrays = Array.new
33+
all_cookies.each do |cookie|
34+
cookies_arrays.push(cookie.split('; ')[0])
35+
end
36+
37+
html = Nokogiri::HTML(res.body)
38+
post_uri = URI(html.xpath('//form').first.attributes['action'].value)
39+
40+
http = Net::HTTP.new(post_uri.host, post_uri.port)
41+
http.use_ssl = true
42+
request = Net::HTTP::Post.new(post_uri.request_uri)
43+
request['Cookie'] = cookies_arrays.join('; ')
44+
request.set_form_data({'username' => username, 'password' => password})
45+
46+
response = http.request(request)
47+
48+
if response.is_a?(Net::HTTPRedirection)
49+
response_details = URI.decode_www_form(URI(response['location']).query)
50+
@auth_body = {state: response_details.assoc('state')[1], code: response_details.assoc('code')[1]}
51+
end
52+
end

features/step_definitions/policy_steps.rb

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@
1313
expect(@user_api_key).to be
1414
end
1515

16+
Given(/^a user "([^"]+)"$/) do |user_id|
17+
response = $conjur.load_policy 'root', <<-POLICY
18+
- !user #{user_id}
19+
POLICY
20+
@user = $conjur.resource("cucumber:user:#{user_id}")
21+
@user_api_key = response.created_roles["cucumber:user:#{user_id}"]['api_key']
22+
expect(@user_api_key).to be
23+
end
24+
1625
Given(/^a new delegated user$/) do
1726
# Create a new host that is owned by that user
1827
step 'a new user'
@@ -88,26 +97,38 @@
8897
8998
- !variable claim-mapping
9099
91-
- !variable scope
92-
93100
- !variable nonce
94101
- !variable state
102+
103+
- !variable redirect-uri
104+
105+
- !group users
106+
107+
- !permit
108+
role: !group users
109+
privilege: [ read, authenticate ]
110+
resource: !webservice
111+
112+
- !user alice
113+
- !grant
114+
role: !group conjur/authn-oidc/keycloak/users
115+
member: !user alice
95116
POLICY
96117
@provider_uri = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/provider-uri")
97118
@client_id = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/client-id")
98119
@client_secret = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/client-secret")
99120
@name = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/name")
100121
@claim_mapping = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/claim-mapping")
101-
@scope = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/scope")
102122
@nonce = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/nonce")
103123
@state = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/state")
124+
@redirect_uri = $conjur.resource("cucumber:variable:conjur/authn-oidc/keycloak/redirect-uri")
104125

105126
@provider_uri.add_value "https://keycloak:8443/auth/realms/master"
106127
@client_id.add_value "conjurClient"
107128
@client_secret.add_value "1234"
108-
@claim_mapping.add_value "map"
109-
@scope.add_value "openid"
110-
@nonce.add_value "dont-use-this-again"
111-
@state.add_value "test-state"
129+
@claim_mapping.add_value "preferred_username"
130+
@nonce.add_value SecureRandom.uuid
131+
@state.add_value SecureRandom.uuid
112132
@name.add_value "keycloak"
133+
@redirect_uri.add_value "http://conjur_5/authn-oidc/keycloak/cucumber/authenticate"
113134
end

0 commit comments

Comments
 (0)