diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/UserBootstrap.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/UserBootstrap.groovy index 19b27dd1c..33d93564c 100644 --- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/UserBootstrap.groovy +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/UserBootstrap.groovy @@ -29,6 +29,13 @@ class UserBootstrap { @Transactional @EventListener void bootstrapUsersAndRoles(ApplicationStartedEvent e) { + if (shibUIConfiguration.roles) { + log.info("bootstrapping roles") + shibUIConfiguration.roles.each { it -> + def role = roleRepository.findByName(it).orElse(new Role(name: it)) + roleRepository.saveAndFlush(role) + } + } if (shibUIConfiguration.userBootstrapResource) { log.info("configuring users from ${shibUIConfiguration.userBootstrapResource.URI}") new CSVReader(new InputStreamReader(shibUIConfiguration.userBootstrapResource.inputStream)).each { it -> diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/ShibUIConfiguration.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/ShibUIConfiguration.java index 3c85674e9..fc20a0265 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/ShibUIConfiguration.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/ShibUIConfiguration.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Optional; +import java.util.Set; @Configuration @ConfigurationProperties(prefix = "shibui") @@ -24,7 +25,7 @@ public class ShibUIConfiguration { * A Resource containing a CSV of users to bootstrap into the system. Currently, this must be in format * * - * username,password,firstName,lastName,role + * username,password,firstName,lastName,role,email * * * Note that the password must be encrypted in the file. Ensure that you prepend the encoder to the value, e.g. @@ -34,4 +35,9 @@ public class ShibUIConfiguration { * */ private Resource userBootstrapResource; + + /** + * A list of roles to bootstrap into the system. + */ + private Set roles; } diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/UserBootstrapTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/UserBootstrapTests.groovy index 74f6df359..29975ca76 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/UserBootstrapTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/UserBootstrapTests.groovy @@ -44,4 +44,19 @@ class UserBootstrapTests extends Specification { assert userRepository.findAll().size() == 2 assert roleRepository.findAll().size() == 2 } + + def "bootstrap roles"() { + setup: + shibUIConfiguration.roles = ['ROLE_ADMIN', 'ROLE_USER'] + def userbootstrap = new UserBootstrap(shibUIConfiguration, userRepository, roleRepository) + + when: + userbootstrap.bootstrapUsersAndRoles(null) + + then: + noExceptionThrown() + assert roleRepository.findAll().size() == 2 + assert roleRepository.findByName('ROLE_ADMIN').get() + assert roleRepository.findByName('ROLE_USER').get() + } } diff --git a/pac4j-module/src/test/docker/conf/application.yml b/pac4j-module/src/test/docker/conf/application.yml index e24389d17..54c9c0a6b 100644 --- a/pac4j-module/src/test/docker/conf/application.yml +++ b/pac4j-module/src/test/docker/conf/application.yml @@ -1,6 +1,6 @@ spring: profiles: - include: dev + include: server: port: 8443 ssl: @@ -9,6 +9,8 @@ server: keyStoreType: "PKCS12" keyAlias: "tomcat" shibui: + user-bootstrap-resource: file:/conf/users.csv + roles: ROLE_ADMIN,ROLE_NONE,ROLE_USER,ROLE_PONY pac4j: keystorePath: "/conf/samlKeystore.jks" keystorePassword: "changeit" @@ -19,6 +21,11 @@ shibui: forceServiceProviderMetadataGeneration: true callbackUrl: "https://localhost:8443/callback" maximumAuthenticationLifetime: 3600000 + saml2ProfileMapping: + username: urn:oid:0.9.2342.19200300.100.1.1 + firstName: urn:oid:2.5.4.42 + lastName: urn:oid:2.5.4.4 + email: urn:oid:0.9.2342.19200300.100.1.3 logging: level: org.pac4j: "TRACE" diff --git a/pac4j-module/src/test/docker/conf/idp-metadata.xml b/pac4j-module/src/test/docker/conf/idp-metadata.xml index 0c0924b54..6cb8c8117 100644 --- a/pac4j-module/src/test/docker/conf/idp-metadata.xml +++ b/pac4j-module/src/test/docker/conf/idp-metadata.xml @@ -1,82 +1,213 @@ - + - + - unicon.net - - Unicon, Inc. - Login service for Unicon Employees - https://idp.unicon.net/logo_135_0.png - + mpt.unicon.net + - MIIDIzCCAgugAwIBAgIUIEHTfbStY0ckKZzxIgqd5p1O2K0wDQYJKoZIhvcNAQEF - BQAwGTEXMBUGA1UEAxMOaWRwLnVuaWNvbi5uZXQwHhcNMTEwOTEzMDMyMzE2WhcN - MzEwOTEzMDMyMzE2WjAZMRcwFQYDVQQDEw5pZHAudW5pY29uLm5ldDCCASIwDQYJ - KoZIhvcNAQEBBQADggEPADCCAQoCggEBANtUsFXxlhvD3bWT5Y7TqKkf5rxa+dPA - z7vpbJ6bWhDPSMXb/9MiJe/ciY5ZKKrB1rdRC04s7blrzem3YtjGihfGd4ld+NRt - Pi0xoAT2YIp83CvEe5BHAKwqD7KTonN1unbN84mVo65itbme9d8lZKc0PfLM+BQp - fhXKUBfYeBCkYU4YWxmgL4Vs7XBaKjEjpTN4ncar4YSrarWTTPyO5RzmVPLAcv88 - 1OBqewTyN41+JRXt0Jopi4ZQ8JjKkm73vhoYDBPHr/VMqk1lFfrDcDwJa2ygyWCm - qTlq6zyLE9Fr6sYz6CbgA2lAqu/b1rYCqVCnRpoHZKahAQ9uGQSfHD8CAwEAAaNj - MGEwQAYDVR0RBDkwN4IOaWRwLnVuaWNvbi5uZXSGJWh0dHBzOi8vaWRwLnVuaWNv - bi5uZXQvaWRwL3NoaWJib2xldGgwHQYDVR0OBBYEFK6yUrpGjvY3B09ke0kVl4wA - CMAnMA0GCSqGSIb3DQEBBQUAA4IBAQDG/gMpr3N+nAMuo7RhtDBsckiJV2+BwT/r - JmpxlHAV1Zgc3eeuOdyxm5/jA78tspLldL0+6W/LzZWov/je36IqVT1wSGy1n0Sc - Pjw8DHgyEJLCij2vVScV+j/Y4Eg0bVy6pZTeQW+e3ygb6WgiVT/ARM8QBp6GjAUC - qIlJCads9Rcx3vAih72I4exUUD4qMuBMeLIdY5XReHy5YHqxbkPjQhDIEORAFlzJ - jLqO/Ldzn4waEa5snDZyeYjsl6pi+8CVGfXLSDVsDuk5s47B9OD+gOSJ1wEc7O/N - nU9d/WCcM1V4IGZGL8TXUdfJoVXYZUFF08jUGSL2mj30WS1orIWo - + MIIDUDCCAjigAwIBAgIVANJjXOfRMLZl0ggUKcix1vGeULobMA0GCSqGSIb3DQEB + CwUAMCQxIjAgBgNVBAMMGXNoaWJib2xldGgubXB0LnVuaWNvbi5uZXQwHhcNMTgw + ODEwMjIzNzQ1WhcNMzgwODEwMjIzNzQ1WjAkMSIwIAYDVQQDDBlzaGliYm9sZXRo + Lm1wdC51bmljb24ubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA + nxzksqMYjCHqRWuSw2sAv6XeC7qfGCnuHzP8NhfQbSuNpeifASOV8+5iOaOoVTUD + iTyAudXklgP6Ul6wmw7iku1TNl5Q/gt5+iFUvMS8ZHo8PuNTCCYhfxUtkRpL3CAt + qghzE9Zsd1hKb/yw640oM986Mg7Icx6Xy9L83Tm2mhgTBwHtNUqN4ShI4zFmYPbH + 7jjHWlExNhzkkv1IudrLMcxSYj2zgxG7DxE3t2JEUIAWxTGAkEIDVdZaKvlkVVkp + t3sZjpfBLPhqprDdcbiszhg2YrITtO52i92ynAH1irYnNVjRKvHZ+sGTtg2uenpj + Qu/cohBkKGE3nC7CVCQqKwIDAQABo3kwdzAdBgNVHQ4EFgQUsedlUmbDiHP3qKvD + gn2gMdzoAuYwVgYDVR0RBE8wTYIZc2hpYmJvbGV0aC5tcHQudW5pY29uLm5ldIYw + aHR0cHM6Ly9zaGliYm9sZXRoLm1wdC51bmljb24ubmV0L2lkcC9zaGliYm9sZXRo + MA0GCSqGSIb3DQEBCwUAA4IBAQAmifiYwbGlWvxYUdqdkwfyulGzsF/AFamI7aU+ + 0a+vCNokKMA2qED3TagRgbyijFrviES0IMr48upcXIba+LsGsLdJBRoKTi0cBVtN + pkfSMDDIZWrKRE785aYw5SvtOT+O83pJNBvayqPA9p0AHkIdoIZ5Va8f4aRMGLFh + J3yrN2kFpfsmdwaVobeTLxyJCe4gh29CqqJLJfBWK+cTqWqq17gP5v9/hX5E33v4 + TxQ0Kyhk110fZre9wE0lxGF9JpIICK4Hw7OcQo+pqus0SFdIpF+yxwbscajWZ7lc + PDZlbYpSYHHfEl3rYtdpP/LJdGe5O9sckIeAtpi/nYw9WjFF + + + + + + MIIDTzCCAjegAwIBAgIUUwMnlrU9wjjhEPjnqTSeKUAVNzIwDQYJKoZIhvcNAQEL + BQAwJDEiMCAGA1UEAwwZc2hpYmJvbGV0aC5tcHQudW5pY29uLm5ldDAeFw0xODA4 + MTAyMjM3NDVaFw0zODA4MTAyMjM3NDVaMCQxIjAgBgNVBAMMGXNoaWJib2xldGgu + bXB0LnVuaWNvbi5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7 + MqrBJfI28Z69eIDRttdOJKaCP456uavRcukQixBMlosIfo9Bs6h2RAShCL+qpr7u + kU4Io2t+pRcf0PUZA+cjX5GY5Mvq0qedi1smcFP/G88QbY1g8w4WUy9nxu2F+e1T + vRnoiclhLcqMA3ALi6j8hRbCYJc0fLtLmdIxoBkYlg9ocnffKff1pYfAGuKxjtus + XkoFU72t3fxuWpmWmeh1tMlevmifqs3oDWJ0WUXZnuiTnm1OrveVqigvlZI9Q2ui + aXc/atJwNlYyQ5aRyZrONh+CO0u+P2d+fIeyHoYAS9m7jlmElHwhGC5LdAyoTzPM + yIGq2iBYRKFz7uU7YjY5AgMBAAGjeTB3MB0GA1UdDgQWBBTlpwwcXISXwYddmFNE + m+hOlP9RGTBWBgNVHREETzBNghlzaGliYm9sZXRoLm1wdC51bmljb24ubmV0hjBo + dHRwczovL3NoaWJib2xldGgubXB0LnVuaWNvbi5uZXQvaWRwL3NoaWJib2xldGgw + DQYJKoZIhvcNAQELBQADggEBAGIUoJCJpuVYycLCLQKMTyK64EeC5ENIBiSiD8HG + iDc/8jUNhcJs2L1zTSMGLINgZp6VmA5wq89caAQvnCHZ32QQRwgcSYPdcuH9NW08 + 9c6XNLUzUDFdTMmYB5xXP0cdJALADkKAtkU+KyI50s33EZbhnOLVkEI06MEDApGH + RyGtUfk7mVPPKCd8F5gapotattC3S8NPZR3+obuwvFgVx8rqP3+D+C+MsF1kNyN9 + cQDAOQ89Dy632CGgouEtYaNYEaqFT9NOlDrqMp3BjPwD+qTvRDoVQ6c3m+wadrqE + Obuqe3/bQswltJMtQI1g0Maf58z5xe70oDnN267chrCfu58= + + + + - MIIDIzCCAgugAwIBAgIUIEHTfbStY0ckKZzxIgqd5p1O2K0wDQYJKoZIhvcNAQEF - BQAwGTEXMBUGA1UEAxMOaWRwLnVuaWNvbi5uZXQwHhcNMTEwOTEzMDMyMzE2WhcN - MzEwOTEzMDMyMzE2WjAZMRcwFQYDVQQDEw5pZHAudW5pY29uLm5ldDCCASIwDQYJ - KoZIhvcNAQEBBQADggEPADCCAQoCggEBANtUsFXxlhvD3bWT5Y7TqKkf5rxa+dPA - z7vpbJ6bWhDPSMXb/9MiJe/ciY5ZKKrB1rdRC04s7blrzem3YtjGihfGd4ld+NRt - Pi0xoAT2YIp83CvEe5BHAKwqD7KTonN1unbN84mVo65itbme9d8lZKc0PfLM+BQp - fhXKUBfYeBCkYU4YWxmgL4Vs7XBaKjEjpTN4ncar4YSrarWTTPyO5RzmVPLAcv88 - 1OBqewTyN41+JRXt0Jopi4ZQ8JjKkm73vhoYDBPHr/VMqk1lFfrDcDwJa2ygyWCm - qTlq6zyLE9Fr6sYz6CbgA2lAqu/b1rYCqVCnRpoHZKahAQ9uGQSfHD8CAwEAAaNj - MGEwQAYDVR0RBDkwN4IOaWRwLnVuaWNvbi5uZXSGJWh0dHBzOi8vaWRwLnVuaWNv - bi5uZXQvaWRwL3NoaWJib2xldGgwHQYDVR0OBBYEFK6yUrpGjvY3B09ke0kVl4wA - CMAnMA0GCSqGSIb3DQEBBQUAA4IBAQDG/gMpr3N+nAMuo7RhtDBsckiJV2+BwT/r - JmpxlHAV1Zgc3eeuOdyxm5/jA78tspLldL0+6W/LzZWov/je36IqVT1wSGy1n0Sc - Pjw8DHgyEJLCij2vVScV+j/Y4Eg0bVy6pZTeQW+e3ygb6WgiVT/ARM8QBp6GjAUC - qIlJCads9Rcx3vAih72I4exUUD4qMuBMeLIdY5XReHy5YHqxbkPjQhDIEORAFlzJ - jLqO/Ldzn4waEa5snDZyeYjsl6pi+8CVGfXLSDVsDuk5s47B9OD+gOSJ1wEc7O/N - nU9d/WCcM1V4IGZGL8TXUdfJoVXYZUFF08jUGSL2mj30WS1orIWo - + MIIDUDCCAjigAwIBAgIVAPJ+hmxRUcPUO6AGY+btaYhgkJqGMA0GCSqGSIb3DQEB + CwUAMCQxIjAgBgNVBAMMGXNoaWJib2xldGgubXB0LnVuaWNvbi5uZXQwHhcNMTgw + ODEwMjIzNzQ1WhcNMzgwODEwMjIzNzQ1WjAkMSIwIAYDVQQDDBlzaGliYm9sZXRo + Lm1wdC51bmljb24ubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA + vRTRYpsnxOjjAXDtlimV8vHveDtC+RAABm7CVzcGzYCKRIuP2fhMA5cImQJ4hNAd + PGjDOgopMbRO2KZ285Hyux2J7MJp7mBjALt5nb0ASBn9w0vG2xkDn3SM0sFtiXxE + dGWhNa3rGSd4UFmPPnauaAT7uXLuwmf48kXQrB2FSaJrg7dodLmElhBriwewMszk + iJ1agkVvKRIiQh0pMsyRN+T4331t95mWW7Mze6WqWilCCEQCHQaTn51oFgvP0SDk + fQ/cMufHHoBYnCMOhrIWNFJ0SKXVHJ6rDTrgB3LRB45JAgq4RMiYzqFrvkdZQ8w5 + JJUeS/vPrCrXCCcNw8BgoQIDAQABo3kwdzAdBgNVHQ4EFgQUqKX2WwgXnEG/nJrP + Q+VNvBTmxOswVgYDVR0RBE8wTYIZc2hpYmJvbGV0aC5tcHQudW5pY29uLm5ldIYw + aHR0cHM6Ly9zaGliYm9sZXRoLm1wdC51bmljb24ubmV0L2lkcC9zaGliYm9sZXRo + MA0GCSqGSIb3DQEBCwUAA4IBAQCwzD80lVm6BV0QSOJayrI0CEQSPUUs+y2teOPv + vfGF4Yf3lYd29WdkdcP3ThgWEnX+RW1R4bAh5IEdpmsFBOkZFEamda4Y3t9YbwBs + Jh4bI+LAXmwCHhmBCmF60n78j7kaBWqsic2LJS1j7S0TvsttiW1Ku1rr3c76zncU + eRwuUnFlUDWdSzRJVQXz102MNAuEU1aSZDpmyDYR/ohCTMtsFxfhH6iBQ5GkmSwb + CTqpAtFWs5I4X2Af/CPoYQvqjlmCNjUrRuaDmzlVv7BBCBsYal02rK3bD0hnk5MY + /lEfUgFasEoUz7RqLvMt3rx/esZ9JA2j7YY2jcpt8+B6sXoA + + + + + - urn:mace:shibboleth:1.0:nameIdentifier - urn:oasis:names:tc:SAML:2.0:nameid-format:transient - - - - + + + + + - + + + + + mpt.unicon.net + + + + + + + MIIDUDCCAjigAwIBAgIVANJjXOfRMLZl0ggUKcix1vGeULobMA0GCSqGSIb3DQEB + CwUAMCQxIjAgBgNVBAMMGXNoaWJib2xldGgubXB0LnVuaWNvbi5uZXQwHhcNMTgw + ODEwMjIzNzQ1WhcNMzgwODEwMjIzNzQ1WjAkMSIwIAYDVQQDDBlzaGliYm9sZXRo + Lm1wdC51bmljb24ubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA + nxzksqMYjCHqRWuSw2sAv6XeC7qfGCnuHzP8NhfQbSuNpeifASOV8+5iOaOoVTUD + iTyAudXklgP6Ul6wmw7iku1TNl5Q/gt5+iFUvMS8ZHo8PuNTCCYhfxUtkRpL3CAt + qghzE9Zsd1hKb/yw640oM986Mg7Icx6Xy9L83Tm2mhgTBwHtNUqN4ShI4zFmYPbH + 7jjHWlExNhzkkv1IudrLMcxSYj2zgxG7DxE3t2JEUIAWxTGAkEIDVdZaKvlkVVkp + t3sZjpfBLPhqprDdcbiszhg2YrITtO52i92ynAH1irYnNVjRKvHZ+sGTtg2uenpj + Qu/cohBkKGE3nC7CVCQqKwIDAQABo3kwdzAdBgNVHQ4EFgQUsedlUmbDiHP3qKvD + gn2gMdzoAuYwVgYDVR0RBE8wTYIZc2hpYmJvbGV0aC5tcHQudW5pY29uLm5ldIYw + aHR0cHM6Ly9zaGliYm9sZXRoLm1wdC51bmljb24ubmV0L2lkcC9zaGliYm9sZXRo + MA0GCSqGSIb3DQEBCwUAA4IBAQAmifiYwbGlWvxYUdqdkwfyulGzsF/AFamI7aU+ + 0a+vCNokKMA2qED3TagRgbyijFrviES0IMr48upcXIba+LsGsLdJBRoKTi0cBVtN + pkfSMDDIZWrKRE785aYw5SvtOT+O83pJNBvayqPA9p0AHkIdoIZ5Va8f4aRMGLFh + J3yrN2kFpfsmdwaVobeTLxyJCe4gh29CqqJLJfBWK+cTqWqq17gP5v9/hX5E33v4 + TxQ0Kyhk110fZre9wE0lxGF9JpIICK4Hw7OcQo+pqus0SFdIpF+yxwbscajWZ7lc + PDZlbYpSYHHfEl3rYtdpP/LJdGe5O9sckIeAtpi/nYw9WjFF + + + + + + + + + + MIIDTzCCAjegAwIBAgIUUwMnlrU9wjjhEPjnqTSeKUAVNzIwDQYJKoZIhvcNAQEL + BQAwJDEiMCAGA1UEAwwZc2hpYmJvbGV0aC5tcHQudW5pY29uLm5ldDAeFw0xODA4 + MTAyMjM3NDVaFw0zODA4MTAyMjM3NDVaMCQxIjAgBgNVBAMMGXNoaWJib2xldGgu + bXB0LnVuaWNvbi5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7 + MqrBJfI28Z69eIDRttdOJKaCP456uavRcukQixBMlosIfo9Bs6h2RAShCL+qpr7u + kU4Io2t+pRcf0PUZA+cjX5GY5Mvq0qedi1smcFP/G88QbY1g8w4WUy9nxu2F+e1T + vRnoiclhLcqMA3ALi6j8hRbCYJc0fLtLmdIxoBkYlg9ocnffKff1pYfAGuKxjtus + XkoFU72t3fxuWpmWmeh1tMlevmifqs3oDWJ0WUXZnuiTnm1OrveVqigvlZI9Q2ui + aXc/atJwNlYyQ5aRyZrONh+CO0u+P2d+fIeyHoYAS9m7jlmElHwhGC5LdAyoTzPM + yIGq2iBYRKFz7uU7YjY5AgMBAAGjeTB3MB0GA1UdDgQWBBTlpwwcXISXwYddmFNE + m+hOlP9RGTBWBgNVHREETzBNghlzaGliYm9sZXRoLm1wdC51bmljb24ubmV0hjBo + dHRwczovL3NoaWJib2xldGgubXB0LnVuaWNvbi5uZXQvaWRwL3NoaWJib2xldGgw + DQYJKoZIhvcNAQELBQADggEBAGIUoJCJpuVYycLCLQKMTyK64EeC5ENIBiSiD8HG + iDc/8jUNhcJs2L1zTSMGLINgZp6VmA5wq89caAQvnCHZ32QQRwgcSYPdcuH9NW08 + 9c6XNLUzUDFdTMmYB5xXP0cdJALADkKAtkU+KyI50s33EZbhnOLVkEI06MEDApGH + RyGtUfk7mVPPKCd8F5gapotattC3S8NPZR3+obuwvFgVx8rqP3+D+C+MsF1kNyN9 + cQDAOQ89Dy632CGgouEtYaNYEaqFT9NOlDrqMp3BjPwD+qTvRDoVQ6c3m+wadrqE + Obuqe3/bQswltJMtQI1g0Maf58z5xe70oDnN267chrCfu58= + + + + + + + + + + MIIDUDCCAjigAwIBAgIVAPJ+hmxRUcPUO6AGY+btaYhgkJqGMA0GCSqGSIb3DQEB + CwUAMCQxIjAgBgNVBAMMGXNoaWJib2xldGgubXB0LnVuaWNvbi5uZXQwHhcNMTgw + ODEwMjIzNzQ1WhcNMzgwODEwMjIzNzQ1WjAkMSIwIAYDVQQDDBlzaGliYm9sZXRo + Lm1wdC51bmljb24ubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA + vRTRYpsnxOjjAXDtlimV8vHveDtC+RAABm7CVzcGzYCKRIuP2fhMA5cImQJ4hNAd + PGjDOgopMbRO2KZ285Hyux2J7MJp7mBjALt5nb0ASBn9w0vG2xkDn3SM0sFtiXxE + dGWhNa3rGSd4UFmPPnauaAT7uXLuwmf48kXQrB2FSaJrg7dodLmElhBriwewMszk + iJ1agkVvKRIiQh0pMsyRN+T4331t95mWW7Mze6WqWilCCEQCHQaTn51oFgvP0SDk + fQ/cMufHHoBYnCMOhrIWNFJ0SKXVHJ6rDTrgB3LRB45JAgq4RMiYzqFrvkdZQ8w5 + JJUeS/vPrCrXCCcNw8BgoQIDAQABo3kwdzAdBgNVHQ4EFgQUqKX2WwgXnEG/nJrP + Q+VNvBTmxOswVgYDVR0RBE8wTYIZc2hpYmJvbGV0aC5tcHQudW5pY29uLm5ldIYw + aHR0cHM6Ly9zaGliYm9sZXRoLm1wdC51bmljb24ubmV0L2lkcC9zaGliYm9sZXRo + MA0GCSqGSIb3DQEBCwUAA4IBAQCwzD80lVm6BV0QSOJayrI0CEQSPUUs+y2teOPv + vfGF4Yf3lYd29WdkdcP3ThgWEnX+RW1R4bAh5IEdpmsFBOkZFEamda4Y3t9YbwBs + Jh4bI+LAXmwCHhmBCmF60n78j7kaBWqsic2LJS1j7S0TvsttiW1Ku1rr3c76zncU + eRwuUnFlUDWdSzRJVQXz102MNAuEU1aSZDpmyDYR/ohCTMtsFxfhH6iBQ5GkmSwb + CTqpAtFWs5I4X2Af/CPoYQvqjlmCNjUrRuaDmzlVv7BBCBsYal02rK3bD0hnk5MY + /lEfUgFasEoUz7RqLvMt3rx/esZ9JA2j7YY2jcpt8+B6sXoA + + + + + + + + + + + + + \ No newline at end of file