From ff64103b4d85c62ae304049353da0f7ce886a43b Mon Sep 17 00:00:00 2001 From: Martin Weise <martin.weise@tuwien.ac.at> Date: Sun, 2 Apr 2023 17:09:15 +0200 Subject: [PATCH] SSL Support - Gateway has self-signed SSL certificate for all requests - Authentication service can be used securely behind Gateway - User service exposes self-registration endpoint --- .env.unix.example | 5 +- docker-compose.yml | 4 +- fda-authentication-service/Dockerfile | 4 +- fda-authentication-service/dbrepo-realm.json | 52 ++++++------ .../docker-entrypoint.sh | 4 +- fda-authentication-service/server.keystore | Bin 0 -> 2220 bytes .../service-register.sh | 7 +- .../java/at/tuwien/config/ReadyConfig.java | 2 +- .../tuwien/service/impl/ImageServiceImpl.java | 1 - fda-gateway-service/Dockerfile | 6 ++ fda-gateway-service/pom.xml | 8 ++ .../java/at/tuwien/config/ReadyConfig.java | 4 +- .../src/main/resources/application-docker.yml | 14 +++- .../src/main/resources/application-local.yml | 14 +++- .../src/main/resources/application.yml | 16 +++- fda-gateway-service/server.keystore | Bin 0 -> 2220 bytes ...JwtResponseDto.java => CreateUserDto.java} | 22 +++-- .../at/tuwien/api/auth/CredentialDto.java | 29 +++++++ .../at/tuwien/api/auth/SignupRequestDto.java | 5 +- .../at/tuwien/api/auth/TokenBriefDto.java | 43 ---------- .../java/at/tuwien/api/auth/TokenDto.java | 51 +++++++----- .../java/at/tuwien/entities/auth/Realm.java | 31 +++++++ .../java/at/tuwien/entities/user/User.java | 2 +- fda-query-service/pom.xml | 3 - fda-user-service/Dockerfile | 3 + fda-user-service/pom.xml | 30 +------ .../java/at/tuwien/endpoint/UserEndpoint.java | 6 +- .../src/main/resources/application-docker.yml | 5 ++ .../src/main/resources/application-local.yml | 9 +- .../src/main/resources/application.yml | 5 ++ .../src/test/resources/application.properties | 5 -- .../java/at/tuwien/config/GatewayConfig.java | 40 +++++++++ .../java/at/tuwien/config/ReadyConfig.java | 13 ++- .../exception/RealmNotFoundException.java | 21 +++++ .../exception/RemoteUnavailableException.java | 21 +++++ .../gateway/AuthenticationServiceGateway.java | 11 +++ .../AuthenticationServiceGatewayImpl.java | 77 ++++++++++++++++++ .../java/at/tuwien/mapper/UserMapper.java | 3 +- .../repository/elastic/UserIdxRepository.java | 10 +++ .../repository/jpa/RealmRepository.java | 14 ++++ .../java/at/tuwien/service/RealmService.java | 10 +++ .../java/at/tuwien/service/UserService.java | 4 +- .../tuwien/service/impl/RealmServiceImpl.java | 43 ++++++++++ .../tuwien/service/impl/UserServiceImpl.java | 33 +++++--- server.keystore | Bin 0 -> 2220 bytes 45 files changed, 520 insertions(+), 170 deletions(-) create mode 100644 fda-authentication-service/server.keystore create mode 100644 fda-gateway-service/server.keystore rename fda-metadata-db/api/src/main/java/at/tuwien/api/auth/{JwtResponseDto.java => CreateUserDto.java} (53%) create mode 100644 fda-metadata-db/api/src/main/java/at/tuwien/api/auth/CredentialDto.java delete mode 100644 fda-metadata-db/api/src/main/java/at/tuwien/api/auth/TokenBriefDto.java create mode 100644 fda-metadata-db/entities/src/main/java/at/tuwien/entities/auth/Realm.java create mode 100644 fda-user-service/services/src/main/java/at/tuwien/config/GatewayConfig.java create mode 100644 fda-user-service/services/src/main/java/at/tuwien/exception/RealmNotFoundException.java create mode 100644 fda-user-service/services/src/main/java/at/tuwien/exception/RemoteUnavailableException.java create mode 100644 fda-user-service/services/src/main/java/at/tuwien/gateway/AuthenticationServiceGateway.java create mode 100644 fda-user-service/services/src/main/java/at/tuwien/gateway/impl/AuthenticationServiceGatewayImpl.java create mode 100644 fda-user-service/services/src/main/java/at/tuwien/repository/elastic/UserIdxRepository.java create mode 100644 fda-user-service/services/src/main/java/at/tuwien/repository/jpa/RealmRepository.java create mode 100644 fda-user-service/services/src/main/java/at/tuwien/service/RealmService.java create mode 100644 fda-user-service/services/src/main/java/at/tuwien/service/impl/RealmServiceImpl.java create mode 100644 server.keystore diff --git a/.env.unix.example b/.env.unix.example index bbc4ce743d..2e4923867f 100644 --- a/.env.unix.example +++ b/.env.unix.example @@ -14,4 +14,7 @@ BROKER_PASSWORD=fda KEYCLOAK_ADMIN=fda KEYCLOAK_ADMIN_PASSWORD=fda BROKER_CONSUMERS=2 -WEBSITE=http://example.com \ No newline at end of file +WEBSITE=http://example.com +KEY_ALIAS=server +KEY_STORE_PATH=/server.keystore +KEY_STORE_PASSWORD=password \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 07f8df8fa9..4fffbf9e7e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -235,8 +235,10 @@ services: ports: - "9099:9099" depends_on: + fda-authentication-service: + condition: service_healthy fda-metadata-db: - condition: service_started + condition: service_healthy logging: driver: json-file diff --git a/fda-authentication-service/Dockerfile b/fda-authentication-service/Dockerfile index 38e737360b..243d968918 100644 --- a/fda-authentication-service/Dockerfile +++ b/fda-authentication-service/Dockerfile @@ -13,8 +13,8 @@ ENV KC_DB=mariadb WORKDIR /opt/keycloak -# for demonstration purposes only, please make sure to use proper certificates in production instead -RUN keytool -genkeypair -storepass password -storetype PKCS12 -keyalg RSA -keysize 2048 -dname "CN=server" -alias server -ext "SAN:c=DNS:localhost,IP:127.0.0.1" -keystore conf/server.keystore +COPY ./server.keystore ./conf/server.keystore + RUN /opt/keycloak/bin/kc.sh build ###### SECOND STAGE ###### diff --git a/fda-authentication-service/dbrepo-realm.json b/fda-authentication-service/dbrepo-realm.json index 0e26cf80c9..2007120dde 100644 --- a/fda-authentication-service/dbrepo-realm.json +++ b/fda-authentication-service/dbrepo-realm.json @@ -26,7 +26,7 @@ "oauth2DeviceCodeLifespan" : 600, "oauth2DevicePollingInterval" : 5, "enabled" : true, - "sslRequired" : "none", + "sslRequired" : "external", "registrationAllowed" : false, "registrationEmailAsUsername" : false, "rememberMe" : false, @@ -843,7 +843,7 @@ "otpPolicyLookAheadWindow" : 1, "otpPolicyPeriod" : 30, "otpPolicyCodeReusable" : false, - "otpSupportedApplications" : [ "totpAppGoogleName", "totpAppFreeOTPName", "totpAppMicrosoftAuthenticatorName" ], + "otpSupportedApplications" : [ "totpAppMicrosoftAuthenticatorName", "totpAppGoogleName", "totpAppFreeOTPName" ], "webAuthnPolicyRpEntityName" : "keycloak", "webAuthnPolicySignatureAlgorithms" : [ "ES256" ], "webAuthnPolicyRpId" : "", @@ -1761,7 +1761,7 @@ "subType" : "anonymous", "subComponents" : { }, "config" : { - "allowed-protocol-mapper-types" : [ "oidc-usermodel-property-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-address-mapper", "oidc-usermodel-attribute-mapper", "saml-user-attribute-mapper", "oidc-full-name-mapper", "saml-role-list-mapper", "saml-user-property-mapper" ] + "allowed-protocol-mapper-types" : [ "saml-user-attribute-mapper", "saml-user-property-mapper", "oidc-address-mapper", "oidc-usermodel-attribute-mapper", "oidc-usermodel-property-mapper", "saml-role-list-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-full-name-mapper" ] } }, { "id" : "1849e52a-b8c9-44a8-af3d-ee19376a1ed1", @@ -1787,7 +1787,7 @@ "subType" : "authenticated", "subComponents" : { }, "config" : { - "allowed-protocol-mapper-types" : [ "saml-user-property-mapper", "oidc-full-name-mapper", "oidc-usermodel-property-mapper", "saml-role-list-mapper", "oidc-usermodel-attribute-mapper", "saml-user-attribute-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper" ] + "allowed-protocol-mapper-types" : [ "saml-user-property-mapper", "saml-role-list-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-property-mapper", "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "oidc-full-name-mapper" ] } } ], "org.keycloak.userprofile.UserProfileProvider" : [ { @@ -1845,7 +1845,7 @@ "internationalizationEnabled" : false, "supportedLocales" : [ ], "authenticationFlows" : [ { - "id" : "5eb1d49c-38cd-41a8-9557-13bcffb1a642", + "id" : "6fa20b3b-44fc-40ba-b310-bb2e729d53b9", "alias" : "Account verification options", "description" : "Method with which to verity the existing account", "providerId" : "basic-flow", @@ -1867,7 +1867,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "29e68803-3d8d-4fe5-af03-0814e35a6ed3", + "id" : "c4f55400-b209-4eea-b996-70a19bea428e", "alias" : "Authentication Options", "description" : "Authentication options.", "providerId" : "basic-flow", @@ -1896,7 +1896,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "aeadaa3b-f3d2-47ef-9e0a-ea4b737fe684", + "id" : "e43378cd-51b1-4978-8083-c01b8ab9e4c7", "alias" : "Browser - Conditional OTP", "description" : "Flow to determine if the OTP is required for the authentication", "providerId" : "basic-flow", @@ -1918,7 +1918,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "4c958b93-579e-45da-8471-a6aebc439641", + "id" : "db5f2382-dabd-4a38-901b-95eff1d60c14", "alias" : "Direct Grant - Conditional OTP", "description" : "Flow to determine if the OTP is required for the authentication", "providerId" : "basic-flow", @@ -1940,7 +1940,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "6878c43f-0aa7-40c6-bf28-f984029e893b", + "id" : "29a20ae2-7a1a-44fd-888a-fac7954cfe01", "alias" : "First broker login - Conditional OTP", "description" : "Flow to determine if the OTP is required for the authentication", "providerId" : "basic-flow", @@ -1962,7 +1962,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "aae75803-fb3c-4c74-9ee7-73fc897aad05", + "id" : "3aa766d9-06ec-4073-9143-d810e12a2233", "alias" : "Handle Existing Account", "description" : "Handle what to do if there is existing account with same email/username like authenticated identity provider", "providerId" : "basic-flow", @@ -1984,7 +1984,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "0987a7fe-5e31-40b1-be1f-6cd4a5a76e43", + "id" : "6a72a53f-bf1e-4c06-a366-71a4d963d5d0", "alias" : "Reset - Conditional OTP", "description" : "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.", "providerId" : "basic-flow", @@ -2006,7 +2006,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "68078236-033e-4f17-b02f-fb5f401be3fe", + "id" : "5cb272da-a960-4429-b090-e676b358bb80", "alias" : "User creation or linking", "description" : "Flow for the existing/non-existing user alternatives", "providerId" : "basic-flow", @@ -2029,7 +2029,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "28c746e7-fc22-4c61-872a-26670fffb8ed", + "id" : "58c9a9c9-3a95-45bf-9c40-d2926246158a", "alias" : "Verify Existing Account by Re-authentication", "description" : "Reauthentication of existing account", "providerId" : "basic-flow", @@ -2051,7 +2051,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "502957db-db9d-4138-a5e3-90fce22bff15", + "id" : "976a2b1b-0a72-4c7b-9ebb-356595ad08b4", "alias" : "browser", "description" : "browser based authentication", "providerId" : "basic-flow", @@ -2087,7 +2087,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "9312b6c7-f999-4285-ae9f-e365666066e7", + "id" : "63b290b2-4828-457b-9ed4-c68aa477cd2b", "alias" : "clients", "description" : "Base authentication for clients", "providerId" : "client-flow", @@ -2123,7 +2123,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "31c2af88-b37c-4fdb-8dec-23a5ba145114", + "id" : "9c557280-9319-45c7-8656-198765ab5f23", "alias" : "direct grant", "description" : "OpenID Connect Resource Owner Grant", "providerId" : "basic-flow", @@ -2152,7 +2152,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "c11ae35d-772a-4a1f-9934-a1945b45d617", + "id" : "6b0351e2-9b6b-475a-b59b-045096c2bbfa", "alias" : "docker auth", "description" : "Used by Docker clients to authenticate against the IDP", "providerId" : "basic-flow", @@ -2167,7 +2167,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "0485179d-460c-4ad0-b0b2-02bbf57eb012", + "id" : "39d51855-eabd-4b38-b2da-04046c3d156c", "alias" : "first broker login", "description" : "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", "providerId" : "basic-flow", @@ -2190,7 +2190,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "aa1b06b4-1c12-4f7c-9d5a-6422ab5bb89a", + "id" : "ee67da7f-0738-4ef6-a07f-cb814a171dc6", "alias" : "forms", "description" : "Username, password, otp and other auth forms.", "providerId" : "basic-flow", @@ -2212,7 +2212,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "fc52dc5f-16ee-499e-ad0a-ba04093efc33", + "id" : "011fb692-45ac-487f-8124-56836be0fbfe", "alias" : "http challenge", "description" : "An authentication flow based on challenge-response HTTP Authentication Schemes", "providerId" : "basic-flow", @@ -2234,7 +2234,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "576fb8d9-96b4-464a-a2b5-655c61755ec0", + "id" : "7fe214c5-6462-4965-8a37-6c5753f27a97", "alias" : "registration", "description" : "registration flow", "providerId" : "basic-flow", @@ -2250,7 +2250,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "a026a910-1a04-4eb0-9fe2-6eb72139a39b", + "id" : "e140eca6-cb4e-4db9-811a-f2c8a012d873", "alias" : "registration form", "description" : "registration form", "providerId" : "form-flow", @@ -2286,7 +2286,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "0d0e32f3-7030-42fa-be83-528281d9eca0", + "id" : "715bab3d-905a-4f91-8c62-b141cfd89002", "alias" : "reset credentials", "description" : "Reset credentials for a user if they forgot their password or something", "providerId" : "basic-flow", @@ -2322,7 +2322,7 @@ "userSetupAllowed" : false } ] }, { - "id" : "ec850fcc-5b8c-4109-9cf4-a16f84cd7804", + "id" : "83dd0a05-4fc5-47d3-84d8-f6f2641e4de3", "alias" : "saml ecp", "description" : "SAML ECP Profile Authentication Flow", "providerId" : "basic-flow", @@ -2338,13 +2338,13 @@ } ] } ], "authenticatorConfig" : [ { - "id" : "d42b19d3-2efe-4879-9ce0-7c055a3d949e", + "id" : "c07fe13c-bb0d-451b-955e-078376f851db", "alias" : "create unique user config", "config" : { "require.password.update.after.registration" : "false" } }, { - "id" : "f1c71d63-f83f-432d-b9b4-e1a97095b5e1", + "id" : "5b25a33e-a4dc-4827-a4e8-62fc1f383cef", "alias" : "review profile config", "config" : { "update.profile.on.first.login" : "missing" diff --git a/fda-authentication-service/docker-entrypoint.sh b/fda-authentication-service/docker-entrypoint.sh index ca82a7bada..d8e0fdcd85 100644 --- a/fda-authentication-service/docker-entrypoint.sh +++ b/fda-authentication-service/docker-entrypoint.sh @@ -1,6 +1,6 @@ #!/bin/bash -/app/service-register.sh authentication-service 8080 -(while sleep 60; do bash /app/service-register.sh authentication-service 8080; done) & +/app/service-register.sh authentication-service 8443 8080 +(while sleep 60; do bash /app/service-register.sh authentication-service 8443 8080; done) & /opt/keycloak/bin/kc.sh start-dev --import-realm diff --git a/fda-authentication-service/server.keystore b/fda-authentication-service/server.keystore new file mode 100644 index 0000000000000000000000000000000000000000..93e5c28b23293910dac23a3e974cb485524a3a17 GIT binary patch literal 2220 zcmezO_TO6u1_mYu1_nkjW-CrDDoZV5U|?)_(k^+$z`)96(8Ti3fRBw!n~jl$QHx2C zk&%^wrHSR0ft0_Tv%S~twhg>Bw_i+23rqSbF)!NX+rsV9$F+`rtCCI+T>hpdIP+ik z6|Y4l9726*RUC>&8EJ(+sz+X`$}Z!{YmeLb)WCku16A2LWv-q(r&||HF#Hp=^Y6}k zuL?|<*&2#oA6IwJw!0)F7u&pMzY+WEy{8?2a~%&>6}$QW(izn^rJZ~y|CgQ#*zwU$ zb#7O8$(>)S#VaP(*DkxwbB@X4_U<VMZd7p02;Il^G2LX2-leQ5|M}%td7qLv&g0W@ z?7Vr&iwMK8B@$8+F}Afgx0L(6xOrU4JTm6Rg34dgAJ!f|;$S<+&|KQ@S&Y+nUuDhn zn>_w`o;p{+!0(&;<dmXy_V=@PKkup;=gm_nzJIx}_1VVBaTnTtd@$U>n13-?j!)H` zwU@JFiGz$m;-bkt((_#plo`yM7WZ*kOKaGpC@!NfyuT9!K1!wBk6FXw{wLLMJKw+A zAs0Vb&tq%rta|n&>)*DpR)@?P9(Ar~KJN<Lapa@R&-E?hMMw4puiokVW$DHrayB-z zX05G#%pEhK{Mdz^joqG1Pg45#ymfp1L2~0Xx#9;a>{i}=!4fFALyEs{TaJcX(Vms3 z3V%u&wk@o@zr`}wb~Vd8sf~LikN(k)byiQS78Kd>^nL$}FP(2f7n^v$+FblyVoKqM zMKgbi9T&F`II=70VVN6?ZC3kr^`}X5YGaghGU6sSC@kpibJBP@x3)8Ci-+^`^;xX4 z(`Ao*Uny=~8`XBSA@J1B<`s|Agn!)FyJSm+|9)Fbm8P@;(R<=dUFv;q@&;U+?|kIa ztt!92<=TJ6ugjbmeG}t<#9V(f>B59vWje+G)c#pl`&ZXLZ*VwmWT5<mUEbGWo;H7Q z`Tyz%87B*NSuSO-(A)lo@7K+B{2{sj_HE#sQ7V7X$>FS!lh5sj_3|?mZn$T7uM3+l zH>>uW!Ooge@f52|UT5UYYZyhCrC%@oEErPiSt%@(yfMe3R8MNVFh|bT8IKdCZ!F<^ zHJeXf%zrjx^P}@7TVe|)E^+!>R%q3|+V-`k#ghB=G6pWvKN9*p7gWD2m_B1p!_S)Y z^9v+|jz2hbaa;G?=yj}({|~x|{gFI>N_g-5HTO761f(Ss9Gb7}{$ix|#A*5Y?UBr7 zr8?6jwp~lsNKW=Xy2;aNr^7WhBOSvefBvuo!P`!jp5@!}$R^Y9{sUgNJ$~z7JSpB5 zAfmi@>2>`R)}b>uDI7Vsb3)bZ6ZJ{kPyQ_wd8@kRr0rq`IsZvIjVX1PrUX{bTah;Z z+Ds$%pZBbpa&{K~-8lK&>p6>fW!CesottD?{Ns?zd)>nJKkpn)ZB_N@T%>Tq^lIQ1 zqd=w!eZ9XnSFV?+i8j<qT5{bv@4%#<whgQyFAl%|bTBGFS$B^*can?viu9lfyYD)F z68Ig*ryyy&{_nl8#|dW?6V5G=SI)lDfBk*UAx6eKo_AFa9^7_yx@%xqY@KV@mLm(= zc5W@*u>PW}m`ufwH6_OyyQ<c8JWcURJvZyv^Br}%Qx^Xc`)%@d8*`ESnb!3SmQG&l zd8(-4X~egCb~EDtG0SSHR`?2TE^t3n&ary+!a|j=J_U73L9ZRP`A_NoGs?{IPOe$* z{<yU%`GReEh5Dp5t*!i5tK4IwpOta6D*7L>VQJa&@7V&$s$;dUq<!jxCjE?Wc5jq% z+kea~U@C8kU+>3TKVHd&nlcOL-&9!K`*oV^vBjTOgG)x%2t88+O9lq!WP>K=c!MS; z_XW&Mj7&@{vA-sB8St`kYPET^edlFl<Yr|sNHF9!;ACSCWnmL$attx#H{b<v*oE1` zGE?*N5)B0m_&@?&!t5cT3gMZld4^I35+D(7VL=zCpwxnV1((#a)SUc+)S_ZTAp-%B z9J4TIPJVJ?PDXxliGiFruaU8ViGh)!v9Xb{S(G@hv9W=%u>q7z2NyIkDj|EDk(GhD ziIJbdpox)-sfm%1;c>U9r`y>Dl}Dol3{II&o07Yd-z2c>g~s_4tFQICrSThGj_itF zIOR)&gwfT=xV(umOL-$*v-;$%J8L$$#7IPLE?s_V={kikKSgiqs-4f7WGVCbgU=Qz zEyhnO@0M=O6f(S|c80xI*_LbC_m)RlS+-rBJGp+X6Q5e{V01=y?S}v9rZszR=NzuB z-Kk|?JL~p@#WPxG+>!CRcFgq2t*)=xu2OfSye|GeJimQ6mu#Gq-+8~YOOj=?atx%o z3}ZNFYl*v?S11<c`z(;0*UX^OFr6c+D0}wLimA)fe$Re7^S%DrzGF9S#sB=Bo}pi? zVKlq->m^3>$BuVr&D`9~rYa;Z-pRzw$iTQ*(LmlnmW?@7mXAe@MdVZ6vgckRjrpZ> zf(~*Dnts*Kw_1Q4h}_^nWMpW+q4ILhp1-NH_0o@@x+?wQ_0zqlCS_c{mBUfIAmjN& z&!W)$*~;-!7IW<DBJEqAE8TCp{8f53*Xr1+)Y9ndC+&qUDaO6osda4ieVZ#mnp}^C z-Hs){efP81;7NPT<caUiPI4rz-9Bqq$|7sqnbv2W`6oqbN_%qne|y+*?M97VaEkjY zj?|36$1YqtJD%UKPC7hA-aYDJ^_Tv`H)M|Ilp8u1e2$dJT@^dKJ?`{`9XjqO3b*uy z-QL~wVrtcNj&kp3vFwF`&x31KL<5y~Ca>4I{d&Qhfc*BP$;&o$u)OX(XuDk`XWsJX z)w#<=SC((ODfs5@udhdnuFleG|EG5T)t|3|KX$MOKH9FZ(MOW4muX_j&kF$`^D6+s C1<soQ literal 0 HcmV?d00001 diff --git a/fda-authentication-service/service-register.sh b/fda-authentication-service/service-register.sh index 72734426bb..2d7f64be97 100755 --- a/fda-authentication-service/service-register.sh +++ b/fda-authentication-service/service-register.sh @@ -9,7 +9,8 @@ EUREKA_URI="http://$EUREKA_HOST:$EUREKA_PORT" SERVICE_NAME="$1" SERVICE_PROTOCOL="http" SERVICE_HOST="$1" -SERVICE_PORT="${2:-9000}" +SECURE_PORT="${2:-9000}" +SERVICE_PORT="${3:-9000}" SERVICE_URI="$SERVICE_PROTOCOL://$SERVICE_HOST:$SERVICE_PORT" HOME_URI="$SERVICE_URI/realms/dbrepo" @@ -72,8 +73,8 @@ cat <<EOF > /tmp/json.json "@enabled": "true" }, "securePort": { - "\$": "$SERVICE_PORT", - "@enabled": "false" + "\$": "$SECURE_PORT", + "@enabled": "true" }, "vipAddress": "$SERVICE_HOST", "secureVipAddress": "$SERVICE_HOST", diff --git a/fda-container-service/services/src/main/java/at/tuwien/config/ReadyConfig.java b/fda-container-service/services/src/main/java/at/tuwien/config/ReadyConfig.java index 00c5a1f3dc..37617f6ccf 100644 --- a/fda-container-service/services/src/main/java/at/tuwien/config/ReadyConfig.java +++ b/fda-container-service/services/src/main/java/at/tuwien/config/ReadyConfig.java @@ -37,7 +37,7 @@ public class ReadyConfig { imageService.pull(imageRepository, imageTag); } else { log.debug("image {}:{} is present on the host", imageRepository, imageTag); - log.debug("skip pulling image {}:{}", imageRepository, imageTag); + log.trace("skip pulling image {}:{}", imageRepository, imageTag); } Files.touch(new File(readyPath)); log.info("Service is ready"); diff --git a/fda-container-service/services/src/main/java/at/tuwien/service/impl/ImageServiceImpl.java b/fda-container-service/services/src/main/java/at/tuwien/service/impl/ImageServiceImpl.java index 682ced6609..ccb3dbae79 100644 --- a/fda-container-service/services/src/main/java/at/tuwien/service/impl/ImageServiceImpl.java +++ b/fda-container-service/services/src/main/java/at/tuwien/service/impl/ImageServiceImpl.java @@ -162,7 +162,6 @@ public class ImageServiceImpl implements ImageService { public boolean exists(String repository, String tag) { final List<Image> images = dockerClient.listImagesCmd() .exec(); - log.trace("found images {}", images); return images.stream() .filter(i -> Objects.nonNull(i.getRepoTags())) .filter(i -> i.getRepoTags().length > 0) diff --git a/fda-gateway-service/Dockerfile b/fda-gateway-service/Dockerfile index f8aea4c73b..a270239d58 100644 --- a/fda-gateway-service/Dockerfile +++ b/fda-gateway-service/Dockerfile @@ -21,6 +21,12 @@ ENV METADATA_USERNAME=postgres ENV METADATA_PASSWORD=postgres ENV GATEWAY_ENDPOINT=http://gateway-service:9095 ENV LOG_LEVEL=debug +ENV KEY_ALIAS=server +ENV KEY_PASS=password +ENV KEY_STORE=/server.keystore +ENV KEY_STORE_PASS=password + +COPY ./server.keystore /server.keystore COPY ./service_ready /usr/bin RUN chmod +x /usr/bin/service_ready diff --git a/fda-gateway-service/pom.xml b/fda-gateway-service/pom.xml index 210f10156c..5110b896d8 100644 --- a/fda-gateway-service/pom.xml +++ b/fda-gateway-service/pom.xml @@ -12,6 +12,14 @@ <version>1.1.0-alpha</version> <name>fda-gateway-service</name> <description>Demo project for Spring Boot</description> + <url>https://dbrepo-docs.ossdip.at</url> + <developers> + <developer> + <name>Martin Weise</name> + <email>martin.weise@tuwien.ac.at</email> + <organization>TU Wien</organization> + </developer> + </developers> <packaging>pom</packaging> <modules> diff --git a/fda-gateway-service/rest-service/src/main/java/at/tuwien/config/ReadyConfig.java b/fda-gateway-service/rest-service/src/main/java/at/tuwien/config/ReadyConfig.java index f4eae349a4..2250fa5088 100644 --- a/fda-gateway-service/rest-service/src/main/java/at/tuwien/config/ReadyConfig.java +++ b/fda-gateway-service/rest-service/src/main/java/at/tuwien/config/ReadyConfig.java @@ -18,9 +18,7 @@ public class ReadyConfig { private String readyPath; @EventListener(ApplicationReadyEvent.class) - public void init() throws IOException, InterruptedException { - log.info("Wait more for gateway start"); - Thread.sleep(20 * 1000L); + public void init() throws IOException { Files.touch(new File(readyPath)); } diff --git a/fda-gateway-service/rest-service/src/main/resources/application-docker.yml b/fda-gateway-service/rest-service/src/main/resources/application-docker.yml index 7c42301ea6..b1eda86566 100644 --- a/fda-gateway-service/rest-service/src/main/resources/application-docker.yml +++ b/fda-gateway-service/rest-service/src/main/resources/application-docker.yml @@ -22,8 +22,20 @@ spring: name: gateway-service cloud: loadbalancer.ribbon.enabled: false + gateway: + httpclient: + ssl: + useInsecureTrustManager: true management.endpoints.web.exposure.include: health,info,prometheus -server.port: 9095 +server: + port: 9095 + ssl: + enabled: true + key-alias: "${KEY_ALIAS}" + key-store: "${KEY_STORE}" + key-store-type: jks + key-store-password: "${KEY_STORE_PASS}" + key-password: "${KEY_PASS}" logging: pattern.console: "%d %highlight(%-5level) %msg%n" level: diff --git a/fda-gateway-service/rest-service/src/main/resources/application-local.yml b/fda-gateway-service/rest-service/src/main/resources/application-local.yml index 6c2aeb22df..ab294c2a57 100644 --- a/fda-gateway-service/rest-service/src/main/resources/application-local.yml +++ b/fda-gateway-service/rest-service/src/main/resources/application-local.yml @@ -22,8 +22,20 @@ spring: name: gateway-service cloud: loadbalancer.ribbon.enabled: false + gateway: + httpclient: + ssl: + useInsecureTrustManager: true management.endpoints.web.exposure.include: health,info,prometheus -server.port: 9095 +server: + port: 9095 + ssl: + enabled: true + key-alias: server + key-store: "./server.keystore" + key-store-type: jks + key-store-password: password + key-password: password logging: pattern.console: "%d %highlight(%-5level) %msg%n" level: diff --git a/fda-gateway-service/rest-service/src/main/resources/application.yml b/fda-gateway-service/rest-service/src/main/resources/application.yml index 21e4e554b3..94983082cb 100644 --- a/fda-gateway-service/rest-service/src/main/resources/application.yml +++ b/fda-gateway-service/rest-service/src/main/resources/application.yml @@ -17,9 +17,23 @@ spring: time_zone: UTC application: name: gateway-service + cloud: + loadbalancer.ribbon.enabled: false + gateway: + httpclient: + ssl: + useInsecureTrustManager: true springdoc.swagger-ui.enabled: false management.endpoints.web.exposure.include: health,info,prometheus -server.port: 9095 +server: + port: 9095 + ssl: + enabled: true + key-alias: "${KEY_ALIAS}" + key-store: "${KEY_STORE}" + key-store-type: jks + key-store-password: "${KEY_STORE_PASS}" + key-password: "${KEY_PASS}" logging: pattern.console: "%d %highlight(%-5level) %msg%n" level: diff --git a/fda-gateway-service/server.keystore b/fda-gateway-service/server.keystore new file mode 100644 index 0000000000000000000000000000000000000000..93e5c28b23293910dac23a3e974cb485524a3a17 GIT binary patch literal 2220 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 C1<soQ literal 0 HcmV?d00001 diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/auth/JwtResponseDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/auth/CreateUserDto.java similarity index 53% rename from fda-metadata-db/api/src/main/java/at/tuwien/api/auth/JwtResponseDto.java rename to fda-metadata-db/api/src/main/java/at/tuwien/api/auth/CreateUserDto.java index c92b4913c8..d300e66967 100644 --- a/fda-metadata-db/api/src/main/java/at/tuwien/api/auth/JwtResponseDto.java +++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/auth/CreateUserDto.java @@ -3,6 +3,8 @@ package at.tuwien.api.auth; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; +import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.util.List; @@ -12,22 +14,26 @@ import java.util.List; @Builder @AllArgsConstructor @NoArgsConstructor -public class JwtResponseDto { +public class CreateUserDto { @NotNull - @ToString.Exclude - private String token; - - private String type; - - private Long id; + @Schema(example = "true") + private Boolean enabled; + @NotBlank @Schema(example = "user") private String username; + @NotBlank + @Email @Schema(example = "user@example.com") private String email; - private List<String> roles; + private String firstName; + + private String lastName; + + @NotNull + private List<CredentialDto> credentials; } diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/auth/CredentialDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/auth/CredentialDto.java new file mode 100644 index 0000000000..fe1400d3ab --- /dev/null +++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/auth/CredentialDto.java @@ -0,0 +1,29 @@ +package at.tuwien.api.auth; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +@Getter +@Setter +@ToString +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class CredentialDto { + + @NotBlank + @Schema(example = "password") + private String type; + + @NotBlank + @Schema(example = "abc123") + private String value; + + @NotNull + @Schema(example = "false") + private Boolean temporary; + +} diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/auth/SignupRequestDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/auth/SignupRequestDto.java index 7f6f3937bc..3f6784bdd0 100644 --- a/fda-metadata-db/api/src/main/java/at/tuwien/api/auth/SignupRequestDto.java +++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/auth/SignupRequestDto.java @@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import javax.validation.constraints.Email; +import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; @@ -15,12 +16,12 @@ import javax.validation.constraints.Pattern; @NoArgsConstructor public class SignupRequestDto { - @NotNull + @NotBlank @Pattern(regexp = "^[a-z0-9]{3,}$") @Schema(example = "user") private String username; - @NotNull + @NotBlank @Email @Schema(example = "user@example.com") private String email; diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/auth/TokenBriefDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/auth/TokenBriefDto.java deleted file mode 100644 index cbb5060540..0000000000 --- a/fda-metadata-db/api/src/main/java/at/tuwien/api/auth/TokenBriefDto.java +++ /dev/null @@ -1,43 +0,0 @@ -package at.tuwien.api.auth; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.*; - -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import java.time.Instant; - -@Getter -@Setter -@ToString -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class TokenBriefDto { - - @NotNull - private Long id; - - @NotBlank - @JsonProperty("token_hash") - @Schema(example = "5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03") - private String tokenHash; - - @NotNull - @Schema(example = "2020-08-04 11:12:00") - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "UTC") - private Instant created; - - @JsonProperty("last_used") - @Schema(example = "2020-08-04 11:12:00") - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "UTC") - private Instant lastUsed; - - @NotNull - @Schema(example = "2020-08-04 11:12:00") - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "UTC") - private Instant expires; - -} diff --git a/fda-metadata-db/api/src/main/java/at/tuwien/api/auth/TokenDto.java b/fda-metadata-db/api/src/main/java/at/tuwien/api/auth/TokenDto.java index 1cf442509c..cf3399dbe9 100644 --- a/fda-metadata-db/api/src/main/java/at/tuwien/api/auth/TokenDto.java +++ b/fda-metadata-db/api/src/main/java/at/tuwien/api/auth/TokenDto.java @@ -1,13 +1,11 @@ package at.tuwien.api.auth; -import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; -import java.time.Instant; @Getter @Setter @@ -17,31 +15,44 @@ import java.time.Instant; @NoArgsConstructor public class TokenDto { - @NotNull - private Long id; + @NotBlank + @JsonProperty("access_token") + @Schema(example = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJBbFdvalRsa1dBSVVoYTJLWjFvOEluWEtNbVAzUTg0STZiMFFHYkR6aEpvIn0.eyJleHAiOjE2ODAyNjgyNjgsImlhdCI6MTY4MDI2ODIwOCwianRpIjoiNjkwNjRlNTQtODNhNS00NGYxLWE3OTItNWFjOWU4OTA5YTlkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy9tYXN0ZXIiLCJzdWIiOiI4MjQ2OWMyMS0yYjNjLTRmMDctODg1Yi1hMzViMGQ5YTJhNjYiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJhZG1pbi1jbGkiLCJzZXNzaW9uX3N0YXRlIjoiNDQ1ODA3ZWUtMjg3Ni00NjFkLWE4ZjMtNGQyN2IzMGMyMWZhIiwiYWNyIjoiMSIsInNjb3BlIjoicHJvZmlsZSBlbWFpbCIsInNpZCI6IjQ0NTgwN2VlLTI4NzYtNDYxZC1hOGYzLTRkMjdiMzBjMjFmYSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoiZmRhIn0.IOQxqWvlPDV9WuFOeLVG-ayexbK8OqylPABghEMSbMpmNlQhSAjbjaMY31uU-uADZRHB-mC8bmRS5PoWNtanuhz0lORDCeissFsbv0UL9Q42CaxG75vFAAD5WsdIHIr-dtEjEiXYtu-qwdg83griAUeO119TTdgldyPxo4jWzNw0ui6W7r4LqP4fSk31iJfxR5urgs5k6Ctzg-fXCORT31-nKz_YJQwLoPO9j4afX_1mnCXY5qFGMSrmPKzB0CArZfUpa_4nqt4Y768yOC3gigAyCjXtvXKkgCmARPSRjERGDdTb6SGbAwRDiVHVy9wy7XZwOcCFMEra9H7mV0Mx2A") + private String accessToken; @NotBlank - @JsonProperty("token_hash") - @Schema(example = "5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03") - private String tokenHash; + @JsonProperty("refresh_token") + @Schema(example = "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI4YTczZGYwZS03NzMwLTRiZDEtOGVhOC1mZTdjZWViNmMxYWMifQ.eyJleHAiOjE2ODAyNzAwMDgsImlhdCI6MTY4MDI2ODIwOCwianRpIjoiNWYyNDIwNDItNmJmZi00ZTQ2LTg2NTAtNDBhY2E3YjVkZjMyIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy9tYXN0ZXIiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL21hc3RlciIsInN1YiI6IjgyNDY5YzIxLTJiM2MtNGYwNy04ODViLWEzNWIwZDlhMmE2NiIsInR5cCI6IlJlZnJlc2giLCJhenAiOiJhZG1pbi1jbGkiLCJzZXNzaW9uX3N0YXRlIjoiNDQ1ODA3ZWUtMjg3Ni00NjFkLWE4ZjMtNGQyN2IzMGMyMWZhIiwic2NvcGUiOiJwcm9maWxlIGVtYWlsIiwic2lkIjoiNDQ1ODA3ZWUtMjg3Ni00NjFkLWE4ZjMtNGQyN2IzMGMyMWZhIn0.-GltWGkIaKUJ4AqRYnGHblTr0ygZm2CsRQB6zz5ePm4") + private String refreshToken; + + @NotBlank + @JsonProperty("token_type") + @Schema(example = "Bearer") + private String tokenType; @NotNull - @Schema(example = "2020-08-04 11:12:00") - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "UTC") - private Instant created; + @JsonProperty("expires_in") + @Schema(example = "60") + private Long expiresIn; - @JsonProperty("last_used") - @Schema(example = "2020-08-04 11:12:00") - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "UTC") - private Instant lastUsed; + @NotNull + @JsonProperty("session_state") + @Schema(example = "445807ee-2876-461d-a8f3-4d27b30c21fa") + private String sessionState; @NotNull - @Schema(example = "2020-08-04 11:12:00") - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone = "UTC") - private Instant expires; + @JsonProperty("scope") + @Schema(example = "profile email") + private String scope; - @NotBlank - @Schema(example = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c") - private String token; + @NotNull + @JsonProperty("refresh_expires_in") + @Schema(example = "1800") + private Long refreshExpiresIn; + + @NotNull + @JsonProperty("not-before-policy") + @Schema(example = "0") + private Long notBeforePolicy; } diff --git a/fda-metadata-db/entities/src/main/java/at/tuwien/entities/auth/Realm.java b/fda-metadata-db/entities/src/main/java/at/tuwien/entities/auth/Realm.java new file mode 100644 index 0000000000..fb7010325f --- /dev/null +++ b/fda-metadata-db/entities/src/main/java/at/tuwien/entities/auth/Realm.java @@ -0,0 +1,31 @@ +package at.tuwien.entities.auth; + +import lombok.*; + +import javax.persistence.*; + +@Data +@Entity +@Builder +@AllArgsConstructor +@NoArgsConstructor +@ToString +@EqualsAndHashCode(onlyExplicitlyIncluded = true) +@Table(name = "realm") +public class Realm { + + @Id + @EqualsAndHashCode.Include + @Column(nullable = false) + private String id; + + @Column(nullable = false) + private Boolean enabled; + + @Column(nullable = false) + private String name; + + @Column(nullable = false) + private String sslRequired; + +} diff --git a/fda-metadata-db/entities/src/main/java/at/tuwien/entities/user/User.java b/fda-metadata-db/entities/src/main/java/at/tuwien/entities/user/User.java index abd946bdb9..29f7222a71 100644 --- a/fda-metadata-db/entities/src/main/java/at/tuwien/entities/user/User.java +++ b/fda-metadata-db/entities/src/main/java/at/tuwien/entities/user/User.java @@ -36,7 +36,7 @@ public class User { @Column(name = "last_name") private String lastname; - @Column(name = "realm id") + @Column(name = "realm_id") private String realmId; @Column(unique = true, nullable = false) diff --git a/fda-query-service/pom.xml b/fda-query-service/pom.xml index 67fb838c96..35ec3a2928 100644 --- a/fda-query-service/pom.xml +++ b/fda-query-service/pom.xml @@ -297,9 +297,6 @@ <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-project-info-reports-plugin</artifactId> <version>3.0.0</version> -<!-- <configuration>--> -<!-- <outputDirectory>docs</outputDirectory>--> -<!-- </configuration>--> </plugin> <plugin> <groupId>com.soebes.maven.plugins</groupId> diff --git a/fda-user-service/Dockerfile b/fda-user-service/Dockerfile index dd9fe0250e..a772cacf6f 100644 --- a/fda-user-service/Dockerfile +++ b/fda-user-service/Dockerfile @@ -24,6 +24,9 @@ FROM openjdk:11-jre-slim as runtime ENV METADATA_DB=fda ENV METADATA_USERNAME=root ENV METADATA_PASSWORD=dbrepo +ENV GATEWAY_ENDPOINT=http://gateway-service:9095 +ENV KEYCLOAK_ADMIN=fda +ENV KEYCLOAK_ADMIN_PASSWORD=fda ENV LOG_LEVEL=debug ENV DBREPO_CLIENT_SECRET=client-secret ENV CLIENT_ID=dbrepo-client diff --git a/fda-user-service/pom.xml b/fda-user-service/pom.xml index f06580d159..989dafab4c 100644 --- a/fda-user-service/pom.xml +++ b/fda-user-service/pom.xml @@ -118,29 +118,6 @@ <groupId>org.springframework.data</groupId> <artifactId>spring-data-elasticsearch</artifactId> </dependency> - <!-- AMPQ --> - <dependency> - <groupId>com.rabbitmq</groupId> - <artifactId>amqp-client</artifactId> - <version>${rabbit-amqp-client.version}</version> - </dependency> - <!-- Docker --> - <dependency> - <groupId>com.github.docker-java</groupId> - <artifactId>docker-java</artifactId> - <version>${docker.version}</version> - <exclusions> - <exclusion> - <groupId>javax.ws.rs</groupId> - <artifactId>jsr311-api</artifactId> - </exclusion> - </exclusions> - </dependency> - <dependency> - <groupId>com.github.docker-java</groupId> - <artifactId>docker-java-transport-httpclient5</artifactId> - <version>${docker.version}</version> - </dependency> <!-- IDE --> <dependency> <groupId>org.projectlombok</groupId> @@ -237,9 +214,7 @@ <exclude>at/tuwien/handlers/**/*</exclude> <exclude>at/tuwien/exception/**/*</exclude> <exclude>at/tuwien/config/**/*</exclude> - <exclude>**/RabbitMqServiceImpl.class</exclude> - <exclude>**/ServiceSeeder.class</exclude> - <exclude>**/FdaQueryServiceApplication.class</exclude> + <exclude>**/FdaUserServiceApplication.class</exclude> </excludes> </configuration> <executions> @@ -267,9 +242,6 @@ <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-project-info-reports-plugin</artifactId> <version>3.0.0</version> -<!-- <configuration>--> -<!-- <outputDirectory>docs</outputDirectory>--> -<!-- </configuration>--> </plugin> <plugin> <groupId>com.soebes.maven.plugins</groupId> diff --git a/fda-user-service/rest-service/src/main/java/at/tuwien/endpoint/UserEndpoint.java b/fda-user-service/rest-service/src/main/java/at/tuwien/endpoint/UserEndpoint.java index 7bb8dc3149..20c4119928 100644 --- a/fda-user-service/rest-service/src/main/java/at/tuwien/endpoint/UserEndpoint.java +++ b/fda-user-service/rest-service/src/main/java/at/tuwien/endpoint/UserEndpoint.java @@ -2,6 +2,9 @@ package at.tuwien.endpoint; import at.tuwien.api.auth.SignupRequestDto; import at.tuwien.api.user.UserBriefDto; +import at.tuwien.exception.RealmNotFoundException; +import at.tuwien.exception.RemoteUnavailableException; +import at.tuwien.exception.UserNotFoundException; import at.tuwien.mapper.UserMapper; import at.tuwien.service.UserService; import io.micrometer.core.annotation.Timed; @@ -48,7 +51,8 @@ public class UserEndpoint { @Transactional @Timed(value = "user.create", description = "Time needed to create a user in the metadata database") @Operation(summary = "Create a user") - public ResponseEntity<UserBriefDto> create(SignupRequestDto data) { + public ResponseEntity<?> create(SignupRequestDto data) throws RealmNotFoundException, UserNotFoundException, + RemoteUnavailableException { log.debug("endpoint create a user, data={}", data); final UserBriefDto dto = userMapper.userToUserBriefDto(userService.create(data)); log.trace("create user resulted in dto {}", dto); diff --git a/fda-user-service/rest-service/src/main/resources/application-docker.yml b/fda-user-service/rest-service/src/main/resources/application-docker.yml index 084cc82986..486101dd8e 100644 --- a/fda-user-service/rest-service/src/main/resources/application-docker.yml +++ b/fda-user-service/rest-service/src/main/resources/application-docker.yml @@ -35,6 +35,11 @@ eureka: client.serviceUrl.defaultZone: http://discovery-service:9090/eureka/ fda: ready.path: /ready + gateway.endpoint: "${GATEWAY_ENDPOINT}" + keycloak: + endpoint: https://authentication-service:8443/ + username: "${KEYCLOAK_ADMIN}" + password: "${KEYCLOAK_ADMIN_PASSWORD}" jwt: issuer: "${JWT_ISSUER}" public_key: "${JWT_PUBKEY}" \ No newline at end of file diff --git a/fda-user-service/rest-service/src/main/resources/application-local.yml b/fda-user-service/rest-service/src/main/resources/application-local.yml index 4b86aa03a8..c6ac95610e 100644 --- a/fda-user-service/rest-service/src/main/resources/application-local.yml +++ b/fda-user-service/rest-service/src/main/resources/application-local.yml @@ -32,9 +32,14 @@ logging: org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver: debug eureka: instance.hostname: user-service - client.serviceUrl.defaultZone: http://discovery-service:9090/eureka/ + client.serviceUrl.defaultZone: http://localhost:9090/eureka/ fda: - ready.path: /ready + ready.path: ./ready + gateway.endpoint: http://localhost:9095 + keycloak: + endpoint: https://localhost:8443/ + username: fda + password: fda jwt: issuer: http://localhost:8080/realms/dbrepo public_key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqqnHQ2BWWW9vDNLRCcxD++xZg/16oqMo/c1l+lcFEjjAIJjJp/HqrPYU/U9GvquGE6PbVFtTzW1KcKawOW+FJNOA3CGo8Q1TFEfz43B8rZpKsFbJKvQGVv1Z4HaKPvLUm7iMm8Hv91cLduuoWx6Q3DPe2vg13GKKEZe7UFghF+0T9u8EKzA/XqQ0OiICmsmYPbwvf9N3bCKsB/Y10EYmZRb8IhCoV9mmO5TxgWgiuNeCTtNCv2ePYqL/U0WvyGFW0reasIK8eg3KrAUj8DpyOgPOVBn3lBGf+3KFSYi+0bwZbJZWqbC/Xlk20Go1YfeJPRIt7ImxD27R/lNjgDO/MwIDAQAB \ No newline at end of file diff --git a/fda-user-service/rest-service/src/main/resources/application.yml b/fda-user-service/rest-service/src/main/resources/application.yml index 9ba4e1547a..5f93e7a618 100644 --- a/fda-user-service/rest-service/src/main/resources/application.yml +++ b/fda-user-service/rest-service/src/main/resources/application.yml @@ -35,6 +35,11 @@ eureka: client.serviceUrl.defaultZone: http://discovery-service:9090/eureka/ fda: ready.path: /ready + gateway.endpoint: "${GATEWAY_ENDPOINT}" + keycloak: + endpoint: https://authentication-service:8443/ + username: "${KEYCLOAK_ADMIN}" + password: "${KEYCLOAK_ADMIN_PASSWORD}" jwt: issuer: "${JWT_ISSUER}" public_key: "${JWT_PUBKEY}" diff --git a/fda-user-service/rest-service/src/test/resources/application.properties b/fda-user-service/rest-service/src/test/resources/application.properties index 4eea490a91..ddba279a3b 100644 --- a/fda-user-service/rest-service/src/test/resources/application.properties +++ b/fda-user-service/rest-service/src/test/resources/application.properties @@ -21,11 +21,6 @@ spring.jpa.show-sql=false logging.level.root=error logging.level.at.tuwien.=trace -# broker service -spring.rabbitmq.host=dbrepo-broker-service -spring.rabbitmq.username=guest -spring.rabbitmq.password=guest - # search service fda.consumers=2 fda.gateway.endpoint: http://localhost:15672 diff --git a/fda-user-service/services/src/main/java/at/tuwien/config/GatewayConfig.java b/fda-user-service/services/src/main/java/at/tuwien/config/GatewayConfig.java new file mode 100644 index 0000000000..540b5d96f4 --- /dev/null +++ b/fda-user-service/services/src/main/java/at/tuwien/config/GatewayConfig.java @@ -0,0 +1,40 @@ +package at.tuwien.config; + +import lombok.Getter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.DefaultUriBuilderFactory; + +@Getter +@Configuration +public class GatewayConfig { + + @Value("${fda.gateway.endpoint}") + private String gatewayEndpoint; + + @Value("${fda.keycloak.endpoint}") + private String keycloakEndpoint; + + @Value("${fda.keycloak.username}") + private String keycloakUsername; + + @Value("${fda.keycloak.password}") + private String keycloakPassword; + + @Bean + public RestTemplate gatewayRestTemplate() { + final RestTemplate restTemplate = new RestTemplate(); + restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(gatewayEndpoint)); + return restTemplate; + } + + @Bean + public RestTemplate keycloakRestTemplate() { + final RestTemplate restTemplate = new RestTemplate(); + restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory(keycloakEndpoint)); + return restTemplate; + } + +} diff --git a/fda-user-service/services/src/main/java/at/tuwien/config/ReadyConfig.java b/fda-user-service/services/src/main/java/at/tuwien/config/ReadyConfig.java index 2250fa5088..388480c9be 100644 --- a/fda-user-service/services/src/main/java/at/tuwien/config/ReadyConfig.java +++ b/fda-user-service/services/src/main/java/at/tuwien/config/ReadyConfig.java @@ -1,7 +1,10 @@ package at.tuwien.config; +import at.tuwien.exception.RealmNotFoundException; +import at.tuwien.service.RealmService; import com.google.common.io.Files; import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.annotation.Configuration; @@ -17,8 +20,16 @@ public class ReadyConfig { @Value("${fda.ready.path}") private String readyPath; + private final RealmService realmService; + + @Autowired + public ReadyConfig(RealmService realmService) { + this.realmService = realmService; + } + @EventListener(ApplicationReadyEvent.class) - public void init() throws IOException { + public void init() throws IOException, RealmNotFoundException { + realmService.update("master"); Files.touch(new File(readyPath)); } diff --git a/fda-user-service/services/src/main/java/at/tuwien/exception/RealmNotFoundException.java b/fda-user-service/services/src/main/java/at/tuwien/exception/RealmNotFoundException.java new file mode 100644 index 0000000000..1750cfb525 --- /dev/null +++ b/fda-user-service/services/src/main/java/at/tuwien/exception/RealmNotFoundException.java @@ -0,0 +1,21 @@ +package at.tuwien.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(code = HttpStatus.NOT_FOUND) +public class RealmNotFoundException extends Exception { + + public RealmNotFoundException(String msg) { + super(msg); + } + + public RealmNotFoundException(String msg, Throwable thr) { + super(msg, thr); + } + + public RealmNotFoundException(Throwable thr) { + super(thr); + } + +} diff --git a/fda-user-service/services/src/main/java/at/tuwien/exception/RemoteUnavailableException.java b/fda-user-service/services/src/main/java/at/tuwien/exception/RemoteUnavailableException.java new file mode 100644 index 0000000000..3f6700d06b --- /dev/null +++ b/fda-user-service/services/src/main/java/at/tuwien/exception/RemoteUnavailableException.java @@ -0,0 +1,21 @@ +package at.tuwien.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(code = HttpStatus.NO_CONTENT) +public class RemoteUnavailableException extends Exception { + + public RemoteUnavailableException(String msg) { + super(msg); + } + + public RemoteUnavailableException(String msg, Throwable thr) { + super(msg, thr); + } + + public RemoteUnavailableException(Throwable thr) { + super(thr); + } + +} diff --git a/fda-user-service/services/src/main/java/at/tuwien/gateway/AuthenticationServiceGateway.java b/fda-user-service/services/src/main/java/at/tuwien/gateway/AuthenticationServiceGateway.java new file mode 100644 index 0000000000..3d41955d06 --- /dev/null +++ b/fda-user-service/services/src/main/java/at/tuwien/gateway/AuthenticationServiceGateway.java @@ -0,0 +1,11 @@ +package at.tuwien.gateway; + +import at.tuwien.api.auth.CreateUserDto; +import at.tuwien.api.auth.TokenDto; +import at.tuwien.exception.RemoteUnavailableException; + +public interface AuthenticationServiceGateway { + TokenDto getToken() throws RemoteUnavailableException; + + void createUser(String token, CreateUserDto data) throws RemoteUnavailableException; +} diff --git a/fda-user-service/services/src/main/java/at/tuwien/gateway/impl/AuthenticationServiceGatewayImpl.java b/fda-user-service/services/src/main/java/at/tuwien/gateway/impl/AuthenticationServiceGatewayImpl.java new file mode 100644 index 0000000000..19e2544e29 --- /dev/null +++ b/fda-user-service/services/src/main/java/at/tuwien/gateway/impl/AuthenticationServiceGatewayImpl.java @@ -0,0 +1,77 @@ +package at.tuwien.gateway.impl; + +import at.tuwien.api.auth.CreateUserDto; +import at.tuwien.api.auth.TokenDto; +import at.tuwien.config.GatewayConfig; +import at.tuwien.exception.RemoteUnavailableException; +import at.tuwien.gateway.AuthenticationServiceGateway; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.*; +import org.springframework.stereotype.Service; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.HttpServerErrorException; +import org.springframework.web.client.ResourceAccessException; +import org.springframework.web.client.RestTemplate; + +@Log4j2 +@Service +public class AuthenticationServiceGatewayImpl implements AuthenticationServiceGateway { + + private final RestTemplate restTemplate; + private final GatewayConfig gatewayConfig; + + @Autowired + public AuthenticationServiceGatewayImpl(@Qualifier("keycloakRestTemplate") RestTemplate restTemplate, + GatewayConfig gatewayConfig) { + this.restTemplate = restTemplate; + this.gatewayConfig = gatewayConfig; + } + + @Override + public TokenDto getToken() throws RemoteUnavailableException { + final HttpHeaders headers = new HttpHeaders(); + headers.add("Content-Type", MediaType.APPLICATION_FORM_URLENCODED.toString()); + final MultiValueMap<String, String> payload = new LinkedMultiValueMap<>(); + payload.add("username", gatewayConfig.getKeycloakUsername()); + payload.add("password", gatewayConfig.getKeycloakPassword()); + payload.add("grant_type", "password"); + payload.add("client_id", "admin-cli"); + final String url = "/realms/master/protocol/openid-connect/token"; + log.debug("call authentication service {}", url); + final ResponseEntity<TokenDto> response; + try { + response = restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(payload, headers), TokenDto.class); + } catch (ResourceAccessException | HttpServerErrorException.ServiceUnavailable e) { + log.error("Failed to obtain admin token: {}", e.getMessage()); + throw new RemoteUnavailableException("Failed to obtain admin token", e); + } + if (response.getStatusCode().equals(HttpStatus.UNAUTHORIZED)) { + log.error("Failed to obtain admin token: credentials are invalid"); + throw new RemoteUnavailableException("Failed to obtain admin token: credentials are invalid"); + } + return response.getBody(); + } + + @Override + public void createUser(String token, CreateUserDto data) throws RemoteUnavailableException { + final HttpHeaders headers = new HttpHeaders(); + headers.add("Content-Type", MediaType.APPLICATION_JSON.toString()); + headers.add("Accept", MediaType.APPLICATION_JSON.toString()); + headers.add("Authorization", "Bearer: " + token); + final ResponseEntity<Void> response; + try { + response = restTemplate.exchange("/admin/realms/dbrepo/users", HttpMethod.POST, new HttpEntity<>(data, headers), Void.class); + } catch (ResourceAccessException | HttpServerErrorException.ServiceUnavailable e) { + log.error("Failed to create user: {}", e.getMessage()); + throw new RemoteUnavailableException("Failed to create user", e); + } + if (response.getStatusCode().equals(HttpStatus.UNAUTHORIZED)) { + log.error("Failed to create user: credentials are invalid"); + throw new RemoteUnavailableException("Failed to create user: credentials are invalid"); + } + } + +} diff --git a/fda-user-service/services/src/main/java/at/tuwien/mapper/UserMapper.java b/fda-user-service/services/src/main/java/at/tuwien/mapper/UserMapper.java index cba134ae89..3a60fc1c3d 100644 --- a/fda-user-service/services/src/main/java/at/tuwien/mapper/UserMapper.java +++ b/fda-user-service/services/src/main/java/at/tuwien/mapper/UserMapper.java @@ -1,5 +1,6 @@ package at.tuwien.mapper; +import at.tuwien.api.auth.CreateUserDto; import at.tuwien.api.auth.SignupRequestDto; import at.tuwien.api.user.GrantedAuthorityDto; import at.tuwien.api.user.UserBriefDto; @@ -21,7 +22,7 @@ public interface UserMapper { UserBriefDto userToUserBriefDto(User data); - User signupRequestDtoToUser(SignupRequestDto data); + CreateUserDto signupRequestDtoToCreateUserDto(SignupRequestDto data); default GrantedAuthority grantedAuthorityDtoToGrantedAuthority(GrantedAuthorityDto data) { final GrantedAuthority authority = new SimpleGrantedAuthority(data.getAuthority()); diff --git a/fda-user-service/services/src/main/java/at/tuwien/repository/elastic/UserIdxRepository.java b/fda-user-service/services/src/main/java/at/tuwien/repository/elastic/UserIdxRepository.java new file mode 100644 index 0000000000..812cb439f6 --- /dev/null +++ b/fda-user-service/services/src/main/java/at/tuwien/repository/elastic/UserIdxRepository.java @@ -0,0 +1,10 @@ +package at.tuwien.repository.elastic; + +import at.tuwien.api.identifier.IdentifierDto; +import at.tuwien.api.user.UserDto; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface UserIdxRepository extends ElasticsearchRepository<UserDto, Long> { +} \ No newline at end of file diff --git a/fda-user-service/services/src/main/java/at/tuwien/repository/jpa/RealmRepository.java b/fda-user-service/services/src/main/java/at/tuwien/repository/jpa/RealmRepository.java new file mode 100644 index 0000000000..db0443c0a7 --- /dev/null +++ b/fda-user-service/services/src/main/java/at/tuwien/repository/jpa/RealmRepository.java @@ -0,0 +1,14 @@ +package at.tuwien.repository.jpa; + +import at.tuwien.entities.auth.Realm; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface RealmRepository extends JpaRepository<Realm, String> { + + Optional<Realm> findByName(String name); + +} diff --git a/fda-user-service/services/src/main/java/at/tuwien/service/RealmService.java b/fda-user-service/services/src/main/java/at/tuwien/service/RealmService.java new file mode 100644 index 0000000000..fc3f15f288 --- /dev/null +++ b/fda-user-service/services/src/main/java/at/tuwien/service/RealmService.java @@ -0,0 +1,10 @@ +package at.tuwien.service; + +import at.tuwien.entities.auth.Realm; +import at.tuwien.exception.RealmNotFoundException; + +public interface RealmService { + Realm find(String name) throws RealmNotFoundException; + + Realm update(String name) throws RealmNotFoundException; +} diff --git a/fda-user-service/services/src/main/java/at/tuwien/service/UserService.java b/fda-user-service/services/src/main/java/at/tuwien/service/UserService.java index d9371a4695..abf06036cb 100644 --- a/fda-user-service/services/src/main/java/at/tuwien/service/UserService.java +++ b/fda-user-service/services/src/main/java/at/tuwien/service/UserService.java @@ -3,6 +3,8 @@ package at.tuwien.service; import at.tuwien.api.auth.SignupRequestDto; import at.tuwien.entities.container.Container; import at.tuwien.entities.user.User; +import at.tuwien.exception.RealmNotFoundException; +import at.tuwien.exception.RemoteUnavailableException; import at.tuwien.exception.UserNotFoundException; import java.security.Principal; @@ -26,7 +28,7 @@ public interface UserService { */ User findByUsername(String username) throws UserNotFoundException; - User create(SignupRequestDto data); + User create(SignupRequestDto data) throws RealmNotFoundException, RemoteUnavailableException, UserNotFoundException; /** * Finds a user by id. diff --git a/fda-user-service/services/src/main/java/at/tuwien/service/impl/RealmServiceImpl.java b/fda-user-service/services/src/main/java/at/tuwien/service/impl/RealmServiceImpl.java new file mode 100644 index 0000000000..249876f68d --- /dev/null +++ b/fda-user-service/services/src/main/java/at/tuwien/service/impl/RealmServiceImpl.java @@ -0,0 +1,43 @@ +package at.tuwien.service.impl; + +import at.tuwien.entities.auth.Realm; +import at.tuwien.exception.RealmNotFoundException; +import at.tuwien.repository.jpa.RealmRepository; +import at.tuwien.service.RealmService; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Log4j2 +@Service +public class RealmServiceImpl implements RealmService { + + final RealmRepository realmRepository; + + @Autowired + public RealmServiceImpl(RealmRepository realmRepository) { + this.realmRepository = realmRepository; + } + + @Override + public Realm find(String name) throws RealmNotFoundException { + final Optional<Realm> optional = realmRepository.findByName(name); + if (optional.isEmpty()) { + log.error("Failed to find realm with name '{}'", name); + throw new RealmNotFoundException("Failed to find realm"); + } + return optional.get(); + } + + @Override + public Realm update(String name) throws RealmNotFoundException { + final Realm realm = find("master"); + realm.setSslRequired("NONE"); + final Realm entity = realmRepository.save(realm); + log.info("Disabled SSL for realm with name '{}'", name); + return entity; + } + +} diff --git a/fda-user-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java b/fda-user-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java index 5578d9186b..50bbea2634 100644 --- a/fda-user-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java +++ b/fda-user-service/services/src/main/java/at/tuwien/service/impl/UserServiceImpl.java @@ -1,8 +1,13 @@ package at.tuwien.service.impl; +import at.tuwien.api.auth.CreateUserDto; import at.tuwien.api.auth.SignupRequestDto; +import at.tuwien.api.auth.TokenDto; import at.tuwien.entities.user.User; +import at.tuwien.exception.RealmNotFoundException; +import at.tuwien.exception.RemoteUnavailableException; import at.tuwien.exception.UserNotFoundException; +import at.tuwien.gateway.AuthenticationServiceGateway; import at.tuwien.mapper.UserMapper; import at.tuwien.repository.jpa.UserRepository; import at.tuwien.service.UserService; @@ -12,7 +17,6 @@ import org.springframework.stereotype.Service; import java.util.List; import java.util.Optional; -import java.util.UUID; @Log4j2 @Service @@ -20,11 +24,14 @@ public class UserServiceImpl implements UserService { private final UserMapper userMapper; private final UserRepository userRepository; + private final AuthenticationServiceGateway authenticationServiceGateway; @Autowired - public UserServiceImpl(UserMapper userMapper, UserRepository userRepository) { + public UserServiceImpl(UserMapper userMapper, UserRepository userRepository, + AuthenticationServiceGateway authenticationServiceGateway) { this.userMapper = userMapper; this.userRepository = userRepository; + this.authenticationServiceGateway = authenticationServiceGateway; } @Override @@ -43,14 +50,20 @@ public class UserServiceImpl implements UserService { } @Override - public User create(SignupRequestDto data) { - final User user = userMapper.signupRequestDtoToUser(data); - user.setRealmId("82c39861-d877-4667-a0f3-4daa2ee230e0"); - user.setEmailVerified(false); - user.setId(UUID.randomUUID().toString()); - final User entity = userRepository.save(user); - log.info("Created user with id {}", entity.getId()); - return entity; + public User create(SignupRequestDto data) throws RealmNotFoundException, RemoteUnavailableException, + UserNotFoundException { + final TokenDto dto = authenticationServiceGateway.getToken(); + log.debug("obtained authentication token"); + final CreateUserDto userDto = userMapper.signupRequestDtoToCreateUserDto(data); + authenticationServiceGateway.createUser(dto.getAccessToken(), userDto); + final Optional<User> optional = userRepository.findByUsername(data.getUsername()); + if (optional.isEmpty()) { + /* should never occur */ + throw new UserNotFoundException("User not found with username '" + data.getUsername() + "'"); + } + final User user = optional.get(); + log.info("Created user with id {}", user.getId()); + return user; } @Override diff --git a/server.keystore b/server.keystore new file mode 100644 index 0000000000000000000000000000000000000000..93e5c28b23293910dac23a3e974cb485524a3a17 GIT binary patch literal 2220 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 C1<soQ literal 0 HcmV?d00001 -- GitLab