Compare commits
21 Commits
ba820e428e
...
dedupe_fea
| Author | SHA1 | Date | |
|---|---|---|---|
| 61bea5fb6e | |||
| c835a9deb0 | |||
| b862a3f686 | |||
| bc00515c1b | |||
| 60f9aa05a0 | |||
| 4705649ae8 | |||
| 5acaffc224 | |||
| 0a1b901b12 | |||
| 440c13cc49 | |||
| 9b9557105c | |||
| af360d7793 | |||
| 452e6189e4 | |||
| 7e4fb66fc6 | |||
| 213f560c4a | |||
| 8449578424 | |||
| 1adcc04efc | |||
| 0e5de99f55 | |||
| 0dae53017d | |||
| 934937feb0 | |||
| dcb6850306 | |||
| f264f90f3b |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,5 +1,4 @@
|
||||
/target/
|
||||
/config/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
### STS ###
|
||||
@@ -30,6 +29,8 @@
|
||||
/.nb-gradle/
|
||||
/cygnus-onprem-app/target
|
||||
/cygnus-cloud-client/target
|
||||
/cygnus-installer/src/test
|
||||
/cygnus-cloud-service/target
|
||||
/cygnus-installer/src/target
|
||||
/cygnus-installer/target
|
||||
/cygnus-onprem-db/target
|
||||
/cygnus-lib/target
|
||||
|
||||
8
.vscode/launch.json
vendored
8
.vscode/launch.json
vendored
@@ -59,14 +59,18 @@
|
||||
"REDIS_HOST": "103.125.129.116",
|
||||
"REDIS_PORT": "7901",
|
||||
"REDIS_PASSWORD": "M@triXR3d1s@6202",
|
||||
"REDIS_DATABASE": "1",
|
||||
"REDIS_SSL": "false",
|
||||
"CYGNUS_QUERY_CACHE_ENABLED": "false",
|
||||
"CYGNUS_CLOUD_BASE_URL": "http://localhost:8090",
|
||||
"CYGNUS_TOKEN_URL": "http://localhost:8090/oauth2/token",
|
||||
"CYGNUS_CLIENT_ID": "matrix",
|
||||
"CYGNUS_INSTALLATION_ID": "matrix-delhi-cygnus-01",
|
||||
"CYGNUS_CLIENT_ASSERTION": "file:${workspaceFolder}/matrix-installation/config/machine-assertion.jwt",
|
||||
"CYGNUS_CLIENT_ASSERTION": "file:${workspaceFolder}/config/clients/matrix/matrix-matrix-delhi-cygnus-01-assertion.jwt",
|
||||
"CYGNUS_LOGIN_KEY_ID": "cygnus-login-2026-01",
|
||||
"CYGNUS_LOGIN_PUBLIC_KEY": "file:${workspaceFolder}/matrix-installation/config/keys/login-public.pem",
|
||||
"CYGNUS_LOGIN_PUBLIC_KEY": "file:${workspaceFolder}/config/keys/login-public.pem",
|
||||
"CYGNUS_PAYLOAD_PRIVATE_KEY": "file:${workspaceFolder}/config/keys/case-save-private.pem",
|
||||
"CYGNUS_PAYLOAD_PUBLIC_KEY": "file:${workspaceFolder}/config/keys/case-save-public.pem",
|
||||
"CYGNUS_CLOUD_REQUEST_TIMEOUT": "PT10S",
|
||||
"CYGNUS_TOKEN_REFRESH_SKEW": "PT30S"
|
||||
},
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
eyJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.rf8bViJPb5bRJHFamVoCftE0TLA1Gz7JyGnfcjtKEx3KiUL4SSbgYSUQlsKhCt8VJMWE--UpgbkM0Bv3pFVsMF_uh693MhFstEy_A6S3MODjoUV_bMLa_Zr1yH2Jwzud4LSyw-ctJ7G-vO8S_I6YML0HV5kNbobdFmMfXFLGKssVmM_Km0m57ZgSjj3zRii0cKpmdwwSbWoJC2y519TpKhIja0OZAoN1oB3IVKvERlFYCQYUpQmcRkzULGrlSoLIm9iqbRX4qMGhGISwVS6JdVtn9WjpSjF3xkUxN_QsVuYKYFL_kEKWSNepIcfoip7Ag9Qw_S1RZA_KO908MgrzGRbs2UIpxY9sAM8yZ-k1NTk0swV836s5pdDIP3PHovcd6iR8mqWBPt7mq7ES98vNeCZxqPLB_b1JuNfKsbLPdRIvEk2DTjZHeEi-yA1yl5uMi_1f4la6mgy65u_jLL_Ow28uZtj-8yQ3dR4lF3K7tkxQaB4LQiH5nl6lXEndpoPe.Cpu6VoHf2ptCue_L.uH-Pq1WZN-x_c71Iyx8X1QJa1JZRp9sYta9iUOmQ4W8x4Qh2wYm-_tpr8FEw56MLvIb8IH_gHVVLAJgXTmCZhyo26vJlPCtnMMPYFDrPRzTJv9Ewg7RMpsAh_kXFFK4UJ6Tgt_r7Tg_bnVOTKXodUjl3wVdMowZRX_ua-gKwLU-2LDWdqIRmuFDSOkMb1sFBZLPyjWHg_rThs-RwVa4YJdDi74s-L0WX0xRPXzeovu1-xvOgZ0xYf0ScbsFQgvK-JwAxOWsB1WKeHRqnnx5-apK6qtzhpiJ30c7ukPlrg2nieuJvkXOVuKBKXLVRLSViOH4HU76DD96btDUA0Cg2kEURpepucX0VWPyB7K3xb9v1AT42TUkW9wZzdmIs9saRo-ItuWzlCezvapLIsbqmYCs_rW2J3KgqXrUyy2mptn32sqaqQZnlNVu4wwboPCCrbl2MG5CYlYKrwaOHNg611j8sCDkIptm_UmPFnOnzvQYwURuDSgzswTIV5bTd_58yxag2yWwiMdGLMDbxxSUPQ6a4EbuDkqwmGBTSLiG7SaSFchSg6o9EflqK6k-u_rlixCxmfg1A6sa7nloW17dOxDzGKtmn9lBoaskL97nNrhP6ptftak7j4TIZulz1FUOSVoR8kXK8RNQMj-b6rg_MdSO9Ecq5hZsza1SzjkzKZvV-tpP6Wl6-rszCH6g3DIQAWN5aWdUkwuya1HqDDyVPbUOVQPsp4nhVC24QmnlbcqFwQdoCrikYKyX3Snc0H6_K4z9c6nURAdj6THwHmA9BfHtJniI_rEIvkmBk3yndi-H5eAjtxIoYSFQrSTWEFhgvk6bAKoR_xb_cHgzKOxYLBiO_FifkjkFDOlkVBuYnZEp3oRePDKgMDfL5Oxjuie4u-8yrH52Cd32yQzbvGplaXLLeEDf3i71dcz4LkO5DknScWG3G_SbKBpjlse-GKe3XYqRXeRIYLpyiX1MXph0b-Q.dvHU75ZR8wJFxoSacfkthw
|
||||
40
config/clients/matrix/matrix-signing-private.pem
Normal file
40
config/clients/matrix/matrix-signing-private.pem
Normal file
@@ -0,0 +1,40 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
M/D4ZjXsfrW//BMF6+w2Bh4=
|
||||
-----END PRIVATE KEY-----
|
||||
11
config/clients/matrix/matrix-signing-public.pem
Normal file
11
config/clients/matrix/matrix-signing-public.pem
Normal file
@@ -0,0 +1,11 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAloJtGMOLcTNWe1IgdrT8
|
||||
uYucI1Vs02WjyUPZ7Po51iC67QmGdG0InzlBJYdkYtTz8eda+qArZMNGB0ChFs/7
|
||||
xKPKASkMvVcrm4IYbth0DEIkXWAL7YXsWd8qdS+KsnxuC6TqvuA9Xq/PX4RmtAq4
|
||||
bl0/1T2HZjJs53/b73l5NehcseZU129w+5lBqDwW5xh+1VnXNbc96za7BFfQSnfg
|
||||
9WwaWSpo8Y57XATnV7s46yT8gNKM29INHJXs4aIrQ9tcLnTbDz9nhGceNgec3AhO
|
||||
zc4TyCPugUiG9WD4ehsQr+7Cp30RqT5l9ZPvoBTpAdHLZ1r/jB+qY6+WkY6EsOJW
|
||||
2xg9bUYoHXjMiFdi8OLXC4NTAPUquFOaIMfjxGaYQc8NoDMFiq3qdTWi2ndCOoxX
|
||||
yFxYRP5pYs/oA46UAHZsCHaspjvl9jfR/abCALBtsFLwpLA9qqBws5ojXFH//UoX
|
||||
E7dXnJziCFQNyJOhXtIhbQhtb3wJc6WSLtDrRpFtaJudAgMBAAE=
|
||||
-----END PUBLIC KEY-----
|
||||
40
config/keys/access-token-private.pem
Normal file
40
config/keys/access-token-private.pem
Normal file
@@ -0,0 +1,40 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
m/lDtrY4EpMy9FSQD1zb+qE=
|
||||
-----END PRIVATE KEY-----
|
||||
11
config/keys/access-token-public.pem
Normal file
11
config/keys/access-token-public.pem
Normal file
@@ -0,0 +1,11 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAvyfuM67QxEonEvC2Vf21
|
||||
P+fxo406Z4C+zNzxH/8tCPhMH94Sklt10WXqSfQFfZbhJPVYoZL8m0NDI7ozI7lI
|
||||
MPAhAVfcFOzO6VqpFGrzMgMqmnWLrxRsL3y1rjB3LnE84W+ATcS/mlk6rwbCfrSo
|
||||
RRlY3i79ol8h36jhhaHT2/iGGO3uvqAQK334lQEOlqr+YL4Kkr/GMOm86bE4PcZS
|
||||
JgCTAnlCQC7TUu6jGWuocmI1nNwLXPjQvXgc+HKtJEqFGf+a0fty9fLgaR2yIzlM
|
||||
9i31r3kjeKzqVe2DeLTbttd8bVWU4/KmGg8rEchtwC8wR4inuDUjwJ3FwmdBrvDp
|
||||
Ga1AM8yofdbs73Lv2EgkvRLvlgaWiX2P6KdlKGHeaDj9v0YWJbiFM4rc9y5hD3lG
|
||||
2unhpvP/49OFXVBT2/pm86LmxSlwsun3G2LKNOXI646jhdVHQkIVcBiHTHYQOe9/
|
||||
xLqx3ZiEM7witbzuJnxIkbj/8OFgH+WDUmTQVXtbz7vdAgMBAAE=
|
||||
-----END PUBLIC KEY-----
|
||||
40
config/keys/assertion-decryption-private.pem
Normal file
40
config/keys/assertion-decryption-private.pem
Normal file
@@ -0,0 +1,40 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIG/gIBADANBgkqhkiG9w0BAQEFAASCBugwggbkAgEAAoIBgQC1lzvnT5zHANwb
|
||||
+W+kQebd/EWCnlfl1/3SznVHhKEqlXp2YNFhedWKX0aZesl/9oYCqux/plS9lYms
|
||||
AnY47Zda3y1ypqOdpZ0zfcGsf9DO1MmSgYdkzXEtjkSlFpajUtobaA0axrEbQ431
|
||||
PV6YqLtcMRwj0uZz+aE/pK65Se8bCrVnjfe+oah2iuRT5PaMJ9+WHB96e8Fw6TgY
|
||||
lmgkWViyPL0O2WFrvQwml1UVZ9/GzhQGGGSNyRvsZsNNXFrfG/PU0RuRjb6iH+0m
|
||||
a4i66kDsDpOd9g/Vg9c8xFAW1I9oow54pbknkiiu+BAqvgLvgdH2IGiMk3agnr8G
|
||||
N8BrPs/yTLAuPa6j2Al6Y6bXDPwdnJmzPjzYYdrTCqlRwV84ivShMyIm28uf8VJh
|
||||
VvnG82DfFaIY8yO7fZnj1dNftXFMOwiMbHnC0N3gbwgtLfJSUrDTK58dpybLwWf4
|
||||
+WT5e3MFvPqurh+tX3f/eZ9Uw8aAEPHyYuNUmi88GdcoFJf5J1sCAwEAAQKCAYAK
|
||||
nLn9fKOW5a/3Wo5xtQA+/N07EvHkFslYpoQoF9IrYOz1OhdCcRJPsd24XnqkJc4T
|
||||
HdYQZ7IQGksfaE1sakYsI1rOlnp9Xg5f0fudjyKu07SsATHebDsvBF9ynm1TQiZI
|
||||
773EUNRM2ZfUOy/qEAJTEvOoDE03feE0jPVBEtcMZ4XOdXeDBoOH2foaBQl7i2D/
|
||||
rskQKWdWp+qFVVTkuuv6Dp6l3YJZ/4RURQfN5nIndiepa4eE2bnuCNtlC/6rh0CR
|
||||
fPSI+i7eg9X8lCiqC4WHbyXp4zrqBbw60RkoYedyhWZE+pAsTnh1jxRQoFXUs03Z
|
||||
XV3aD3gJLwUlIOf65kvLTTo1o/V2uyNZJSzFDNvVJrFIg0AqwzAgaY5kjbVXlf4G
|
||||
GmjacP56TADbs/fZSRMjibGP+KsbiVbc1Mnio4co+9lyRMtwXe4TUUa3GOoaMN8a
|
||||
LzT+5geVlZ1koQuofwfXFCKPaAe/SVFLNHsp/eyO6HCT9dUGXOxgoT1pL+/k6dEC
|
||||
gcEA22uySiIOJelq1cN7s+CRxsn8mdx4eZHoc067heutxocYp/pFdJKmY5Qk/h5e
|
||||
uC+/hsiWOS1KC2JVSi/fo7L3f1wttCQ5GLdhnp7umTGmDmFtEyn6b1EOai+nvjow
|
||||
cqZDMY1jNpiLXnSRSplXUwE04RQ/4+z29GlIRGvaXkI/ovcBJ2RlJF2hydFbBOlK
|
||||
vH12EtURrTgU9y5UJR6j8evmmSOv5ufKOX3FUKFNyau2kwYZD3BPuFGLlDrIN4Ic
|
||||
NRK/AoHBANPdDfqjtlIOXv7Va2SaOOhDkGV6MHlx+5VeUkt1Qh9yIcVihMCXL61o
|
||||
35BOd10TmyV4OZDwIIIMiHim4ofDAnOsXWOhNKlu2qN0HY6gDmfTrQM8L0sHyErM
|
||||
YY1fOAtRiTEOOIgikj/8E1KTJ2HWVnZDWUXaQVnU7Vmn0b3Yq/IN/impL627ZKTl
|
||||
dg45nNEfVhXfoXv+4O3Cmkt4WGM4XaDesmoGSkTjZaXFCzH9SgWSs7JClgDzCJ14
|
||||
QSzn96G+ZQKBwFwugaetaP46cvy9dKHcTcITJ8FII4EHcH3I7PVVTxthtFUVysov
|
||||
tiGNooD0J10AClnIuXvp7/qaZDSXqj/utxXVlwngUfB1Uli+coT/m8Dc42Mytpi/
|
||||
l+u6e6FqduIjwYT23mCYc6zKEiQiCdLAZgPNaw4JhrKl7It6ODJzaKLBXMW84tUF
|
||||
VSwhfTix/gj0OH+u7g80yXITD5zMo5nGPonFuWerp4TBtvyp17FLJ5fa7vpSd9t6
|
||||
vsYWb/kJ+2m8pwKBwQDTVvyd3Hd/7UQH0x9Y8Jr53oQJJlV6oCBGBRv0l9jJA5H6
|
||||
k2c3stjlk+sHya46U9d9DivmkBLth9EPAfKRWQ92EifqvaGJrsI9MRRW9QTJv5cj
|
||||
1gKbRv0e2DgrzSNb7w76t2PfMRVQ7ITd51rutt/zAwXnr2tnUAcgW07XoW8Me7bh
|
||||
Ghsso/UmpJsaX5A175txIG63AS6hHnHJ/Re2ikCju+Kf7vxhMbFxJlkfmbogSxIk
|
||||
LVXzRnx+kLn7ML6OQx0CgcEAxcsIByq8JDtAUbvWtObfET86QPcw5otZ9eadetVU
|
||||
UGtbVc2zVIsstMkHGzvLuG8k61vkTimJnwJ+SVy8CEmV+7ZLY3T/wFBI3XdCYpAp
|
||||
bJi6Fn0LsUdu/dRD8KNyaQZVcMGoqPQNVCaHC6YB4tWuWR/unaxPDYiP8u/PwWCz
|
||||
+Cwpeby5XxlYR79YlIZFTeFbRogZZ+sfbWX9q314MxoVf/ZPETOA9063z4kAXcL5
|
||||
RqsZZ1cLu0TCOoNBkcSr79a6
|
||||
-----END PRIVATE KEY-----
|
||||
11
config/keys/assertion-decryption-public.pem
Normal file
11
config/keys/assertion-decryption-public.pem
Normal file
@@ -0,0 +1,11 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAtZc750+cxwDcG/lvpEHm
|
||||
3fxFgp5X5df90s51R4ShKpV6dmDRYXnVil9GmXrJf/aGAqrsf6ZUvZWJrAJ2OO2X
|
||||
Wt8tcqajnaWdM33BrH/QztTJkoGHZM1xLY5EpRaWo1LaG2gNGsaxG0ON9T1emKi7
|
||||
XDEcI9Lmc/mhP6SuuUnvGwq1Z433vqGodorkU+T2jCfflhwfenvBcOk4GJZoJFlY
|
||||
sjy9Dtlha70MJpdVFWffxs4UBhhkjckb7GbDTVxa3xvz1NEbkY2+oh/tJmuIuupA
|
||||
7A6TnfYP1YPXPMRQFtSPaKMOeKW5J5IorvgQKr4C74HR9iBojJN2oJ6/BjfAaz7P
|
||||
8kywLj2uo9gJemOm1wz8HZyZsz482GHa0wqpUcFfOIr0oTMiJtvLn/FSYVb5xvNg
|
||||
3xWiGPMju32Z49XTX7VxTDsIjGx5wtDd4G8ILS3yUlKw0yufHacmy8Fn+Plk+Xtz
|
||||
Bbz6rq4frV93/3mfVMPGgBDx8mLjVJovPBnXKBSX+SdbAgMBAAE=
|
||||
-----END PUBLIC KEY-----
|
||||
40
config/keys/case-save-private.pem
Normal file
40
config/keys/case-save-private.pem
Normal file
@@ -0,0 +1,40 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
5PO2cnRk24OsUqAswTBT2qjd
|
||||
-----END PRIVATE KEY-----
|
||||
11
config/keys/case-save-public.pem
Normal file
11
config/keys/case-save-public.pem
Normal file
@@ -0,0 +1,11 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAzpOwECKVW0KdZwlVJtW7
|
||||
tkqqa1wY1J+HhuFf/kbjmJv8fwFcGj+uyy2s5cXzgckNHz3Cv4Ki8VnQakbn83KR
|
||||
TNIuMvYgwnaNY35KvVKU5R8KPJ7wV8yEUyhRyjtauaY9TaVUH0MStD3izcZ7Pfej
|
||||
XJvxRtLjQ9SX/K+joHs3mkWyWDNYm9u6ecLBoPxW6BpAXiUOWnSpc0IO2njGbvnY
|
||||
I7zs5tYdFjVtDTf4TOSIDXeCXc7nNUhf/yQVAEKvGmr64SihZc+11T5AXJy1eVEj
|
||||
Fwj7hWqcZxhgukacOoU8oUORO0O0H1HIS8ICXHBgKL17Jq+furEInlU4Pfp1tkA7
|
||||
dYh9nXQ91+hmRtTSXA1BpzWdIzC3fQqnwTsD6cyIDsPdRB9iSJTywFPbGywMIbh4
|
||||
wIpUOS3s83DBtpxj2qHw7zc5Q99BP4Dd38kl9ejfdYuFYRmbzrq+BZR7ic5/LM7+
|
||||
8iExYGpz3sFCr6qJAlCDK4th6TCl2ZjzgpTOF3pnC1I7AgMBAAE=
|
||||
-----END PUBLIC KEY-----
|
||||
40
config/keys/login-private.pem
Normal file
40
config/keys/login-private.pem
Normal file
@@ -0,0 +1,40 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
VkpSw8QqBfhHSViEh12BQZa2
|
||||
-----END PRIVATE KEY-----
|
||||
11
config/keys/login-public.pem
Normal file
11
config/keys/login-public.pem
Normal file
@@ -0,0 +1,11 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA2g0IbNxsNIZ6fKaGTHTQ
|
||||
pUFfgJVq3x0SZ458xAQDL0l1PZ+lnMtvS3/ZZpbF99bLuqyzUuHwi+1BJ/Nled61
|
||||
oK8RdJKfUPiQUshXfvWT4/sLsYO6H+v2qw2jBv6kx3h+teDiuHMbw6ikUECr5u1k
|
||||
qkjb+ls3aijtWplmN25HRhwFB/l6/0xAhEQNA36EoNb+ufsDR/2aRQYGQ6qegynp
|
||||
8bUt7JDf3hW1y76UCKlKteFfIOkp4zwY0YYq/NewgKlze08LBrX+zy5xr5Vn8nE0
|
||||
ZtWY8vbNC33Sf6g5D1ZlA+HvquplAWS/rPymj+IN79FeXNegmyCxF/ZafsneaUBn
|
||||
GpSgXYbyASpA+OkqUqJcBEeTI4rfRZPiyx3ztaibg+rgOEM/DUV5le2WyujnsQ75
|
||||
IG4SrVu/XTmF08MN8/hD1+ydBVnhVa7bE4WctqgA1T/5BP7ivAB03a1BJHpKFRh/
|
||||
Q/pO5ONIK8lNGG6aImLPmtJijEvOL0VsUdp+oO87VnTFAgMBAAE=
|
||||
-----END PUBLIC KEY-----
|
||||
@@ -1,10 +1,15 @@
|
||||
package com.cygnus.client;
|
||||
|
||||
import com.cygnus.client.model.CloudIdentitySession;
|
||||
import com.cygnus.client.model.CloudDataItem;
|
||||
import com.cygnus.client.model.CloudDataRequest;
|
||||
import com.cygnus.client.model.CloudQueryResponse;
|
||||
import com.cygnus.client.model.LoginPayload;
|
||||
import com.cygnus.client.security.LoginEnvelopeEncryptor;
|
||||
import com.cygnus.client.security.MachineTokenProvider;
|
||||
import java.time.Clock;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
@@ -50,4 +55,40 @@ public class CloudIdentityClient {
|
||||
.bodyToMono(CloudIdentitySession.class))
|
||||
.timeout(properties.requestTimeout());
|
||||
}
|
||||
|
||||
public Mono<CloudQueryResponse> fetchQuery(int queryId) {
|
||||
return tokenProvider.accessToken()
|
||||
.flatMap(token -> webClient.get()
|
||||
.uri(properties.baseUri().resolve("/api/v1/queries/" + queryId))
|
||||
.header(HttpHeaders.AUTHORIZATION, "Bearer " + token)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.retrieve()
|
||||
.bodyToMono(CloudQueryResponse.class))
|
||||
.timeout(properties.requestTimeout());
|
||||
}
|
||||
|
||||
public Mono<CloudQueryResponse> fetchQuery(String queryKey) {
|
||||
return tokenProvider.accessToken()
|
||||
.flatMap(token -> webClient.get()
|
||||
.uri(properties.baseUri().resolve("/api/v1/queries/key/" + queryKey))
|
||||
.header(HttpHeaders.AUTHORIZATION, "Bearer " + token)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.retrieve()
|
||||
.bodyToMono(CloudQueryResponse.class))
|
||||
.timeout(properties.requestTimeout());
|
||||
}
|
||||
|
||||
public Mono<List<CloudDataItem>> fetchData(String scope, Map<String, Object> data) {
|
||||
return tokenProvider.accessToken()
|
||||
.flatMap(token -> webClient.post()
|
||||
.uri(properties.baseUri().resolve("/api/v1/platform/data"))
|
||||
.header(HttpHeaders.AUTHORIZATION, "Bearer " + token)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.bodyValue(new CloudDataRequest(scope, Map.copyOf(data)))
|
||||
.retrieve()
|
||||
.bodyToFlux(CloudDataItem.class)
|
||||
.collectList())
|
||||
.timeout(properties.requestTimeout());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.cygnus.client.model;
|
||||
|
||||
public record CloudDataItem(Object value, String label, String group) {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.cygnus.client.model;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public record CloudDataRequest(String scope, Map<String, Object> data) {
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.cygnus.client.model;
|
||||
|
||||
public record CloudQueryResponse(int queryId, String query) {
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.cygnus.cloud.platform.api;
|
||||
|
||||
import com.cygnus.cloud.platform.service.ScopedDataException;
|
||||
import com.cygnus.cloud.platform.service.ScopedDataService;
|
||||
import jakarta.validation.Valid;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/platform/data")
|
||||
public class ScopedDataController {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ScopedDataController.class);
|
||||
private final ScopedDataService service;
|
||||
|
||||
public ScopedDataController(ScopedDataService service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public Flux<ScopedDataItem> data(
|
||||
@AuthenticationPrincipal Jwt machineJwt,
|
||||
@Valid @RequestBody ScopedDataRequest request) {
|
||||
if (machineJwt == null) throw new ScopedDataException("Machine authentication required");
|
||||
try {
|
||||
return service.fetch(UUID.fromString(machineJwt.getClaimAsString("tenant_id")), request);
|
||||
} catch (IllegalArgumentException exception) {
|
||||
throw new ScopedDataException("Machine tenant is invalid");
|
||||
}
|
||||
}
|
||||
|
||||
@ExceptionHandler(ScopedDataException.class)
|
||||
@ResponseStatus(HttpStatus.BAD_REQUEST)
|
||||
Map<String, String> invalidRequest(ScopedDataException exception) {
|
||||
LOGGER.warn("Scoped platform-data request rejected: {}", exception.getMessage());
|
||||
return Map.of("code", "PLATFORM_DATA_INVALID", "message", exception.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.cygnus.cloud.platform.api;
|
||||
|
||||
public record ScopedDataItem(
|
||||
Object value,
|
||||
String label,
|
||||
String group) {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.cygnus.cloud.platform.api;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.util.Map;
|
||||
|
||||
public record ScopedDataRequest(
|
||||
@NotBlank String scope,
|
||||
@NotNull Map<String, Object> data) {
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.cygnus.cloud.platform.repository;
|
||||
|
||||
import com.cygnus.cloud.database.ReactiveDatabaseClient;
|
||||
import com.cygnus.cloud.platform.api.ScopedDataItem;
|
||||
import io.vertx.sqlclient.Row;
|
||||
import io.vertx.sqlclient.Tuple;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
@Repository
|
||||
public class ScopedDataRepository {
|
||||
private static final String COMPANY_OPTIONS = """
|
||||
SELECT ov.opt_value AS value,
|
||||
ov.val_description AS label,
|
||||
lower(o.description) || '.' AS group_name
|
||||
FROM platform.company_options_mapping m
|
||||
JOIN platform.options o ON o.option_id = m.option_id
|
||||
JOIN platform.options_values ov ON ov.opt_value_id = m.opt_value_id
|
||||
JOIN identity.company c ON c.company_id = m.company_id
|
||||
WHERE c.tenant_id = $1
|
||||
AND m.company_id = $2
|
||||
AND o.isactive = 1
|
||||
AND ov.isactive = 1
|
||||
AND o.description = ANY($3::text[])
|
||||
ORDER BY o.description, ov.val_description
|
||||
""";
|
||||
private static final String PORTFOLIO_OPTIONS = """
|
||||
SELECT ov.opt_value AS value,
|
||||
ov.val_description AS label,
|
||||
lower(o.description) || '.' AS group_name
|
||||
FROM platform.options_mapping m
|
||||
JOIN platform.options o ON o.option_id = m.option_id
|
||||
JOIN platform.options_values ov ON ov.opt_value_id = m.opt_value_id
|
||||
JOIN identity.company c ON c.company_id = m.company_id
|
||||
JOIN platform.company_branch_portfolios cbp
|
||||
ON cbp.company_id = m.company_id
|
||||
AND cbp.portfolio_reference = m.portfolio_reference
|
||||
WHERE c.tenant_id = $1
|
||||
AND m.company_id = $2
|
||||
AND cbp.company_branch_id = $3
|
||||
AND m.portfolio_reference = $4
|
||||
AND o.isactive = 1
|
||||
AND ov.isactive = 1
|
||||
AND o.description = ANY($5::text[])
|
||||
ORDER BY o.description, ov.val_description
|
||||
""";
|
||||
|
||||
private final ReactiveDatabaseClient database;
|
||||
|
||||
public ScopedDataRepository(ReactiveDatabaseClient database) {
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
public Flux<ScopedDataItem> companyOptions(
|
||||
UUID tenantId, short companyId, List<String> descriptions) {
|
||||
return rows(COMPANY_OPTIONS, Tuple.of(tenantId, companyId, descriptions.toArray(String[]::new)));
|
||||
}
|
||||
|
||||
public Flux<ScopedDataItem> portfolioOptions(
|
||||
UUID tenantId, short companyId, short branchId, UUID portfolioReference,
|
||||
List<String> descriptions) {
|
||||
return rows(PORTFOLIO_OPTIONS,
|
||||
Tuple.of(tenantId, companyId, branchId, portfolioReference,
|
||||
descriptions.toArray(String[]::new)));
|
||||
}
|
||||
|
||||
private Flux<ScopedDataItem> rows(String sql, Tuple parameters) {
|
||||
return database.preparedQuery(sql, parameters)
|
||||
.flatMapMany(result -> Flux.fromIterable(result))
|
||||
.map(this::item);
|
||||
}
|
||||
|
||||
private ScopedDataItem item(Row row) {
|
||||
return new ScopedDataItem(
|
||||
row.getValue("value"), row.getString("label"), row.getString("group_name"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.cygnus.cloud.platform.service;
|
||||
|
||||
public class ScopedDataException extends RuntimeException {
|
||||
public ScopedDataException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.cygnus.cloud.platform.service;
|
||||
|
||||
import com.cygnus.cloud.platform.api.ScopedDataItem;
|
||||
import com.cygnus.cloud.platform.api.ScopedDataRequest;
|
||||
import com.cygnus.cloud.platform.repository.ScopedDataRepository;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import org.springframework.stereotype.Service;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
@Service
|
||||
public class ScopedDataService {
|
||||
public static final String COMPANY_OPTIONS = "company-options";
|
||||
public static final String PORTFOLIO_OPTIONS = "portfolio-options";
|
||||
|
||||
private final ScopedDataRepository repository;
|
||||
|
||||
public ScopedDataService(ScopedDataRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public Flux<ScopedDataItem> fetch(UUID tenantId, ScopedDataRequest request) {
|
||||
Map<String, Object> data = request.data();
|
||||
short companyId = shortValue(data, "companyId");
|
||||
List<String> descriptions = descriptions(data);
|
||||
return switch (request.scope().trim().toLowerCase(Locale.ROOT)) {
|
||||
case COMPANY_OPTIONS -> repository.companyOptions(tenantId, companyId, descriptions);
|
||||
case PORTFOLIO_OPTIONS -> repository.portfolioOptions(
|
||||
tenantId, companyId, shortValue(data, "branchId"),
|
||||
uuidValue(data, "portfolioReference"), descriptions);
|
||||
default -> Flux.error(new ScopedDataException("Unsupported data scope"));
|
||||
};
|
||||
}
|
||||
|
||||
private UUID uuidValue(Map<String, Object> data, String name) {
|
||||
try {
|
||||
return UUID.fromString(String.valueOf(data.get(name)));
|
||||
} catch (RuntimeException exception) {
|
||||
throw new ScopedDataException(name + " must be a valid UUID");
|
||||
}
|
||||
}
|
||||
|
||||
private short shortValue(Map<String, Object> data, String name) {
|
||||
Object value = data.get(name);
|
||||
try {
|
||||
short result = value instanceof Number number
|
||||
? number.shortValue() : Short.parseShort(String.valueOf(value));
|
||||
if (result <= 0) throw new NumberFormatException();
|
||||
return result;
|
||||
} catch (RuntimeException exception) {
|
||||
throw new ScopedDataException(name + " must be a positive number");
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> descriptions(Map<String, Object> data) {
|
||||
Object value = data.get("descriptions");
|
||||
if (!(value instanceof List<?> values)) {
|
||||
throw new ScopedDataException("descriptions must be a non-empty list");
|
||||
}
|
||||
List<String> result = values.stream()
|
||||
.map(String::valueOf)
|
||||
.map(String::trim)
|
||||
.filter(text -> !text.isEmpty())
|
||||
.map(text -> text.toUpperCase(Locale.ROOT))
|
||||
.distinct()
|
||||
.toList();
|
||||
if (result.isEmpty() || result.size() > 20) {
|
||||
throw new ScopedDataException("descriptions must contain between 1 and 20 values");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.cygnus.cloud.query;
|
||||
|
||||
public record CloudQuery(int queryId, String query) {
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.cygnus.cloud.query;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@Validated
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/queries")
|
||||
public class CloudQueryController {
|
||||
|
||||
private final QueryCatalogRepository repository;
|
||||
|
||||
public CloudQueryController(QueryCatalogRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
@GetMapping("/{queryId}")
|
||||
public Mono<CloudQuery> query(
|
||||
@PathVariable @Min(1) int queryId) {
|
||||
return repository.findEnabled(queryId)
|
||||
.switchIfEmpty(Mono.error(new QueryNotFoundException(queryId)));
|
||||
}
|
||||
|
||||
@GetMapping("/key/{queryKey}")
|
||||
public Mono<CloudQuery> queryByKey(@PathVariable String queryKey) {
|
||||
return repository.findEnabled(queryKey)
|
||||
.switchIfEmpty(Mono.error(new QueryNotFoundException(queryKey)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.cygnus.cloud.query;
|
||||
|
||||
import com.cygnus.cloud.database.ReactiveDatabaseClient;
|
||||
import io.vertx.sqlclient.Tuple;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@Repository
|
||||
public class QueryCatalogRepository {
|
||||
|
||||
private static final String INITIALIZE = """
|
||||
CREATE SCHEMA IF NOT EXISTS platform;
|
||||
CREATE SEQUENCE IF NOT EXISTS platform.application_query_id_seq;
|
||||
CREATE TABLE IF NOT EXISTS platform.application_query (
|
||||
query_id integer PRIMARY KEY DEFAULT nextval('platform.application_query_id_seq'),
|
||||
query_key varchar(100),
|
||||
query_text text NOT NULL,
|
||||
enabled boolean NOT NULL DEFAULT true,
|
||||
created_at timestamptz NOT NULL DEFAULT current_timestamp,
|
||||
updated_at timestamptz NOT NULL DEFAULT current_timestamp,
|
||||
CONSTRAINT ck_platform_application_query_id
|
||||
CHECK (query_id > 0),
|
||||
CONSTRAINT ck_platform_application_query_text
|
||||
CHECK (length(btrim(query_text)) > 0)
|
||||
);
|
||||
ALTER TABLE platform.application_query
|
||||
ADD COLUMN IF NOT EXISTS query_key varchar(100);
|
||||
ALTER TABLE platform.application_query ALTER COLUMN query_id
|
||||
SET DEFAULT nextval('platform.application_query_id_seq');
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS ux_platform_application_query_key
|
||||
ON platform.application_query (query_key) WHERE query_key IS NOT NULL;
|
||||
SELECT setval('platform.application_query_id_seq',
|
||||
greatest(coalesce((SELECT max(query_id) FROM platform.application_query), 0) + 1, 1), false)
|
||||
""";
|
||||
private static final String FIND = """
|
||||
SELECT query_id, query_text
|
||||
FROM platform.application_query
|
||||
WHERE query_id = $1
|
||||
AND enabled = true
|
||||
""";
|
||||
private static final String FIND_BY_KEY = """
|
||||
SELECT query_id, query_text
|
||||
FROM platform.application_query
|
||||
WHERE query_key = $1
|
||||
AND enabled = true
|
||||
""";
|
||||
private final ReactiveDatabaseClient database;
|
||||
|
||||
public QueryCatalogRepository(ReactiveDatabaseClient database) {
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
public Mono<Void> initialize() {
|
||||
return database.query(INITIALIZE).then();
|
||||
}
|
||||
|
||||
public Mono<CloudQuery> findEnabled(int queryId) {
|
||||
return database.preparedQuery(FIND, Tuple.of(queryId))
|
||||
.flatMapMany(rows -> reactor.core.publisher.Flux.fromIterable(rows))
|
||||
.next()
|
||||
.map(row -> new CloudQuery(
|
||||
row.getInteger("query_id"), row.getString("query_text")));
|
||||
}
|
||||
|
||||
public Mono<CloudQuery> findEnabled(String queryKey) {
|
||||
return database.preparedQuery(FIND_BY_KEY, Tuple.of(queryKey))
|
||||
.flatMapMany(rows -> reactor.core.publisher.Flux.fromIterable(rows))
|
||||
.next()
|
||||
.map(row -> new CloudQuery(row.getInteger("query_id"), row.getString("query_text")));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.cygnus.cloud.query;
|
||||
|
||||
import java.time.Duration;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class QueryCatalogSchemaInitializer implements ApplicationRunner {
|
||||
|
||||
private final QueryCatalogRepository repository;
|
||||
|
||||
public QueryCatalogSchemaInitializer(QueryCatalogRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments arguments) {
|
||||
repository.initialize()
|
||||
.block(Duration.ofMinutes(2));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.cygnus.cloud.query;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
@ResponseStatus(HttpStatus.NOT_FOUND)
|
||||
public class QueryNotFoundException extends RuntimeException {
|
||||
|
||||
public QueryNotFoundException(int queryId) {
|
||||
super("Query was not found: " + queryId);
|
||||
}
|
||||
|
||||
public QueryNotFoundException(String queryKey) {
|
||||
super("Query was not found: " + queryKey);
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,10 @@ public class CloudSecurityConfiguration {
|
||||
.permitAll()
|
||||
.pathMatchers("/api/v1/identity/login")
|
||||
.hasAuthority("SCOPE_identity.login")
|
||||
.pathMatchers("/api/v1/queries/**")
|
||||
.hasAuthority("SCOPE_identity.login")
|
||||
.pathMatchers("/api/v1/platform/data")
|
||||
.hasAuthority("SCOPE_identity.login")
|
||||
.pathMatchers("/api/v1/admin/**")
|
||||
.hasAuthority("SCOPE_cygnus.admin")
|
||||
.anyExchange().authenticated())
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
CREATE SCHEMA IF NOT EXISTS platform;
|
||||
CREATE SEQUENCE IF NOT EXISTS platform.application_query_id_seq;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS platform.application_query (
|
||||
query_id integer PRIMARY KEY DEFAULT nextval('platform.application_query_id_seq'),
|
||||
query_key varchar(100),
|
||||
query_text text NOT NULL,
|
||||
enabled boolean NOT NULL DEFAULT true,
|
||||
created_at timestamptz NOT NULL DEFAULT current_timestamp,
|
||||
updated_at timestamptz NOT NULL DEFAULT current_timestamp,
|
||||
CONSTRAINT ck_platform_application_query_id
|
||||
CHECK (query_id > 0),
|
||||
CONSTRAINT ck_platform_application_query_text
|
||||
CHECK (length(btrim(query_text)) > 0)
|
||||
);
|
||||
ALTER TABLE platform.application_query
|
||||
ADD COLUMN IF NOT EXISTS query_key varchar(100);
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS ux_platform_application_query_key
|
||||
ON platform.application_query (query_key) WHERE query_key IS NOT NULL;
|
||||
ALTER TABLE platform.application_query ALTER COLUMN query_id
|
||||
SET DEFAULT nextval('platform.application_query_id_seq');
|
||||
SELECT setval('platform.application_query_id_seq',
|
||||
greatest(coalesce((SELECT max(query_id) FROM platform.application_query), 0) + 1, 1), false);
|
||||
@@ -0,0 +1,25 @@
|
||||
DO $$
|
||||
DECLARE
|
||||
current_type text;
|
||||
BEGIN
|
||||
SELECT data_type
|
||||
INTO current_type
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'platform'
|
||||
AND table_name = 'application_query'
|
||||
AND column_name = 'query_id';
|
||||
|
||||
IF current_type IN ('character varying', 'text') THEN
|
||||
ALTER TABLE platform.application_query
|
||||
DROP CONSTRAINT IF EXISTS ck_platform_application_query_id;
|
||||
|
||||
ALTER TABLE platform.application_query
|
||||
ALTER COLUMN query_id TYPE integer
|
||||
USING regexp_replace(query_id, '^Query', '')::integer;
|
||||
|
||||
ALTER TABLE platform.application_query
|
||||
ADD CONSTRAINT ck_platform_application_query_id
|
||||
CHECK (query_id > 0);
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
@@ -0,0 +1,11 @@
|
||||
-- Stable query key; query_id is generated by PostgreSQL.
|
||||
BEGIN;
|
||||
|
||||
INSERT INTO platform.application_query(query_key, query_text, enabled, created_at, updated_at, ismigrated)
|
||||
VALUES ('APPLICATION_SAVE',
|
||||
'procedure!C0L!select * from public.save_application_details(?::jsonb,?::smallint,?::smallint,?::smallint)',
|
||||
true, clock_timestamp(), clock_timestamp(), true)
|
||||
ON CONFLICT (query_key) WHERE query_key IS NOT NULL DO UPDATE SET
|
||||
query_text=excluded.query_text, enabled=true, updated_at=clock_timestamp(), ismigrated=true;
|
||||
|
||||
COMMIT;
|
||||
BIN
cygnus-installer/.DS_Store
vendored
BIN
cygnus-installer/.DS_Store
vendored
Binary file not shown.
@@ -30,6 +30,7 @@ public class DeploymentWriter {
|
||||
try {
|
||||
Path normalizedOutput = output.toAbsolutePath().normalize();
|
||||
Path config = normalizedOutput.resolve("config");
|
||||
protectCloudConfiguration(config, profile);
|
||||
Path keyDirectory = config.resolve("keys");
|
||||
Files.createDirectories(keyDirectory);
|
||||
|
||||
@@ -82,6 +83,23 @@ public class DeploymentWriter {
|
||||
}
|
||||
}
|
||||
|
||||
private void protectCloudConfiguration(Path deploymentConfig, ProductProfile profile) {
|
||||
if (isInside(deploymentConfig, profile.assertionEncryptionPublicKey())
|
||||
|| isInside(deploymentConfig, profile.loginEncryptionPublicKey())) {
|
||||
throw new IllegalArgumentException(
|
||||
"Refusing to write deployment files over the cloud-service "
|
||||
+ "configuration directory");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isInside(Path directory, Path file) {
|
||||
if (file == null) {
|
||||
return false;
|
||||
}
|
||||
return file.toAbsolutePath().normalize().startsWith(
|
||||
directory.toAbsolutePath().normalize());
|
||||
}
|
||||
|
||||
private String installationConfiguration(
|
||||
UUID installationUuid,
|
||||
String installationCode,
|
||||
@@ -174,6 +192,7 @@ public class DeploymentWriter {
|
||||
appendEnvironment(env, "REDIS_HOST", runtime.redisHost());
|
||||
appendEnvironment(env, "REDIS_PORT", runtime.redisPort());
|
||||
appendEnvironment(env, "REDIS_PASSWORD", runtime.redisPassword());
|
||||
appendEnvironment(env, "REDIS_DATABASE", "1");
|
||||
appendEnvironment(env, "REDIS_SSL", Boolean.toString(runtime.redisSsl()));
|
||||
appendEnvironment(
|
||||
env, "CYGNUS_CLOUD_BASE_URL", normalizedCloudServiceUrl(runtime));
|
||||
|
||||
@@ -156,6 +156,7 @@ public class InstallationService {
|
||||
if (request.outputDirectory() == null) {
|
||||
throw new IllegalArgumentException("Output directory is required");
|
||||
}
|
||||
validateOutputIsolation(request.outputDirectory());
|
||||
RuntimeConfiguration runtime = request.runtimeConfiguration();
|
||||
if (runtime == null) {
|
||||
throw new IllegalArgumentException("Runtime configuration is required");
|
||||
@@ -204,6 +205,27 @@ public class InstallationService {
|
||||
}
|
||||
}
|
||||
|
||||
private void validateOutputIsolation(Path outputDirectory) {
|
||||
Path deploymentConfig = outputDirectory
|
||||
.toAbsolutePath()
|
||||
.normalize()
|
||||
.resolve("config");
|
||||
if (isInside(deploymentConfig, profile.assertionEncryptionPublicKey())
|
||||
|| isInside(deploymentConfig, profile.loginEncryptionPublicKey())) {
|
||||
throw new IllegalArgumentException(
|
||||
"Output directory would overwrite the cloud-service config folder. "
|
||||
+ "Select a dedicated deployment directory, such as "
|
||||
+ "'matrix-installation'.");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isInside(Path directory, Path file) {
|
||||
if (file == null) {
|
||||
return false;
|
||||
}
|
||||
return file.toAbsolutePath().normalize().startsWith(directory);
|
||||
}
|
||||
|
||||
private String normalizedCloudServiceUrl(String value) {
|
||||
String normalized = value.trim();
|
||||
return normalized.endsWith("/")
|
||||
|
||||
@@ -42,8 +42,9 @@ import org.springframework.stereotype.Service;
|
||||
public class SwingInstallationWizard {
|
||||
|
||||
private static final String WELCOME = "welcome";
|
||||
private static final String DATABASE = "database";
|
||||
private static final String DEPLOYMENT = "deployment";
|
||||
private static final String DETAILS = "details";
|
||||
private static final String RUNTIME = "runtime";
|
||||
private static final String INSTALLING = "installing";
|
||||
private static final Color ACCENT = new Color(35, 97, 146);
|
||||
private static final Color BACKGROUND = new Color(236, 243, 247);
|
||||
@@ -68,7 +69,9 @@ public class SwingInstallationWizard {
|
||||
private JPasswordField dockerPassword;
|
||||
private JTextField outputDirectory;
|
||||
private JTextField containerCloudServiceUrl;
|
||||
private JTextField databaseUrl;
|
||||
private JTextField databaseHost;
|
||||
private JTextField databasePort;
|
||||
private JTextField databaseName;
|
||||
private JTextField databaseUsername;
|
||||
private JPasswordField databasePassword;
|
||||
private JTextField redisHost;
|
||||
@@ -139,8 +142,9 @@ public class SwingInstallationWizard {
|
||||
cardPanel = new JPanel(cards);
|
||||
cardPanel.setBackground(BACKGROUND);
|
||||
cardPanel.add(welcomePanel(), WELCOME);
|
||||
cardPanel.add(databasePanel(), DATABASE);
|
||||
cardPanel.add(deploymentPanel(), DEPLOYMENT);
|
||||
cardPanel.add(detailsPanel(), DETAILS);
|
||||
cardPanel.add(runtimePanel(), RUNTIME);
|
||||
cardPanel.add(installingPanel(), INSTALLING);
|
||||
root.add(cardPanel, BorderLayout.CENTER);
|
||||
return root;
|
||||
@@ -197,7 +201,8 @@ public class SwingInstallationWizard {
|
||||
JPanel top = new JPanel(new BorderLayout());
|
||||
top.setOpaque(false);
|
||||
top.add(heading("Installation details"), BorderLayout.NORTH);
|
||||
top.add(text("Enter the activation details supplied by Technobee."), BorderLayout.SOUTH);
|
||||
top.add(text("Review and enter the activation details supplied by Technobee."),
|
||||
BorderLayout.SOUTH);
|
||||
panel.add(top, BorderLayout.NORTH);
|
||||
|
||||
JPanel form = new JPanel(new GridBagLayout());
|
||||
@@ -209,6 +214,32 @@ public class SwingInstallationWizard {
|
||||
licenseKey = new JPasswordField();
|
||||
installationCode = new JTextField();
|
||||
installationName = new JTextField();
|
||||
int row = 0;
|
||||
row = addField(form, row, "Client code", clientCode, null);
|
||||
row = addField(form, row, "License key", licenseKey, null);
|
||||
row = addField(form, row, "Installation code", installationCode, null);
|
||||
addField(form, row, "Installation name", installationName, null);
|
||||
panel.add(form, BorderLayout.CENTER);
|
||||
|
||||
JButton back = secondaryButton("Back");
|
||||
back.addActionListener(event -> cards.show(cardPanel, DEPLOYMENT));
|
||||
JButton install = primaryButton("Install");
|
||||
install.addActionListener(event -> startInstallation());
|
||||
panel.add(actions(back, install), BorderLayout.SOUTH);
|
||||
return panel;
|
||||
}
|
||||
|
||||
private JPanel deploymentPanel() {
|
||||
JPanel panel = contentPanel();
|
||||
panel.setLayout(new BorderLayout(0, 12));
|
||||
JPanel top = new JPanel(new BorderLayout());
|
||||
top.setOpaque(false);
|
||||
top.add(heading("Docker and deployment"), BorderLayout.NORTH);
|
||||
top.add(text("Configure the container image, registry and deployment location."),
|
||||
BorderLayout.SOUTH);
|
||||
panel.add(top, BorderLayout.NORTH);
|
||||
|
||||
JPanel form = formPanel();
|
||||
containerCloudServiceUrl =
|
||||
new JTextField(settings.containerCloudServiceUrl().toString());
|
||||
containerCloudServiceUrl.setEditable(true);
|
||||
@@ -220,10 +251,6 @@ public class SwingInstallationWizard {
|
||||
outputDirectory = new JTextField(
|
||||
settings.defaultOutputDirectory().toAbsolutePath().normalize().toString());
|
||||
int row = 0;
|
||||
row = addField(form, row, "Client code", clientCode, null);
|
||||
row = addField(form, row, "License key", licenseKey, null);
|
||||
row = addField(form, row, "Installation code", installationCode, null);
|
||||
row = addField(form, row, "Installation name", installationName, null);
|
||||
row = addField(
|
||||
form,
|
||||
row,
|
||||
@@ -237,8 +264,11 @@ public class SwingInstallationWizard {
|
||||
dockerImage,
|
||||
null);
|
||||
row = addField(form, row, "Docker registry", dockerRegistry, null);
|
||||
row = addField(form, row, "Docker username", dockerUsername, null);
|
||||
row = addField(form, row, "Docker password", dockerPassword, null);
|
||||
row = addComponentField(
|
||||
form,
|
||||
row,
|
||||
"Docker credentials",
|
||||
credentialFields(dockerUsername, dockerPassword));
|
||||
for (String field : profile.optionalInstallationFields()) {
|
||||
JTextField input = new JTextField();
|
||||
optionalFields.put(field, input);
|
||||
@@ -254,31 +284,28 @@ public class SwingInstallationWizard {
|
||||
panel.add(scroll, BorderLayout.CENTER);
|
||||
|
||||
JButton back = secondaryButton("Back");
|
||||
back.addActionListener(event -> cards.show(cardPanel, WELCOME));
|
||||
back.addActionListener(event -> cards.show(cardPanel, DATABASE));
|
||||
JButton next = primaryButton("Next");
|
||||
next.addActionListener(event -> cards.show(cardPanel, RUNTIME));
|
||||
next.addActionListener(event -> cards.show(cardPanel, DETAILS));
|
||||
panel.add(actions(back, next), BorderLayout.SOUTH);
|
||||
return panel;
|
||||
}
|
||||
|
||||
private JPanel runtimePanel() {
|
||||
private JPanel databasePanel() {
|
||||
JPanel panel = contentPanel();
|
||||
panel.setLayout(new BorderLayout(0, 12));
|
||||
|
||||
JPanel top = new JPanel(new BorderLayout());
|
||||
top.setOpaque(false);
|
||||
top.add(heading("Runtime configuration"), BorderLayout.NORTH);
|
||||
top.add(heading("Database and Redis"), BorderLayout.NORTH);
|
||||
top.add(text("Configure the database and Redis services used by the "
|
||||
+ profile.displayName() + " on-premises container."), BorderLayout.SOUTH);
|
||||
panel.add(top, BorderLayout.NORTH);
|
||||
|
||||
JPanel form = new JPanel(new GridBagLayout());
|
||||
form.setBackground(PANEL);
|
||||
form.setBorder(BorderFactory.createCompoundBorder(
|
||||
BorderFactory.createLineBorder(new Color(205, 217, 225)),
|
||||
BorderFactory.createEmptyBorder(14, 16, 14, 16)));
|
||||
|
||||
databaseUrl = new JTextField("jdbc:postgresql://localhost:5432/matrix");
|
||||
JPanel form = formPanel();
|
||||
databaseHost = new JTextField("localhost");
|
||||
databasePort = new JTextField("5432");
|
||||
databaseName = new JTextField("matrix");
|
||||
databaseUsername = new JTextField("postgres");
|
||||
databasePassword = new JPasswordField();
|
||||
redisHost = new JTextField("localhost");
|
||||
@@ -287,9 +314,16 @@ public class SwingInstallationWizard {
|
||||
cloudRequestTimeout = new JTextField("PT10S");
|
||||
tokenRefreshSkew = new JTextField("PT30S");
|
||||
int row = 0;
|
||||
row = addField(form, row, "Database URL", databaseUrl, null);
|
||||
row = addField(form, row, "Database username", databaseUsername, null);
|
||||
row = addField(form, row, "Database password", databasePassword, null);
|
||||
row = addComponentField(
|
||||
form,
|
||||
row,
|
||||
"Database",
|
||||
databaseConnectionFields());
|
||||
row = addComponentField(
|
||||
form,
|
||||
row,
|
||||
"Database credentials",
|
||||
credentialFields(databaseUsername, databasePassword));
|
||||
row = addField(form, row, "Redis host", redisHost, null);
|
||||
row = addField(form, row, "Redis port", redisPort, null);
|
||||
row = addField(form, row, "Redis password", redisPassword, null);
|
||||
@@ -304,10 +338,10 @@ public class SwingInstallationWizard {
|
||||
panel.add(form, BorderLayout.CENTER);
|
||||
|
||||
JButton back = secondaryButton("Back");
|
||||
back.addActionListener(event -> cards.show(cardPanel, DETAILS));
|
||||
JButton install = primaryButton("Install");
|
||||
install.addActionListener(event -> startInstallation());
|
||||
panel.add(actions(back, install), BorderLayout.SOUTH);
|
||||
back.addActionListener(event -> cards.show(cardPanel, WELCOME));
|
||||
JButton next = primaryButton("Next");
|
||||
next.addActionListener(event -> cards.show(cardPanel, DEPLOYMENT));
|
||||
panel.add(actions(back, next), BorderLayout.SOUTH);
|
||||
return panel;
|
||||
}
|
||||
|
||||
@@ -373,7 +407,7 @@ public class SwingInstallationWizard {
|
||||
progressBar.setValue(0);
|
||||
progressPercentage.setText("0%");
|
||||
progressMessage.setText("Preparing installation");
|
||||
cards.show(cardPanel, RUNTIME);
|
||||
cards.show(cardPanel, DEPLOYMENT);
|
||||
containerCloudServiceUrl.requestFocusInWindow();
|
||||
});
|
||||
|
||||
@@ -415,8 +449,8 @@ public class SwingInstallationWizard {
|
||||
button.setText("Check Docker and continue");
|
||||
try {
|
||||
get();
|
||||
cards.show(cardPanel, DETAILS);
|
||||
clientCode.requestFocusInWindow();
|
||||
cards.show(cardPanel, DATABASE);
|
||||
databaseHost.requestFocusInWindow();
|
||||
} catch (Exception exception) {
|
||||
showError(message(exception));
|
||||
}
|
||||
@@ -445,7 +479,12 @@ public class SwingInstallationWizard {
|
||||
optionalValues(),
|
||||
new RuntimeConfiguration(
|
||||
containerCloudServiceUrl.getText(),
|
||||
databaseUrl.getText(),
|
||||
"jdbc:postgresql://"
|
||||
+ databaseHost.getText().trim()
|
||||
+ ":"
|
||||
+ databasePort.getText().trim()
|
||||
+ "/"
|
||||
+ databaseName.getText().trim(),
|
||||
databaseUsername.getText(),
|
||||
new String(databaseSecret),
|
||||
redisHost.getText(),
|
||||
@@ -559,7 +598,9 @@ public class SwingInstallationWizard {
|
||||
validateAbsoluteHttpUrl(
|
||||
runtime.containerCloudServiceUrl(),
|
||||
"Container cloud service URL");
|
||||
if (runtime.databaseUrl().isBlank()
|
||||
if (databaseHost.getText().isBlank()
|
||||
|| databasePort.getText().isBlank()
|
||||
|| databaseName.getText().isBlank()
|
||||
|| runtime.databaseUsername().isBlank()
|
||||
|| runtime.databasePassword().isBlank()) {
|
||||
throw new IllegalArgumentException(
|
||||
@@ -632,6 +673,95 @@ public class SwingInstallationWizard {
|
||||
return row + 1;
|
||||
}
|
||||
|
||||
private int addComponentField(
|
||||
JPanel form,
|
||||
int row,
|
||||
String label,
|
||||
Component input) {
|
||||
GridBagConstraints labelConstraints = constraints(0, row);
|
||||
labelConstraints.weightx = 0;
|
||||
labelConstraints.fill = GridBagConstraints.NONE;
|
||||
labelConstraints.anchor = GridBagConstraints.LINE_START;
|
||||
JLabel fieldLabel = new JLabel(label);
|
||||
fieldLabel.setFont(fieldLabel.getFont().deriveFont(Font.BOLD, 12f));
|
||||
form.add(fieldLabel, labelConstraints);
|
||||
|
||||
GridBagConstraints inputConstraints = constraints(1, row);
|
||||
inputConstraints.weightx = 1;
|
||||
inputConstraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
form.add(input, inputConstraints);
|
||||
return row + 1;
|
||||
}
|
||||
|
||||
private JPanel formPanel() {
|
||||
JPanel form = new JPanel(new GridBagLayout());
|
||||
form.setBackground(PANEL);
|
||||
form.setBorder(BorderFactory.createCompoundBorder(
|
||||
BorderFactory.createLineBorder(new Color(205, 217, 225)),
|
||||
BorderFactory.createEmptyBorder(14, 16, 14, 16)));
|
||||
return form;
|
||||
}
|
||||
|
||||
private JPanel databaseConnectionFields() {
|
||||
JPanel fields = inlineFieldsPanel();
|
||||
addInlineField(fields, databaseHost, 0, 0.50);
|
||||
addInlineSeparator(fields, ":", 1);
|
||||
addInlineField(fields, databasePort, 2, 0.15);
|
||||
addInlineSeparator(fields, "/", 3);
|
||||
addInlineField(fields, databaseName, 4, 0.35);
|
||||
databaseHost.setToolTipText("Database host");
|
||||
databasePort.setToolTipText("Database port");
|
||||
databaseName.setToolTipText("Database name");
|
||||
return fields;
|
||||
}
|
||||
|
||||
private JPanel credentialFields(JTextField username, JTextField password) {
|
||||
JPanel fields = inlineFieldsPanel();
|
||||
addInlineLabel(fields, "Username", 0);
|
||||
addInlineField(fields, username, 1, 0.5);
|
||||
addInlineLabel(fields, "Password", 2);
|
||||
addInlineField(fields, password, 3, 0.5);
|
||||
return fields;
|
||||
}
|
||||
|
||||
private JPanel inlineFieldsPanel() {
|
||||
JPanel fields = new JPanel(new GridBagLayout());
|
||||
fields.setOpaque(false);
|
||||
return fields;
|
||||
}
|
||||
|
||||
private void addInlineField(
|
||||
JPanel panel,
|
||||
JTextField field,
|
||||
int column,
|
||||
double weight) {
|
||||
GridBagConstraints constraints = new GridBagConstraints();
|
||||
constraints.gridx = column;
|
||||
constraints.weightx = weight;
|
||||
constraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
constraints.insets = new Insets(0, column == 0 ? 0 : 5, 0, 0);
|
||||
field.setPreferredSize(new Dimension(120, 29));
|
||||
panel.add(field, constraints);
|
||||
}
|
||||
|
||||
private void addInlineLabel(JPanel panel, String text, int column) {
|
||||
GridBagConstraints constraints = new GridBagConstraints();
|
||||
constraints.gridx = column;
|
||||
constraints.weightx = 0;
|
||||
constraints.insets = new Insets(0, column == 0 ? 0 : 12, 0, 5);
|
||||
JLabel label = new JLabel(text);
|
||||
label.setForeground(new Color(75, 88, 99));
|
||||
panel.add(label, constraints);
|
||||
}
|
||||
|
||||
private void addInlineSeparator(JPanel panel, String text, int column) {
|
||||
GridBagConstraints constraints = new GridBagConstraints();
|
||||
constraints.gridx = column;
|
||||
constraints.weightx = 0;
|
||||
constraints.insets = new Insets(0, 5, 0, 0);
|
||||
panel.add(new JLabel(text), constraints);
|
||||
}
|
||||
|
||||
private GridBagConstraints constraints(int column, int row) {
|
||||
GridBagConstraints constraints = new GridBagConstraints();
|
||||
constraints.gridx = column;
|
||||
@@ -664,6 +794,7 @@ public class SwingInstallationWizard {
|
||||
JLabel label = new JLabel(value);
|
||||
label.setFont(label.getFont().deriveFont(Font.BOLD, 19f));
|
||||
label.setForeground(new Color(35, 48, 58));
|
||||
label.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||
return label;
|
||||
}
|
||||
|
||||
@@ -677,6 +808,7 @@ public class SwingInstallationWizard {
|
||||
private JPanel summaryRow(String label, String value) {
|
||||
JPanel row = new JPanel(new BorderLayout(18, 0));
|
||||
row.setOpaque(false);
|
||||
row.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||
row.setBorder(BorderFactory.createEmptyBorder(7, 0, 7, 0));
|
||||
JLabel name = new JLabel(label);
|
||||
name.setPreferredSize(new Dimension(130, 20));
|
||||
@@ -691,7 +823,8 @@ public class SwingInstallationWizard {
|
||||
JPanel row = new JPanel(new BorderLayout(18, 0));
|
||||
row.setOpaque(false);
|
||||
row.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||
row.setMaximumSize(new Dimension(Integer.MAX_VALUE, 34));
|
||||
row.setBorder(BorderFactory.createEmptyBorder(7, 0, 7, 0));
|
||||
row.setMaximumSize(new Dimension(Integer.MAX_VALUE, 42));
|
||||
JLabel name = new JLabel(label);
|
||||
name.setFont(name.getFont().deriveFont(Font.BOLD));
|
||||
name.setPreferredSize(new Dimension(130, 28));
|
||||
|
||||
@@ -23,6 +23,7 @@ public class TechnobeeServiceInstallerApplication implements CommandLineRunner {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
disableAccidentalSpringDebug(args);
|
||||
SpringApplication application =
|
||||
new SpringApplication(TechnobeeServiceInstallerApplication.class);
|
||||
application.setWebApplicationType(WebApplicationType.NONE);
|
||||
@@ -39,6 +40,18 @@ public class TechnobeeServiceInstallerApplication implements CommandLineRunner {
|
||||
}
|
||||
}
|
||||
|
||||
static void disableAccidentalSpringDebug(String[] args) {
|
||||
boolean debugRequested = Arrays.stream(args)
|
||||
.anyMatch(argument -> "--debug".equals(argument)
|
||||
|| "--debug=true".equalsIgnoreCase(argument));
|
||||
if (!debugRequested && System.getProperty("debug") == null) {
|
||||
// DEBUG is commonly exported by developer tools with non-boolean
|
||||
// values. Spring maps it to its own debug switch unless a more
|
||||
// specific system property is present.
|
||||
System.setProperty("debug", "false");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String... args) {
|
||||
boolean cli = Arrays.asList(args).contains("--cli");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.cygnus.installer;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
@@ -108,6 +109,7 @@ class DeploymentWriterTest {
|
||||
.contains("MATRIX_IMAGE=\"registry.example.com/matrix:1.0.0\"")
|
||||
.contains("MATRIX_DB_URL=\"jdbc:postgresql://db:5432/matrix\"")
|
||||
.contains("REDIS_HOST=\"redis\"")
|
||||
.contains("REDIS_DATABASE=\"1\"")
|
||||
.contains("CYGNUS_CLOUD_BASE_URL=\"http://host.docker.internal:8090\"")
|
||||
.contains("CYGNUS_TOKEN_URL=\"http://host.docker.internal:8090/oauth2/token\"")
|
||||
.contains("CYGNUS_CLIENT_ID=\"matrix-client\"")
|
||||
@@ -121,4 +123,84 @@ class DeploymentWriterTest {
|
||||
assertThat(output.resolve("config/keys/client-signing-private.pem"))
|
||||
.isRegularFile();
|
||||
}
|
||||
|
||||
@Test
|
||||
void refusesToOverwriteCloudServiceConfiguration() throws Exception {
|
||||
Path cloudConfig = temporaryDirectory.resolve("config");
|
||||
Path cloudKeys = cloudConfig.resolve("keys");
|
||||
Files.createDirectories(cloudKeys);
|
||||
Path assertionPublic = cloudKeys.resolve("assertion-decryption-public.pem");
|
||||
Path loginPublic = cloudKeys.resolve("login-public.pem");
|
||||
Files.writeString(assertionPublic, "assertion-public-key");
|
||||
Files.writeString(loginPublic, "login-public-key");
|
||||
|
||||
var profile = new ProductProfile(
|
||||
"matrix",
|
||||
"Matrix",
|
||||
"matrix-onprem",
|
||||
"MATRIX_IMAGE",
|
||||
"matrix",
|
||||
"installation.yml",
|
||||
"MATRIX_INSTALLATION_CONFIG",
|
||||
"/srv/matrix/config/installation.yml",
|
||||
"8080:8080",
|
||||
"/matrix/",
|
||||
"/oauth2/token",
|
||||
assertionPublic,
|
||||
loginPublic,
|
||||
"cygnus-login-2026-01",
|
||||
List.of());
|
||||
|
||||
assertThatThrownBy(() -> new DeploymentWriter().write(
|
||||
temporaryDirectory,
|
||||
UUID.randomUUID(),
|
||||
"primary",
|
||||
"matrix-client",
|
||||
new ActivationDtos.ValidationResponse(
|
||||
"activation-token",
|
||||
OffsetDateTime.now().plusMinutes(5),
|
||||
UUID.randomUUID(),
|
||||
"matrix-client",
|
||||
"FULL",
|
||||
2),
|
||||
new ActivationDtos.RegistrationResponse(
|
||||
UUID.randomUUID(),
|
||||
UUID.randomUUID(),
|
||||
UUID.randomUUID(),
|
||||
null,
|
||||
"primary",
|
||||
1,
|
||||
"ACTIVE"),
|
||||
new InstallationKeyService().generate(),
|
||||
"assertion",
|
||||
new InstallerSettings(
|
||||
"matrix",
|
||||
URI.create("https://cloud.example.com"),
|
||||
URI.create("https://cloud.example.com"),
|
||||
"/api/v1/installations",
|
||||
"production",
|
||||
temporaryDirectory,
|
||||
temporaryDirectory,
|
||||
"1",
|
||||
new IniDocument(Map.of())),
|
||||
profile,
|
||||
"registry.example.com/matrix:1.0.0",
|
||||
Map.of(),
|
||||
new RuntimeConfiguration(
|
||||
"https://cloud.example.com",
|
||||
"jdbc:postgresql://db/matrix",
|
||||
"postgres",
|
||||
"secret",
|
||||
"redis",
|
||||
"7901",
|
||||
"secret",
|
||||
false,
|
||||
"PT10S",
|
||||
"PT30S")))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessageContaining("cloud-service configuration");
|
||||
|
||||
assertThat(assertionPublic).hasContent("assertion-public-key");
|
||||
assertThat(loginPublic).hasContent("login-public-key");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.cygnus.installer;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class TechnobeeServiceInstallerApplicationTest {
|
||||
|
||||
@AfterEach
|
||||
void clearDebugProperty() {
|
||||
System.clearProperty("debug");
|
||||
}
|
||||
|
||||
@Test
|
||||
void disablesDebugUnlessExplicitlyRequested() {
|
||||
TechnobeeServiceInstallerApplication.disableAccidentalSpringDebug(new String[0]);
|
||||
|
||||
assertThat(System.getProperty("debug")).isEqualTo("false");
|
||||
}
|
||||
|
||||
@Test
|
||||
void preservesExplicitDebugRequest() {
|
||||
TechnobeeServiceInstallerApplication.disableAccidentalSpringDebug(
|
||||
new String[] {"--debug"});
|
||||
|
||||
assertThat(System.getProperty("debug")).isNull();
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
spring:
|
||||
main:
|
||||
banner-mode: "off"
|
||||
application:
|
||||
name: technobee-service-installer
|
||||
technobee:
|
||||
installer:
|
||||
config: ${TECHNOBEE_INSTALLER_CONFIG:./installer.ini}
|
||||
version: ${TECHNOBEE_INSTALLER_VERSION:1.0.0}
|
||||
logging:
|
||||
level:
|
||||
root: WARN
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,3 +0,0 @@
|
||||
artifactId=technobee-service-installer
|
||||
groupId=com.cygnus
|
||||
version=1.0.0-SNAPSHOT
|
||||
@@ -1,36 +0,0 @@
|
||||
com/cygnus/installer/MachineAssertionService.class
|
||||
com/cygnus/installer/ActivationDtos$ValidationResponse.class
|
||||
com/cygnus/installer/SwingInstallationWizard$2.class
|
||||
com/cygnus/installer/CommandResult.class
|
||||
com/cygnus/installer/InstallationProgressListener.class
|
||||
com/cygnus/installer/ProductProfileRegistry.class
|
||||
com/cygnus/installer/InstallationRequest.class
|
||||
com/cygnus/installer/InstallerConfiguration.class
|
||||
com/cygnus/installer/ProductProfile.class
|
||||
com/cygnus/installer/InstallationWizard.class
|
||||
com/cygnus/installer/TechnobeeServiceInstallerApplication.class
|
||||
com/cygnus/installer/DeploymentWriter.class
|
||||
com/cygnus/installer/InstallationKeyService.class
|
||||
com/cygnus/installer/DockerComposeDeploymentService.class
|
||||
com/cygnus/installer/ActivationClient.class
|
||||
com/cygnus/installer/ActivationDtos$RegistrationResponse.class
|
||||
com/cygnus/installer/IniDocument.class
|
||||
com/cygnus/installer/SwingInstallationWizard$3.class
|
||||
com/cygnus/installer/InstallerConfigurationException.class
|
||||
com/cygnus/installer/DockerRegistryLoginService.class
|
||||
com/cygnus/installer/SwingInstallationWizard.class
|
||||
com/cygnus/installer/ActivationDtos.class
|
||||
com/cygnus/installer/DockerPrerequisiteChecker.class
|
||||
com/cygnus/installer/InstallerBootstrapProperties.class
|
||||
com/cygnus/installer/SwingInstallationWizard$1.class
|
||||
com/cygnus/installer/CommandExecutor.class
|
||||
com/cygnus/installer/IniConfigurationLoader.class
|
||||
com/cygnus/installer/InstallationService.class
|
||||
com/cygnus/installer/InstallationResult.class
|
||||
com/cygnus/installer/RuntimeConfiguration.class
|
||||
com/cygnus/installer/ActivationDtos$RegistrationRequest.class
|
||||
com/cygnus/installer/ActivationDtos$ValidationRequest.class
|
||||
com/cygnus/installer/PrerequisiteException.class
|
||||
com/cygnus/installer/InstallerSettings.class
|
||||
com/cygnus/installer/InstallationKeyPair.class
|
||||
com/cygnus/installer/SwingInstallationWizard$ProgressUpdate.class
|
||||
@@ -1,28 +0,0 @@
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/ActivationClient.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/ActivationDtos.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/CommandExecutor.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/CommandResult.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/DeploymentWriter.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/DockerComposeDeploymentService.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/DockerPrerequisiteChecker.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/DockerRegistryLoginService.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/IniConfigurationLoader.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/IniDocument.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/InstallationKeyPair.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/InstallationKeyService.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/InstallationProgressListener.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/InstallationRequest.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/InstallationResult.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/InstallationService.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/InstallationWizard.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/InstallerBootstrapProperties.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/InstallerConfiguration.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/InstallerConfigurationException.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/InstallerSettings.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/MachineAssertionService.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/PrerequisiteException.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/ProductProfile.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/ProductProfileRegistry.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/RuntimeConfiguration.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/SwingInstallationWizard.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/main/java/com/cygnus/installer/TechnobeeServiceInstallerApplication.java
|
||||
@@ -1,11 +0,0 @@
|
||||
com/cygnus/installer/MachineAssertionServiceTest.class
|
||||
com/cygnus/installer/DockerRegistryLoginServiceTest$CapturingExecutor.class
|
||||
com/cygnus/installer/DockerRegistryLoginServiceTest.class
|
||||
com/cygnus/installer/DockerComposeDeploymentServiceTest$CapturingExecutor.class
|
||||
com/cygnus/installer/InstallationServiceTest.class
|
||||
com/cygnus/installer/DockerPrerequisiteCheckerTest$1.class
|
||||
com/cygnus/installer/ProductProfileRegistryTest.class
|
||||
com/cygnus/installer/IniConfigurationLoaderTest.class
|
||||
com/cygnus/installer/DockerComposeDeploymentServiceTest.class
|
||||
com/cygnus/installer/DeploymentWriterTest.class
|
||||
com/cygnus/installer/DockerPrerequisiteCheckerTest.class
|
||||
@@ -1,8 +0,0 @@
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/test/java/com/cygnus/installer/DeploymentWriterTest.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/test/java/com/cygnus/installer/DockerComposeDeploymentServiceTest.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/test/java/com/cygnus/installer/DockerPrerequisiteCheckerTest.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/test/java/com/cygnus/installer/DockerRegistryLoginServiceTest.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/test/java/com/cygnus/installer/IniConfigurationLoaderTest.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/test/java/com/cygnus/installer/InstallationServiceTest.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/test/java/com/cygnus/installer/MachineAssertionServiceTest.java
|
||||
/Users/maddy/Projects/cygnus/matrix/cygnus-installer/src/test/java/com/cygnus/installer/ProductProfileRegistryTest.java
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,4 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
Test set: com.cygnus.installer.DeploymentWriterTest
|
||||
-------------------------------------------------------------------------------
|
||||
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.174 s -- in com.cygnus.installer.DeploymentWriterTest
|
||||
@@ -1,4 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
Test set: com.cygnus.installer.DockerComposeDeploymentServiceTest
|
||||
-------------------------------------------------------------------------------
|
||||
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.002 s -- in com.cygnus.installer.DockerComposeDeploymentServiceTest
|
||||
@@ -1,4 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
Test set: com.cygnus.installer.DockerPrerequisiteCheckerTest
|
||||
-------------------------------------------------------------------------------
|
||||
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.004 s -- in com.cygnus.installer.DockerPrerequisiteCheckerTest
|
||||
@@ -1,4 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
Test set: com.cygnus.installer.DockerRegistryLoginServiceTest
|
||||
-------------------------------------------------------------------------------
|
||||
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.010 s -- in com.cygnus.installer.DockerRegistryLoginServiceTest
|
||||
@@ -1,4 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
Test set: com.cygnus.installer.IniConfigurationLoaderTest
|
||||
-------------------------------------------------------------------------------
|
||||
Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.008 s -- in com.cygnus.installer.IniConfigurationLoaderTest
|
||||
@@ -1,4 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
Test set: com.cygnus.installer.InstallationServiceTest
|
||||
-------------------------------------------------------------------------------
|
||||
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.002 s -- in com.cygnus.installer.InstallationServiceTest
|
||||
@@ -1,4 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
Test set: com.cygnus.installer.MachineAssertionServiceTest
|
||||
-------------------------------------------------------------------------------
|
||||
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.570 s -- in com.cygnus.installer.MachineAssertionServiceTest
|
||||
@@ -1,4 +0,0 @@
|
||||
-------------------------------------------------------------------------------
|
||||
Test set: com.cygnus.installer.ProductProfileRegistryTest
|
||||
-------------------------------------------------------------------------------
|
||||
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.005 s -- in com.cygnus.installer.ProductProfileRegistryTest
|
||||
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user