Skip to content

Commit fa632a1

Browse files
authored
Merge pull request CactuseSecurity#3704 from tpurschke/develop
develop: upgrade hasura and fix version sorting in db upgrades
2 parents e9a6538 + b1394c5 commit fa632a1

File tree

3 files changed

+110
-100
lines changed

3 files changed

+110
-100
lines changed

inventory/group_vars/apiserver.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ api_hasura_admin_test_password: "not4production"
88
api_user_email: "{{ api_user }}@{{ api_network_listening_ip_address }}"
99
api_home: "{{ fworch_home }}/api"
1010
api_hasura_cli_bin: "{{ fworch_home }}/api/bin/hasura"
11-
api_hasura_version: "v2.48.4"
11+
api_hasura_version: "v2.48.5"
1212
api_project_name: api
1313
api_no_metadata: false
1414
api_rollback_is_running: false
Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,50 @@
1-
2-
# install all upgrades between running version and version currently being installed
1+
# install all upgrades between running version and version currently being installed
32

43
- name: guard - stop when trying anything but an upgrade with existing database
54
fail:
6-
msg: "Error: You chose upgrade on a system without existing database {{ fworch_db_name }}"
5+
msg: "Error: You chose upgrade on a system without existing database {{ fworch_db_name }}"
76
when: db_exists.query_result.0.count == 0
87

98
- name: create upgrade dir
109
file:
11-
path: "{{ database_install_dir }}/upgrade"
12-
state: directory
10+
path: "{{ database_install_dir }}/upgrade"
11+
state: directory
1312
become: true
14-
15-
- set_fact:
16-
installed_version: "{{ old_version }}"
17-
current_version: "{{ product_version }}"
18-
all_upgrades_available: "{{ lookup('fileglob', 'upgrade/*.sql') }}"
19-
upgrade_files: []
13+
14+
- set_fact:
15+
installed_version: "{{ old_version }}"
16+
current_version: "{{ product_version }}"
17+
all_upgrades_available: "{{ lookup('fileglob', 'upgrade/*.sql') }}"
18+
upgrade_files: []
2019

2120
- name: set list of relevant upgrade files (without extension)
2221
set_fact:
23-
upgrade_files: "{{ upgrade_files + [ item | basename | splitext | first | regex_replace('([\\d\\.]+)\\.sql', '\\1') ] }}"
22+
upgrade_files: "{{ upgrade_files + [ item | basename | splitext | first | regex_replace('([\\d\\.]+)\\.sql', '\\1') ] }}"
2423
when: |
25-
item | basename | splitext | first | regex_replace('([\\d\\.]+)\\.sql', '\\1') is version(installed_version, '>=')
26-
and
27-
item | basename | splitext | first | regex_replace('([\\d\\.]+)\\.sql', '\\1') is version(current_version, '<=')
24+
item | basename | splitext | first | regex_replace('([\\d\\.]+)\\.sql', '\\1') is version(installed_version, '>=')
25+
and
26+
item | basename | splitext | first | regex_replace('([\\d\\.]+)\\.sql', '\\1') is version(current_version, '<=')
2827
with_fileglob:
29-
- "upgrade/*.sql"
28+
- "upgrade/*.sql"
3029

31-
- debug:
32-
msg:
33-
- "installed_version: {{ installed_version }}"
34-
- "current_version: {{ current_version }}"
35-
- "all_upgrades_available: {{ all_upgrades_available }}"
30+
- debug:
31+
msg:
32+
- "installed_version: {{ installed_version }}"
33+
- "current_version: {{ current_version }}"
34+
- "all_upgrades_available: {{ all_upgrades_available }}"
3635

3736
- name: Copy relevant upgrade files
3837
copy:
39-
src: "upgrade/{{ item }}.sql"
40-
dest: "{{ database_install_dir }}/upgrade/"
38+
src: "upgrade/{{ item }}.sql"
39+
dest: "{{ database_install_dir }}/upgrade/"
4140
loop: "{{ upgrade_files }}"
4241
become: true
4342

4443
- name: install upgrades
4544
community.postgresql.postgresql_script:
46-
db: "{{ fworch_db_name }}"
47-
path: "{{ database_install_dir }}/upgrade/{{ item }}.sql"
48-
loop: "{{ upgrade_files | sort }}"
45+
db: "{{ fworch_db_name }}"
46+
path: "{{ database_install_dir }}/upgrade/{{ item }}.sql"
47+
loop: "{{ upgrade_files | community.general.version_sort }}"
4948
become: true
5049
ignore_errors: false
5150
become_user: postgres
Lines changed: 84 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,106 +1,117 @@
11
# this playbook contains middleware server tests
22

3-
- name: wait for middleware port to become available
4-
wait_for:
5-
port: "{{ middleware_web_listener_port }}"
6-
host: "{{ middleware_hostname }}"
7-
connect_timeout: 1
8-
delay: 10
9-
timeout: 25
3+
- name: wait for middleware port to become available
4+
ansible.builtin.wait_for:
5+
port: "{{ middleware_web_listener_port }}"
6+
host: "{{ middleware_hostname }}"
7+
connect_timeout: 1
8+
delay: 10
9+
timeout: 25
1010

1111
- name: middleware test get jwt valid creds
12-
uri:
13-
url: https://{{ middleware_hostname }}:{{ middleware_web_listener_port }}/api/AuthenticationToken/Get/
14-
method: POST
15-
headers:
16-
Content-Type: application/json
17-
body:
18-
Username: user1{{ test_postfix }}
19-
Password: "{{ test_user1_pw }}"
20-
body_format: json
21-
validate_certs: false
22-
return_content: true
12+
ansible.builtin.uri:
13+
url: "https://{{ middleware_hostname }}:{{ middleware_web_listener_port }}/api/AuthenticationToken/Get/"
14+
method: POST
15+
headers:
16+
Content-Type: application/json
17+
body:
18+
Username: "user1{{ test_postfix }}"
19+
Password: "{{ test_user1_pw }}"
20+
body_format: json
21+
validate_certs: false
22+
return_content: true
2323
register: sample_jwt
2424
changed_when: false
2525
# environment: "{{ proxy_env }}"
2626

27-
- debug: var=sample_jwt
27+
- ansible.builtin.debug:
28+
var: sample_jwt
2829

29-
- set_fact: jwt_header="{{sample_jwt.content.split('.')[0]}}"
30+
# --- JWT header decode (base64url -> json) ---
31+
- name: extract raw jwt header and payload segments
32+
ansible.builtin.set_fact:
33+
jwt_header_raw: "{{ sample_jwt.content.split('.')[0] }}"
34+
jwt_payload_raw: "{{ sample_jwt.content.split('.')[1] }}"
3035

31-
- debug: var=jwt_header
36+
# pad and translate base64url for header
37+
- name: normalize/pad base64url header
38+
ansible.builtin.set_fact:
39+
jwt_header_b64: >-
40+
{{ jwt_header_raw
41+
| regex_replace('-', '+')
42+
| regex_replace('_', '/')
43+
~ ('=' * ((4 - (jwt_header_raw | length % 4)) % 4)) }}
3244
33-
## adding potentially missing base64 "=" padding to header:
34-
- set_fact: jwt_header="{{ jwt_header }}=" cacheable=true
35-
when: "jwt_header|length % 4 > 0"
36-
loop:
37-
- 1
38-
- 2
39-
- 3
45+
- ansible.builtin.debug: { var: jwt_header_b64 }
4046

41-
- debug: var=jwt_header
47+
- name: decode + parse header json
48+
ansible.builtin.set_fact:
49+
jwt_header: "{{ jwt_header_b64 | b64decode | from_json }}"
4250

43-
- set_fact: jwt_header="{{ jwt_header|b64decode }}"
44-
- debug: var=jwt_header
45-
- set_fact: jwt_type="{{ jwt_header.typ }}"
46-
- debug: var=jwt_type
51+
- ansible.builtin.debug: { var: jwt_header }
52+
53+
- name: pick header 'typ'
54+
ansible.builtin.set_fact:
55+
jwt_type: "{{ jwt_header['typ'] | default(jwt_header.typ, true) }}"
56+
57+
- ansible.builtin.debug: { var: jwt_type }
4758

4859
- name: middleware get jwt test valid creds output
49-
debug:
50-
msg: "ERROR unexpected jwt test result (jwt_type does not match 'JWT'): {{ jwt_type }}"
60+
ansible.builtin.debug:
61+
msg: "ERROR unexpected jwt test result (jwt_type does not match 'JWT'): {{ jwt_type }}"
5162
when: "jwt_type is not match('JWT')"
5263

53-
- set_fact: jwt_encoded_payload="{{sample_jwt.content.split('.')[1]}}"
64+
# --- JWT payload decode (base64url -> json) ---
65+
- name: normalize/pad base64url payload
66+
ansible.builtin.set_fact:
67+
jwt_payload_b64: >-
68+
{{ jwt_payload_raw
69+
| regex_replace('-', '+')
70+
| regex_replace('_', '/')
71+
~ ('=' * ((4 - (jwt_payload_raw | length % 4)) % 4)) }}
5472
55-
- name: show jwt encoded payload pre padding
56-
debug: var=jwt_encoded_payload
57-
## adding potentially missing base64 = padding to payload:
58-
- set_fact: jwt_encoded_payload="{{ jwt_encoded_payload }}=" cacheable=true
59-
when: "jwt_encoded_payload|length % 4 > 0"
60-
loop:
61-
- 1
62-
- 2
63-
- 3
73+
- ansible.builtin.debug:
74+
var: jwt_payload_b64
6475

65-
- name: show jwt encoded payload post padding
66-
debug: var=jwt_encoded_payload
67-
68-
- set_fact: jwt_payload="{{ jwt_encoded_payload|b64decode }}"
76+
- name: decode + parse payload json
77+
ansible.builtin.set_fact:
78+
jwt_payload: "{{ jwt_payload_b64 | b64decode | from_json }}"
6979

7080
- name: show jwt decoded payload
71-
debug: var=jwt_payload
72-
73-
- set_fact: jwt_unique_user_name="{{ jwt_payload.unique_name }}"
74-
when: "'unique_name' in jwt_payload"
81+
ansible.builtin.debug:
82+
var: jwt_payload
7583

76-
- set_fact: jwt_unique_user_name="{{ jwt_payload.name }}"
77-
when: "'name' in jwt_payload"
84+
- name: select username from payload (unique_name or name)
85+
ansible.builtin.set_fact:
86+
jwt_unique_user_name: >-
87+
{{ ( 'unique_name' in jwt_payload ) | ternary(jwt_payload.unique_name, jwt_payload.name) }}
7888
7989
- name: Verify JWT Middleware and Check Valid Credentials, Output User 'user1_test'
80-
debug:
81-
msg: "ERROR: Unexpected JWT test result (username does not match 'user1{{ test_postfix }}'): {{ jwt_unique_user_name }}"
90+
ansible.builtin.debug:
91+
msg: "ERROR: Unexpected JWT test result (username does not match 'user1{{ test_postfix }}'): {{ jwt_unique_user_name }}"
8292
when: "jwt_unique_user_name != 'user1' ~ test_postfix"
8393

94+
# --- negative test: wrong credentials ---
8495
- name: middleware test get jwt wrong creds
85-
uri:
86-
url: https://{{ middleware_hostname }}:{{ middleware_web_listener_port }}/api/AuthenticationToken/Get/
87-
method: POST
88-
headers:
89-
Content-Type: application/json
90-
body:
91-
Username: user1{{ test_postfix }}
92-
Password: wrong-pwd
93-
body_format: json
94-
validate_certs: false
95-
return_content: true
96+
ansible.builtin.uri:
97+
url: "https://{{ middleware_hostname }}:{{ middleware_web_listener_port }}/api/AuthenticationToken/Get/"
98+
method: POST
99+
headers:
100+
Content-Type: application/json
101+
body:
102+
Username: "user1{{ test_postfix }}"
103+
Password: "wrong-pwd"
104+
body_format: json
105+
validate_certs: false
106+
return_content: true
96107
register: sample_jwt
97108
changed_when: false
98109
ignore_errors: true
99110

100-
- debug:
101-
var: sample_jwt
111+
- ansible.builtin.debug:
112+
var: sample_jwt
102113

103114
- name: middleware get jwt test wrong creds output
104-
debug:
105-
msg: "ERROR unexpected jwt test result (not equal 'error: Invalid credentials.'): {{ sample_jwt.content }}"
106-
when: sample_jwt.content is not match(".*error.*Invalid\scredentials\..*")
115+
ansible.builtin.debug:
116+
msg: "ERROR unexpected jwt test result (not equal 'error: Invalid credentials.'): {{ sample_jwt.content }}"
117+
when: sample_jwt.content is not match(".*error.*Invalid\\scredentials\\..*")

0 commit comments

Comments
 (0)