From 6080932292652d7a183dbbe37cca231f121d7817 Mon Sep 17 00:00:00 2001 From: Jj! Date: Tue, 3 Dec 2019 14:12:17 -0600 Subject: [PATCH 01/10] [NOTASK] postgres test --- .../admin/ui/security/model/User.java | 2 + testbed/postgres/conf/application.yml | 138 ++++++++++++++++++ testbed/postgres/conf/keystore.p12 | Bin 0 -> 2591 bytes testbed/postgres/conf/users.csv | 2 + testbed/postgres/docker-compose.yml | 39 +++++ 5 files changed, 181 insertions(+) create mode 100644 testbed/postgres/conf/application.yml create mode 100644 testbed/postgres/conf/keystore.p12 create mode 100644 testbed/postgres/conf/users.csv create mode 100644 testbed/postgres/docker-compose.yml diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/User.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/User.java index 1a36ffdcc..c30c4ceff 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/User.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/User.java @@ -16,6 +16,7 @@ import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; +import javax.persistence.Table; import javax.persistence.Transient; import java.util.HashSet; import java.util.Set; @@ -31,6 +32,7 @@ @Setter @EqualsAndHashCode(callSuper = true, exclude = "roles") @ToString(exclude = "roles") +@Table(name = "USERS") public class User extends AbstractAuditable { @Column(nullable = false, unique = true) diff --git a/testbed/postgres/conf/application.yml b/testbed/postgres/conf/application.yml new file mode 100644 index 000000000..2173107e1 --- /dev/null +++ b/testbed/postgres/conf/application.yml @@ -0,0 +1,138 @@ +spring: + profiles: + include: + datasource: + platform: postgres + driver-class-name: org.postgresql.Driver + url: jdbc:postgresql://db:5432/shibui + username: shibui + password: shibui + jpa: + properties: + hibernate: + dialect: org.hibernate.dialect.PostgreSQLDialect +server: + port: 8443 + ssl: + key-store: "/conf/keystore.p12" + key-store-password: "changeit" + keyStoreType: "PKCS12" + keyAlias: "tomcat" +shibui: + user-bootstrap-resource: file:/conf/users.csv + roles: ROLE_ADMIN,ROLE_NONE,ROLE_USER,ROLE_PONY +custom: + attributes: + # Default attributes + - name: eduPersonPrincipalName + displayName: label.attribute-eduPersonPrincipalName + - name: uid + displayName: label.attribute-uid + - name: mail + displayName: label.attribute-mail + - name: surname + displayName: label.attribute-surname + - name: givenName + displayName: label.attribute-givenName + - name: eduPersonAffiliation + displayName: label.attribute-eduPersonAffiliation + - name: eduPersonScopedAffiliation + displayName: label.attribute-eduPersonScopedAffiliation + - name: eduPersonPrimaryAffiliation + displayName: label.attribute-eduPersonPrimaryAffiliation + - name: eduPersonEntitlement + displayName: label.attribute-eduPersonEntitlement + - name: eduPersonAssurance + displayName: label.attribute-eduPersonAssurance + - name: eduPersonUniqueId + displayName: label.attribute-eduPersonUniqueId + - name: employeeNumber + displayName: label.attribute-employeeNumber + # Custom attributes + overrides: + # Default overrides + - name: signAssertion + displayName: label.sign-the-assertion + displayType: boolean + defaultValue: false + helpText: tooltip.sign-assertion + attributeName: http://shibboleth.net/ns/profiles/saml2/sso/browser/signAssertions + attributeFriendlyName: signAssertions + - name: dontSignResponse + displayName: label.dont-sign-the-response + displayType: boolean + defaultValue: false + helpText: tooltip.dont-sign-response + attributeName: http://shibboleth.net/ns/profiles/saml2/sso/browser/signResponses + attributeFriendlyName: signResponses + - name: turnOffEncryption + displayName: label.turn-off-encryption-of-response + displayType: boolean + defaultValue: false + helpText: tooltip.turn-off-encryption + attributeName: http://shibboleth.net/ns/profiles/encryptAssertions + attributeFriendlyName: encryptAssertions + - name: useSha + displayName: label.use-sha1-signing-algorithm + displayType: boolean + defaultValue: false + helpText: tooltip.usa-sha-algorithm + persistType: string + persistValue: shibboleth.SecurityConfiguration.SHA1 + attributeName: http://shibboleth.net/ns/profiles/securityConfiguration + attributeFriendlyName: securityConfiguration + - name: ignoreAuthenticationMethod + displayName: label.ignore-any-sp-requested-authentication-method + displayType: boolean + defaultValue: false + helpText: tooltip.ignore-auth-method + persistType: string + persistValue: 0x1 + attributeName: http://shibboleth.net/ns/profiles/disallowedFeatures + attributeFriendlyName: disallowedFeatures + - name: omitNotBefore + displayName: label.omit-not-before-condition + displayType: boolean + defaultValue: false + helpText: tooltip.omit-not-before-condition + attributeName: http://shibboleth.net/ns/profiles/includeConditionsNotBefore + attributeFriendlyName: includeConditionsNotBefore + - name: responderId + displayName: label.responder-id + displayType: string + defaultValue: null + helpText: tooltip.responder-id + attributeName: http://shibboleth.net/ns/profiles/responderId + attributeFriendlyName: responderId + - name: nameIdFormats + displayName: label.nameid-format-to-send + displayType: set + helpText: tooltip.nameid-format + defaultValues: + - urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified + - urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress + - urn:oasis:names:tc:SAML:2.0:nameid-format:persistent + - urn:oasis:names:tc:SAML:2.0:nameid-format:transient + attributeName: http://shibboleth.net/ns/profiles/nameIDFormatPrecedence + attributeFriendlyName: nameIDFormatPrecedence + - name: authenticationMethods + displayName: label.authentication-methods-to-use + displayType: set + helpText: tooltip.authentication-methods-to-use + defaultValues: + - https://refeds.org/profile/mfa + - urn:oasis:names:tc:SAML:2.0:ac:classes:TimeSyncToken + - urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport + attributeName: http://shibboleth.net/ns/profiles/defaultAuthenticationMethods + attributeFriendlyName: defaultAuthenticationMethods + - name: forceAuthn + displayName: label.force-authn + displayType: boolean + defaultValue: false + helpText: tooltip.force-authn + attributeName: http://shibboleth.net/ns/profiles/forceAuthn + attributeFriendlyName: forceAuthn +logging: + level: + org.pac4j: "TRACE" + org.opensaml: "INFO" diff --git a/testbed/postgres/conf/keystore.p12 b/testbed/postgres/conf/keystore.p12 new file mode 100644 index 0000000000000000000000000000000000000000..57f9c162a6953c21e77cf24451d52a9d3fa5cd54 GIT binary patch literal 2591 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 Date: Tue, 3 Dec 2019 15:08:00 -0600 Subject: [PATCH 02/10] [NOTASK] escape table name --- .../internet2/tier/shibboleth/admin/ui/security/model/User.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/User.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/User.java index c30c4ceff..f5cf35e88 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/User.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/User.java @@ -32,7 +32,7 @@ @Setter @EqualsAndHashCode(callSuper = true, exclude = "roles") @ToString(exclude = "roles") -@Table(name = "USERS") +@Table(name = "\"USER\"") public class User extends AbstractAuditable { @Column(nullable = false, unique = true) From f45cc68debe86bc9ddee48ada794d30c66165663 Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Wed, 4 Dec 2019 16:59:10 -0500 Subject: [PATCH 03/10] wip --- backend/build.gradle | 9 +- testbed/mysql/conf/application.yml | 138 +++++++++++++++++++++++++++++ testbed/mysql/conf/keystore.p12 | Bin 0 -> 2591 bytes testbed/mysql/conf/users.csv | 2 + testbed/mysql/docker-compose.yml | 41 +++++++++ 5 files changed, 186 insertions(+), 4 deletions(-) create mode 100644 testbed/mysql/conf/application.yml create mode 100644 testbed/mysql/conf/keystore.p12 create mode 100644 testbed/mysql/conf/users.csv create mode 100644 testbed/mysql/docker-compose.yml diff --git a/backend/build.gradle b/backend/build.gradle index 21c508193..64f8a7e10 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -26,7 +26,7 @@ repositories { configurations.all { resolutionStrategy { force 'org.cryptacular:cryptacular:1.1.3' - + eachDependency { details -> if (details.requested.group == 'org.seleniumhq.selenium' && details.requested.name != 'htmlunit-driver') { details.useVersion '3.141.59' @@ -38,7 +38,7 @@ configurations.all { configurations { integrationTestCompile { extendsFrom compile - + } integrationTestRuntime { extendsFrom runtime @@ -170,6 +170,7 @@ dependencies { compile "com.h2database:h2" runtimeOnly "org.postgresql:postgresql" runtimeOnly 'org.mariadb.jdbc:mariadb-java-client:2.2.0' + runtimeOnly 'mysql:mysql-connector-java:5.1.48' //Swagger compile 'io.springfox:springfox-swagger2:2.9.2' @@ -187,7 +188,7 @@ dependencies { //JSON schema generator testCompile 'com.kjetland:mbknor-jackson-jsonschema_2.12:1.0.29' testCompile 'javax.validation:validation-api:2.0.1.Final' - + //JSON schema validator compile 'org.sharegov:mjson:1.4.1' @@ -200,7 +201,7 @@ dependencies { integrationTestCompile "org.springframework.security:spring-security-test" integrationTestCompile "org.spockframework:spock-core:1.1-groovy-2.4" integrationTestCompile "org.spockframework:spock-spring:1.1-groovy-2.4" - + // CSV file support compile 'com.opencsv:opencsv:4.4' diff --git a/testbed/mysql/conf/application.yml b/testbed/mysql/conf/application.yml new file mode 100644 index 000000000..2f6774d17 --- /dev/null +++ b/testbed/mysql/conf/application.yml @@ -0,0 +1,138 @@ +spring: + profiles: + include: + datasource: + platform: mysql + driver-class-name: com.mysql.jdbc.Driver + url: jdbc:mysql://db:3306/shibui + username: shibui + password: shibui + jpa: + properties: + hibernate: + dialect: org.hibernate.dialect.MySQL5Dialect +server: + port: 8443 + ssl: + key-store: "/conf/keystore.p12" + key-store-password: "changeit" + keyStoreType: "PKCS12" + keyAlias: "tomcat" +shibui: + user-bootstrap-resource: file:/conf/users.csv + roles: ROLE_ADMIN,ROLE_NONE,ROLE_USER,ROLE_PONY +custom: + attributes: + # Default attributes + - name: eduPersonPrincipalName + displayName: label.attribute-eduPersonPrincipalName + - name: uid + displayName: label.attribute-uid + - name: mail + displayName: label.attribute-mail + - name: surname + displayName: label.attribute-surname + - name: givenName + displayName: label.attribute-givenName + - name: eduPersonAffiliation + displayName: label.attribute-eduPersonAffiliation + - name: eduPersonScopedAffiliation + displayName: label.attribute-eduPersonScopedAffiliation + - name: eduPersonPrimaryAffiliation + displayName: label.attribute-eduPersonPrimaryAffiliation + - name: eduPersonEntitlement + displayName: label.attribute-eduPersonEntitlement + - name: eduPersonAssurance + displayName: label.attribute-eduPersonAssurance + - name: eduPersonUniqueId + displayName: label.attribute-eduPersonUniqueId + - name: employeeNumber + displayName: label.attribute-employeeNumber + # Custom attributes + overrides: + # Default overrides + - name: signAssertion + displayName: label.sign-the-assertion + displayType: boolean + defaultValue: false + helpText: tooltip.sign-assertion + attributeName: http://shibboleth.net/ns/profiles/saml2/sso/browser/signAssertions + attributeFriendlyName: signAssertions + - name: dontSignResponse + displayName: label.dont-sign-the-response + displayType: boolean + defaultValue: false + helpText: tooltip.dont-sign-response + attributeName: http://shibboleth.net/ns/profiles/saml2/sso/browser/signResponses + attributeFriendlyName: signResponses + - name: turnOffEncryption + displayName: label.turn-off-encryption-of-response + displayType: boolean + defaultValue: false + helpText: tooltip.turn-off-encryption + attributeName: http://shibboleth.net/ns/profiles/encryptAssertions + attributeFriendlyName: encryptAssertions + - name: useSha + displayName: label.use-sha1-signing-algorithm + displayType: boolean + defaultValue: false + helpText: tooltip.usa-sha-algorithm + persistType: string + persistValue: shibboleth.SecurityConfiguration.SHA1 + attributeName: http://shibboleth.net/ns/profiles/securityConfiguration + attributeFriendlyName: securityConfiguration + - name: ignoreAuthenticationMethod + displayName: label.ignore-any-sp-requested-authentication-method + displayType: boolean + defaultValue: false + helpText: tooltip.ignore-auth-method + persistType: string + persistValue: 0x1 + attributeName: http://shibboleth.net/ns/profiles/disallowedFeatures + attributeFriendlyName: disallowedFeatures + - name: omitNotBefore + displayName: label.omit-not-before-condition + displayType: boolean + defaultValue: false + helpText: tooltip.omit-not-before-condition + attributeName: http://shibboleth.net/ns/profiles/includeConditionsNotBefore + attributeFriendlyName: includeConditionsNotBefore + - name: responderId + displayName: label.responder-id + displayType: string + defaultValue: null + helpText: tooltip.responder-id + attributeName: http://shibboleth.net/ns/profiles/responderId + attributeFriendlyName: responderId + - name: nameIdFormats + displayName: label.nameid-format-to-send + displayType: set + helpText: tooltip.nameid-format + defaultValues: + - urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified + - urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress + - urn:oasis:names:tc:SAML:2.0:nameid-format:persistent + - urn:oasis:names:tc:SAML:2.0:nameid-format:transient + attributeName: http://shibboleth.net/ns/profiles/nameIDFormatPrecedence + attributeFriendlyName: nameIDFormatPrecedence + - name: authenticationMethods + displayName: label.authentication-methods-to-use + displayType: set + helpText: tooltip.authentication-methods-to-use + defaultValues: + - https://refeds.org/profile/mfa + - urn:oasis:names:tc:SAML:2.0:ac:classes:TimeSyncToken + - urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport + attributeName: http://shibboleth.net/ns/profiles/defaultAuthenticationMethods + attributeFriendlyName: defaultAuthenticationMethods + - name: forceAuthn + displayName: label.force-authn + displayType: boolean + defaultValue: false + helpText: tooltip.force-authn + attributeName: http://shibboleth.net/ns/profiles/forceAuthn + attributeFriendlyName: forceAuthn +logging: + level: + org.pac4j: "TRACE" + org.opensaml: "INFO" diff --git a/testbed/mysql/conf/keystore.p12 b/testbed/mysql/conf/keystore.p12 new file mode 100644 index 0000000000000000000000000000000000000000..57f9c162a6953c21e77cf24451d52a9d3fa5cd54 GIT binary patch literal 2591 zcmY+EXEYlM8^+#;9KJd*1inb3Z)iIp_EPKhMV>97D|oBqN7osHVVFVlnzLKj_FP$qF%41Q3R* z^9r}YF%+)Wm1*z9WVf@%JDMN3TvEX07$;TX^lxG0$V|M==T7l`GEyXPdw zXm@Syfq*ghPdN9rC^82iIiSk~gaP$MoHrr;heS_|UuGmN=cS{B0tJIUb0I?8*yTo7 z<;eF;9*tyN_u(*2@@PrdCWF2Dy0D}1o_X_!#ZZ`{?D%G$xW!6I082tT@kNaVWLI$y zQ?{iJZ+N@ftfv2ER`h<1Ps33b3x`zD#Xa^Yls;WQ*yFh6Z4hzUNZY5VhP!2ryOY5V zKGpR+arsS!Krgf}A<6#C2})#Ie`zQ4&PMp_lE|YAC+E}i=UDu!=&HTo~B0gi(9cejrUwu@8hK)P4Ppc|?PGVI38Hao~@kTe57RrfAV`uiHpU&|;rw>h&9Ew=! zLMynJ&c~u{@IoN*@p6@(O;6g*)m@_r4f!y92e%+LL89f0jf2D#yd<5tn%y@)<=-63 z6_0Wk384``Yo}vPAw_V9)L#x);zJ`87Rrq4-DfRRQ`^s@Lrj#H(Pe=Mp7Po8fC#js zcSJ_PtVsY!pJk}CFP;k7O zc_`Dqty6pqp_B4@A5ys8D~azqv>9f*uX6D_`SXt6#4yP$g|~+Vfroy_?Yb-~gYqI0 z5mLA&`cD56Gh6EF>7>Bz6Bov(Oh|U|)q=+_KUMmMQaoWc_bHRFt>yS2`2PdR_MWAzBqHlq;FHp;4?3i-pX#W148gm~V-UUZ|n*JjzAkUSFq zttV7Z>+Y5zw~xD0q0bHr6tPBYk<@ZRYqSC5C5LJiSzj9x*Jfz5<(#IULa0K099m|`{ksz@rub0J!&%HoKuFUrr zWXg;<+Bqmkm+RPThvHeaFl2lIUw}{=`hIFH2F^riQ@cgPRe##VOlhq{C!$y zVj2oh;|;i+c{#2fJ1b-;B#$QNMnLR@eci$$qQ-ms7bc++#f`<^nCMftG;_6g7RkDG zS)Avgii(ZQLOp!MllH-jXVki-(HWhVnKy&7Tl@B)y!#8xCT>ULqi)rNN;h#Q7CxqR zte=q-)bmc(SCU!-g{|J;c?pUaD+SJP9LH%`RA><;$y;@hzcxf~7(I>Z(q(f{zf_Xe zf^+??N-7p<2rn(b58wsx0N4W_0sP?n|Aeg4EFh+Pt{#q1X?a;iWkm%Ac?CFJ`bwTg zf0ro1S3Xt0Ldrlgz}1rZCn5WnVZr|~tkqHEp57>;w2?YVbCA+_xIaH;_`imYz>t%= zKLnhg96NO9Of%ipR@Ct?o8CRsk7X;lAXwe>=H7+*|55nmS)}2Ts|&f1Nl>z1 zPp%bXaadZ_SSnSH-ijLuA8bkgxt3k0e=KaXxvasg01EAO&U?ELSmNRS@Vih`O`n~! zm(iL%2^WSEvkM+EsF_lT1D_e@M-l3VUhD?z3@NL5yD$To`Q|y$2lZz@8Gr zH4a-TtEoQ|2cur+F-BXgKL4tkHyAja?^>!LPV8%yz$IX7t45YvZQo#J^&uiR-_S?` zVVZok0mHxl`d(kE5k+c?f|#$W$oE!N?wV_-Lx@?LcLHxvUivKu_Ty)u3Fn#qSoD1Z z)q5K^gp<}bKZ1pR>6t{YF4aubO9b>EsG|8Ic|MxD@?c@p>&n6>r)Kdcl7DnwQx*!? zqN|mP_On)F72tRv9Ka}`BR`D!)Z6uX6A@!OR6q&@dJtSP&2tHt*YNx*)eyv6=1@=1 z0Ny4nsx!gKdBZ)?43Q@1JQD0EntJm%-;=l00}SIaB7KE>E%tK`$J1|Vk{ZzCy#=0( zrOIhoXp~QXrmT;gp5{^Jz8Ls+TQIjTzYevT&yv94>ouv1?~>VU#n%gf$6Xt~E(ERD zK;m4byGfL*a9YtUngDy?_Brb@jq?t0C5>?`p)fW$*MQBkF|Ww#RnhSC@RkIWjKknZ zBLec1=wR==k~K5LiB(-Ox;}hz-_=vlV^IAz9_d%ru;Fawb=wBT7=0Z)%sJL=ETE z1K}_i-IeO_F;spY)>~=*tiy^f*X(CwGuxLIb|s@IL$=*RKp0_k{sq}UzfGV^$P=R# z0ouf)?@zmvOBRng}=n%+lMZ$8fk6z%zIgz@9-Z^#c&dEhz zjy_f~4KC~7h);(y-@3i8#%7D{ip3I?%)J>p*up#)iL;26E8bS&fw=+*E z&@<&p2yJD Date: Thu, 5 Dec 2019 12:16:07 -0500 Subject: [PATCH 04/10] WIP --- .../domain/AbstractAttributeExtensibleXMLObject.java | 10 ++++++++-- .../shibboleth/admin/ui/domain/RequestInitiator.java | 6 +++++- .../domain/filters/EntityAttributesFilterTarget.java | 2 +- .../tier/shibboleth/admin/ui/security/model/Role.java | 1 + .../tier/shibboleth/admin/ui/security/model/User.java | 2 +- gradle.properties | 2 +- testbed/mysql/conf/application.yml | 2 +- 7 files changed, 18 insertions(+), 7 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractAttributeExtensibleXMLObject.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractAttributeExtensibleXMLObject.java index 62bb46df8..60aef53e8 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractAttributeExtensibleXMLObject.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractAttributeExtensibleXMLObject.java @@ -2,11 +2,14 @@ import lombok.EqualsAndHashCode; import org.hibernate.envers.Audited; +import org.hibernate.envers.NotAudited; import org.opensaml.core.xml.AttributeExtensibleXMLObject; import org.opensaml.core.xml.util.AttributeMap; import javax.annotation.Nonnull; +import javax.persistence.Column; import javax.persistence.ElementCollection; +import javax.persistence.MapKeyColumn; import javax.persistence.MappedSuperclass; import javax.persistence.PostLoad; import javax.persistence.PrePersist; @@ -31,7 +34,10 @@ public AttributeMap getUnknownAttributes() { return this.unknownAttributes; } - @ElementCollection + //@ElementCollection + //@MapKeyColumn(length = 1000) + //@NotAudited + @Transient private Map storageAttributeMap = new HashMap<>(); @PrePersist @@ -43,4 +49,4 @@ void prePersist() { void postLoad() { this.unknownAttributes.putAll(this.storageAttributeMap); } -} \ No newline at end of file +} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RequestInitiator.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RequestInitiator.java index dbd667ff9..96e08ca11 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RequestInitiator.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RequestInitiator.java @@ -4,8 +4,10 @@ import org.opensaml.core.xml.util.AttributeMap; import javax.annotation.Nonnull; +import javax.persistence.Column; import javax.persistence.ElementCollection; import javax.persistence.Entity; +import javax.persistence.MapKeyColumn; import javax.persistence.PostLoad; import javax.persistence.PrePersist; import javax.persistence.Transient; @@ -51,7 +53,9 @@ public void setResponseLocation(String location) { this.responseLocation = location; } - @ElementCollection + //@ElementCollection + //@MapKeyColumn(length = 1000) + @Transient private Map storageAttributeMap = new HashMap<>(); @Transient diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/EntityAttributesFilterTarget.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/EntityAttributesFilterTarget.java index 8a9c2a7fb..965ce0899 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/EntityAttributesFilterTarget.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/EntityAttributesFilterTarget.java @@ -32,7 +32,7 @@ public enum EntityAttributesFilterTargetType { @ElementCollection @OrderColumn - @Column(length = 4000) + //@Column(length = 1000) private List value; public EntityAttributesFilterTargetType getEntityAttributesFilterTargetType() { diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/Role.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/Role.java index 41acabdca..64792774d 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/Role.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/Role.java @@ -41,6 +41,7 @@ public Role(String name, int rank) { @Column(unique = true) private String name; + @Column(name = "ROLE_RANK") private int rank; //Ignore properties annotation here is to prevent stack overflow recursive error during JSON serialization diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/User.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/User.java index f5cf35e88..c30c4ceff 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/User.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/security/model/User.java @@ -32,7 +32,7 @@ @Setter @EqualsAndHashCode(callSuper = true, exclude = "roles") @ToString(exclude = "roles") -@Table(name = "\"USER\"") +@Table(name = "USERS") public class User extends AbstractAuditable { @Column(nullable = false, unique = true) diff --git a/gradle.properties b/gradle.properties index 2b6041ed8..8bad0c7be 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ opensaml.version=3.4.0 spring-boot.version=2.0.0.RELEASE -hibernate.version=5.2.11.Final +hibernate.version=5.3.14.Final lucene.version=7.2.1 diff --git a/testbed/mysql/conf/application.yml b/testbed/mysql/conf/application.yml index 2f6774d17..76e40f809 100644 --- a/testbed/mysql/conf/application.yml +++ b/testbed/mysql/conf/application.yml @@ -10,7 +10,7 @@ spring: jpa: properties: hibernate: - dialect: org.hibernate.dialect.MySQL5Dialect + dialect: org.hibernate.dialect.MySQL8Dialect server: port: 8443 ssl: From 022d8f69d8ca5504fd0a9fbed3b99d692b986dde Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Thu, 5 Dec 2019 16:31:32 -0500 Subject: [PATCH 05/10] WIP1 --- .../admin/ui/envers/PrincipalAwareRevisionEntity.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/envers/PrincipalAwareRevisionEntity.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/envers/PrincipalAwareRevisionEntity.java index e0aef8807..15c5eca75 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/envers/PrincipalAwareRevisionEntity.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/envers/PrincipalAwareRevisionEntity.java @@ -6,12 +6,14 @@ import org.hibernate.envers.RevisionEntity; import javax.persistence.Entity; +import javax.persistence.Table; /** * Extension of the default envers revision entity to track authenticated principals */ @Entity @RevisionEntity(PrincipalEnhancingRevisionListener.class) +@Table(name = "REVINFO") @Getter @Setter public class PrincipalAwareRevisionEntity extends DefaultTrackingModifiedEntitiesRevisionEntity { From 0f31a4f404f1e7919f6510ea5ba92a2c6151573d Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Mon, 9 Dec 2019 14:40:45 -0500 Subject: [PATCH 06/10] WIP --- .../AbstractAttributeExtensibleXMLObject.java | 6 +- .../admin/ui/domain/RequestInitiator.java | 4 +- .../ui/hibernate/QNameTypeContributor.java | 15 ++ .../admin/ui/hibernate/QNameUserType.java | 150 ++++++++++++++++++ .../org.hibernate.boot.model.TypeContributor | 1 + testbed/mariadb/conf/application.yml | 138 ++++++++++++++++ testbed/mariadb/conf/keystore.p12 | Bin 0 -> 2591 bytes testbed/mariadb/conf/users.csv | 2 + testbed/mariadb/docker-compose.yml | 41 +++++ 9 files changed, 350 insertions(+), 7 deletions(-) create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/hibernate/QNameTypeContributor.java create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/hibernate/QNameUserType.java create mode 100644 backend/src/main/resources/META-INF/services/org.hibernate.boot.model.TypeContributor create mode 100644 testbed/mariadb/conf/application.yml create mode 100644 testbed/mariadb/conf/keystore.p12 create mode 100644 testbed/mariadb/conf/users.csv create mode 100644 testbed/mariadb/docker-compose.yml diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractAttributeExtensibleXMLObject.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractAttributeExtensibleXMLObject.java index 60aef53e8..1d35bfc49 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractAttributeExtensibleXMLObject.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractAttributeExtensibleXMLObject.java @@ -1,6 +1,7 @@ package edu.internet2.tier.shibboleth.admin.ui.domain; import lombok.EqualsAndHashCode; +import org.hibernate.annotations.Type; import org.hibernate.envers.Audited; import org.hibernate.envers.NotAudited; import org.opensaml.core.xml.AttributeExtensibleXMLObject; @@ -34,10 +35,7 @@ public AttributeMap getUnknownAttributes() { return this.unknownAttributes; } - //@ElementCollection - //@MapKeyColumn(length = 1000) - //@NotAudited - @Transient + @ElementCollection private Map storageAttributeMap = new HashMap<>(); @PrePersist diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RequestInitiator.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RequestInitiator.java index 96e08ca11..4405d2797 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RequestInitiator.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RequestInitiator.java @@ -53,9 +53,7 @@ public void setResponseLocation(String location) { this.responseLocation = location; } - //@ElementCollection - //@MapKeyColumn(length = 1000) - @Transient + @ElementCollection private Map storageAttributeMap = new HashMap<>(); @Transient diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/hibernate/QNameTypeContributor.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/hibernate/QNameTypeContributor.java new file mode 100644 index 000000000..0cca1f713 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/hibernate/QNameTypeContributor.java @@ -0,0 +1,15 @@ +package edu.internet2.tier.shibboleth.admin.ui.hibernate; + +import org.hibernate.boot.model.TypeContributions; +import org.hibernate.boot.model.TypeContributor; +import org.hibernate.service.ServiceRegistry; + +import javax.xml.namespace.QName; + +public class QNameTypeContributor implements TypeContributor { + + @Override + public void contribute(TypeContributions typeContributions, ServiceRegistry serviceRegistry) { + typeContributions.contributeType(new QNameUserType(), "qname", QName.class.getName()); + } +} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/hibernate/QNameUserType.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/hibernate/QNameUserType.java new file mode 100644 index 000000000..5c14dd1dd --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/hibernate/QNameUserType.java @@ -0,0 +1,150 @@ +package edu.internet2.tier.shibboleth.admin.ui.hibernate; + +import org.hibernate.HibernateException; +import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.usertype.UserType; + +import javax.xml.namespace.QName; +import java.io.Serializable; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; + +public class QNameUserType implements UserType { + + private static final int[] SQL_TYPES = new int[] { Types.VARCHAR }; + + /* + * (non-Javadoc) + * + * @see org.hibernate.usertype.UserType#assemble(java.io.Serializable, java.lang.Object) + */ + public Object assemble(Serializable cached, Object owner) throws HibernateException { + return cached; + } + + /* + * (non-Javadoc) + * + * @see org.hibernate.usertype.UserType#deepCopy(java.lang.Object) + */ + public Object deepCopy(Object value) throws HibernateException { + return value; + } + + /* + * (non-Javadoc) + * + * @see org.hibernate.usertype.UserType#disassemble(java.lang.Object) + */ + public Serializable disassemble(Object value) throws HibernateException { + return (Serializable) value; + } + + /** Compares the int values of the enumerates */ + public boolean equals(Object x, Object y) throws HibernateException { + // todo: check compare on null values + if (x == null && y == null) { + return true; + } + + if (x == null || y == null) { + return false; + } + + if (x.getClass() != y.getClass()) { + return false; + } + + final QName q1 = (QName) x; + final QName q2 = (QName) y; + + return q1.toString().compareTo(q2.toString()) == 0; + } + + /* + * (non-Javadoc) + * + * @see org.hibernate.usertype.UserType#hashCode(java.lang.Object) + */ + public int hashCode(Object x) throws HibernateException { + return x.toString().hashCode(); + } + + /** Not mutable */ + public boolean isMutable() { + return false; + } + + /* + * (non-Javadoc) + * + * @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet, java.lang.String[], + * java.lang.Object) + */ + public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor sessionContractImplementor, Object owner) throws HibernateException, SQLException { + final String str = rs.getString(names[0]); + if (rs.wasNull()) { + return null; + } + return convertFromString(str); + } + + /* + * (non-Javadoc) + * + * @see org.hibernate.usertype.UserType#nullSafeSet(java.sql.PreparedStatement, + * java.lang.Object, int) + */ + public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor sessionContractImplementor) throws HibernateException, SQLException { + if (value == null) { + st.setNull(index, Types.VARCHAR); + } else { + st.setString(index, convertToString((QName) value)); + } + } + + /* + * (non-Javadoc) + * + * @see org.hibernate.usertype.UserType#replace(java.lang.Object, java.lang.Object, + * java.lang.Object) + */ + public Object replace(Object original, Object target, Object owner) throws HibernateException { + return original; + } + + /** Returns the parameterizezd enumType */ + public Class returnedClass() { + return QName.class; + } + + /** An enum is stored in one varchar */ + public int[] sqlTypes() { + return SQL_TYPES; + } + + protected String convertToString(QName qName) { + return "{" + qName.getNamespaceURI() + "}" + qName.getPrefix() + ":" + qName.getLocalPart(); + } + + protected QName convertFromString(String str) { + if (str.indexOf("{") == -1) { + throw new HibernateException("String " + str + " can not be converted to a QName, missing starting {"); + } + final int endIndexNS = str.indexOf("}"); + if (endIndexNS == -1) { + throw new HibernateException("String " + str + + " can not be converted to a QName, missing end ns delimiter } "); + } + final int prefixIndex = str.indexOf(":", endIndexNS); + if (prefixIndex == -1) { + throw new HibernateException("String " + str + " can not be converted to a QName, missing prefix delimiter :"); + } + final String ns = str.substring(1, endIndexNS); + final String prefix = str.substring(endIndexNS + 1, prefixIndex); + final String localPart = str.substring(prefixIndex + 1); + return new QName(ns, localPart, prefix); + } +} diff --git a/backend/src/main/resources/META-INF/services/org.hibernate.boot.model.TypeContributor b/backend/src/main/resources/META-INF/services/org.hibernate.boot.model.TypeContributor new file mode 100644 index 000000000..5f1ae5827 --- /dev/null +++ b/backend/src/main/resources/META-INF/services/org.hibernate.boot.model.TypeContributor @@ -0,0 +1 @@ +edu.internet2.tier.shibboleth.admin.ui.hibernate.QNameTypeContributor diff --git a/testbed/mariadb/conf/application.yml b/testbed/mariadb/conf/application.yml new file mode 100644 index 000000000..68018a4b9 --- /dev/null +++ b/testbed/mariadb/conf/application.yml @@ -0,0 +1,138 @@ +spring: + profiles: + include: + datasource: + platform: mysql + driver-class-name: org.mariadb.jdbc.Driver + url: jdbc:mariadb://db:3306/shibui + username: shibui + password: shibui + jpa: + properties: + hibernate: + dialect: org.hibernate.dialect.MariaDBDialect +server: + port: 8443 + ssl: + key-store: "/conf/keystore.p12" + key-store-password: "changeit" + keyStoreType: "PKCS12" + keyAlias: "tomcat" +shibui: + user-bootstrap-resource: file:/conf/users.csv + roles: ROLE_ADMIN,ROLE_NONE,ROLE_USER,ROLE_PONY +custom: + attributes: + # Default attributes + - name: eduPersonPrincipalName + displayName: label.attribute-eduPersonPrincipalName + - name: uid + displayName: label.attribute-uid + - name: mail + displayName: label.attribute-mail + - name: surname + displayName: label.attribute-surname + - name: givenName + displayName: label.attribute-givenName + - name: eduPersonAffiliation + displayName: label.attribute-eduPersonAffiliation + - name: eduPersonScopedAffiliation + displayName: label.attribute-eduPersonScopedAffiliation + - name: eduPersonPrimaryAffiliation + displayName: label.attribute-eduPersonPrimaryAffiliation + - name: eduPersonEntitlement + displayName: label.attribute-eduPersonEntitlement + - name: eduPersonAssurance + displayName: label.attribute-eduPersonAssurance + - name: eduPersonUniqueId + displayName: label.attribute-eduPersonUniqueId + - name: employeeNumber + displayName: label.attribute-employeeNumber + # Custom attributes + overrides: + # Default overrides + - name: signAssertion + displayName: label.sign-the-assertion + displayType: boolean + defaultValue: false + helpText: tooltip.sign-assertion + attributeName: http://shibboleth.net/ns/profiles/saml2/sso/browser/signAssertions + attributeFriendlyName: signAssertions + - name: dontSignResponse + displayName: label.dont-sign-the-response + displayType: boolean + defaultValue: false + helpText: tooltip.dont-sign-response + attributeName: http://shibboleth.net/ns/profiles/saml2/sso/browser/signResponses + attributeFriendlyName: signResponses + - name: turnOffEncryption + displayName: label.turn-off-encryption-of-response + displayType: boolean + defaultValue: false + helpText: tooltip.turn-off-encryption + attributeName: http://shibboleth.net/ns/profiles/encryptAssertions + attributeFriendlyName: encryptAssertions + - name: useSha + displayName: label.use-sha1-signing-algorithm + displayType: boolean + defaultValue: false + helpText: tooltip.usa-sha-algorithm + persistType: string + persistValue: shibboleth.SecurityConfiguration.SHA1 + attributeName: http://shibboleth.net/ns/profiles/securityConfiguration + attributeFriendlyName: securityConfiguration + - name: ignoreAuthenticationMethod + displayName: label.ignore-any-sp-requested-authentication-method + displayType: boolean + defaultValue: false + helpText: tooltip.ignore-auth-method + persistType: string + persistValue: 0x1 + attributeName: http://shibboleth.net/ns/profiles/disallowedFeatures + attributeFriendlyName: disallowedFeatures + - name: omitNotBefore + displayName: label.omit-not-before-condition + displayType: boolean + defaultValue: false + helpText: tooltip.omit-not-before-condition + attributeName: http://shibboleth.net/ns/profiles/includeConditionsNotBefore + attributeFriendlyName: includeConditionsNotBefore + - name: responderId + displayName: label.responder-id + displayType: string + defaultValue: null + helpText: tooltip.responder-id + attributeName: http://shibboleth.net/ns/profiles/responderId + attributeFriendlyName: responderId + - name: nameIdFormats + displayName: label.nameid-format-to-send + displayType: set + helpText: tooltip.nameid-format + defaultValues: + - urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified + - urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress + - urn:oasis:names:tc:SAML:2.0:nameid-format:persistent + - urn:oasis:names:tc:SAML:2.0:nameid-format:transient + attributeName: http://shibboleth.net/ns/profiles/nameIDFormatPrecedence + attributeFriendlyName: nameIDFormatPrecedence + - name: authenticationMethods + displayName: label.authentication-methods-to-use + displayType: set + helpText: tooltip.authentication-methods-to-use + defaultValues: + - https://refeds.org/profile/mfa + - urn:oasis:names:tc:SAML:2.0:ac:classes:TimeSyncToken + - urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport + attributeName: http://shibboleth.net/ns/profiles/defaultAuthenticationMethods + attributeFriendlyName: defaultAuthenticationMethods + - name: forceAuthn + displayName: label.force-authn + displayType: boolean + defaultValue: false + helpText: tooltip.force-authn + attributeName: http://shibboleth.net/ns/profiles/forceAuthn + attributeFriendlyName: forceAuthn +logging: + level: + org.pac4j: "TRACE" + org.opensaml: "INFO" diff --git a/testbed/mariadb/conf/keystore.p12 b/testbed/mariadb/conf/keystore.p12 new file mode 100644 index 0000000000000000000000000000000000000000..57f9c162a6953c21e77cf24451d52a9d3fa5cd54 GIT binary patch literal 2591 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 Date: Mon, 9 Dec 2019 15:59:13 -0500 Subject: [PATCH 07/10] WIP --- .../filters/EntityAttributesFilterTarget.java | 7 +------ .../MetadataResolverRepositoryTests.groovy | 15 ++------------- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/EntityAttributesFilterTarget.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/EntityAttributesFilterTarget.java index 965ce0899..0a0da096f 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/EntityAttributesFilterTarget.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/filters/EntityAttributesFilterTarget.java @@ -5,13 +5,10 @@ import lombok.EqualsAndHashCode; import org.hibernate.envers.AuditOverride; import org.hibernate.envers.Audited; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import javax.persistence.Column; import javax.persistence.ElementCollection; import javax.persistence.Entity; -import javax.persistence.FetchType; import javax.persistence.OrderColumn; import java.util.ArrayList; import java.util.List; @@ -26,13 +23,11 @@ public enum EntityAttributesFilterTargetType { ENTITY, CONDITION_SCRIPT, CONDITION_REF, REGEX } - private static Logger LOGGER = LoggerFactory.getLogger(EntityAttributesFilterTarget.class); - private EntityAttributesFilterTargetType entityAttributesFilterTargetType; @ElementCollection @OrderColumn - //@Column(length = 1000) + @Column(length = 760) private List value; public EntityAttributesFilterTargetType getEntityAttributesFilterTargetType() { diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/MetadataResolverRepositoryTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/MetadataResolverRepositoryTests.groovy index b3f102167..43bff31ce 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/MetadataResolverRepositoryTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/MetadataResolverRepositoryTests.groovy @@ -200,7 +200,7 @@ class MetadataResolverRepositoryTests extends Specification { basicPersistenceOfResolverIsCorrectFor { it instanceof LocalDynamicMetadataResolver } } - def "persisting entity attributes filter target with script of more than 255 characters"() { + def "persisting entity attributes filter target with script of 760 max chars, as defied in DB schema mapping"() { given: def mdr = new MetadataResolver().with { it.name = "SHIBUI-1588" @@ -211,18 +211,7 @@ class MetadataResolverRepositoryTests extends Specification { it.resourceId = 'SHIBUI-1588' it.entityAttributesFilterTarget = new EntityAttributesFilterTarget().with { it.entityAttributesFilterTargetType = CONDITION_SCRIPT - it.singleValue = """ - /* - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut - labore et dolore magna aliqua. Cras fermentum odio eu feugiat pretium nibh ipsum. Sed augue lacus viverra vitae. - Fermentum et sollicitudin ac orci. Platea dictumst vestibulum rhoncus est pellentesque elit ullamcorper dignissim. - Rhoncus urna neque viverra justo nec ultrices dui sapien. Tortor id aliquet lectus proin nibh nisl condimentum id venenatis. - Massa id neque aliquam vestibulum morbi blandit cursus risus. Metus aliquam eleifend mi in nulla posuere sollicitudin. - Arcu ac tortor dignissim convallis aenean. Et tortor consequat id porta nibh venenatis cras. - Netus et malesuada fames ac turpis egestas. Bibendum arcu vitae elementum curabitur. - Volutpat consequat mauris nunc congue nisi vitae suscipit. - */ - """ + it.singleValue = '/*' + ('X' * 756) + '*/' it } it From 00151ecb186555b83e448b57488770b7a36987cf Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Mon, 9 Dec 2019 17:02:38 -0500 Subject: [PATCH 08/10] WIP --- .../ui/controller/EntityDescriptorController.java | 11 ++++++++++- .../ui/controller/MetadataResolversController.java | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java index 8bb0da84f..914ae8d1b 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java @@ -71,6 +71,7 @@ public void initRestTemplate() { } @PostMapping("/EntityDescriptor") + @Transactional public ResponseEntity create(@RequestBody EntityDescriptorRepresentation edRepresentation) { final String entityId = edRepresentation.getEntityId(); @@ -93,11 +94,13 @@ public ResponseEntity create(@RequestBody EntityDescriptorRepresentation edRe } @PostMapping(value = "/EntityDescriptor", consumes = "application/xml") + @Transactional public ResponseEntity upload(@RequestBody byte[] entityDescriptorXml, @RequestParam String spName) throws Exception { return handleUploadingEntityDescriptorXml(entityDescriptorXml, spName); } @PostMapping(value = "/EntityDescriptor", consumes = "application/x-www-form-urlencoded") + @Transactional public ResponseEntity upload(@RequestParam String metadataUrl, @RequestParam String spName) throws Exception { try { byte[] xmlContents = this.restTemplate.getForObject(metadataUrl, byte[].class); @@ -112,6 +115,7 @@ public ResponseEntity upload(@RequestParam String metadataUrl, @RequestParam } @PutMapping("/EntityDescriptor/{resourceId}") + @Transactional public ResponseEntity update(@RequestBody EntityDescriptorRepresentation edRepresentation, @PathVariable String resourceId) { User currentUser = userService.getCurrentUser(); EntityDescriptor existingEd = entityDescriptorRepository.findByResourceId(resourceId); @@ -163,6 +167,7 @@ public ResponseEntity getAll() { } @GetMapping("/EntityDescriptor/{resourceId}") + @Transactional(readOnly = true) public ResponseEntity getOne(@PathVariable String resourceId) { User currentUser = userService.getCurrentUser(); EntityDescriptor ed = entityDescriptorRepository.findByResourceId(resourceId); @@ -180,6 +185,7 @@ public ResponseEntity getOne(@PathVariable String resourceId) { } @GetMapping(value = "/EntityDescriptor/{resourceId}", produces = "application/xml") + @Transactional(readOnly = true) public ResponseEntity getOneXml(@PathVariable String resourceId) throws MarshallingException { User currentUser = userService.getCurrentUser(); EntityDescriptor ed = entityDescriptorRepository.findByResourceId(resourceId); @@ -195,7 +201,7 @@ public ResponseEntity getOneXml(@PathVariable String resourceId) throws Marsh } } - @Transactional + @Transactional(readOnly = true) @GetMapping(value = "/EntityDescriptor/disabledNonAdmin") public Iterable getDisabledAndNotOwnedByAdmin() { return entityDescriptorRepository.findAllDisabledAndNotOwnedByAdmin() @@ -205,6 +211,7 @@ public Iterable getDisabledAndNotOwnedByAdmin() @Secured("ROLE_ADMIN") @DeleteMapping(value = "/EntityDescriptor/{resourceId}") + @Transactional public ResponseEntity deleteOne(@PathVariable String resourceId) { EntityDescriptor ed = entityDescriptorRepository.findByResourceId(resourceId); if (ed == null) { @@ -220,6 +227,7 @@ public ResponseEntity deleteOne(@PathVariable String resourceId) { //Versioning endpoints @GetMapping("/EntityDescriptor/{resourceId}/Versions") + @Transactional(readOnly = true) public ResponseEntity getAllVersions(@PathVariable String resourceId) { EntityDescriptor ed = entityDescriptorRepository.findByResourceId(resourceId); if (ed == null) { @@ -236,6 +244,7 @@ public ResponseEntity getAllVersions(@PathVariable String resourceId) { } @GetMapping("/EntityDescriptor/{resourceId}/Versions/{versionId}") + @Transactional(readOnly = true) public ResponseEntity getSpecificVersion(@PathVariable String resourceId, @PathVariable String versionId) { EntityDescriptorRepresentation edRepresentation = versionService.findSpecificVersionOfEntityDescriptor(resourceId, versionId); diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java index e07272629..96906980b 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java @@ -157,6 +157,7 @@ public ResponseEntity update(@PathVariable String resourceId, @RequestBody Me //Versioning endpoints @GetMapping("/MetadataResolvers/{resourceId}/Versions") + @Transactional(readOnly = true) public ResponseEntity getAllVersions(@PathVariable String resourceId) { MetadataResolver resolver = resolverRepository.findByResourceId(resourceId); if (resolver == null) { From f5e32da3e485ea81c625702781a86b755fd255f4 Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Wed, 11 Dec 2019 12:07:47 -0500 Subject: [PATCH 09/10] Changes for code review --- .../AbstractAttributeExtensibleXMLObject.java | 4 - .../admin/ui/domain/RequestInitiator.java | 2 - .../envers/PrincipalAwareRevisionEntity.java | 1 - .../admin/ui/hibernate/QNameUserType.java | 75 +++++++++++++------ 4 files changed, 54 insertions(+), 28 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractAttributeExtensibleXMLObject.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractAttributeExtensibleXMLObject.java index 1d35bfc49..50f2bdbe8 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractAttributeExtensibleXMLObject.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractAttributeExtensibleXMLObject.java @@ -1,16 +1,12 @@ package edu.internet2.tier.shibboleth.admin.ui.domain; import lombok.EqualsAndHashCode; -import org.hibernate.annotations.Type; import org.hibernate.envers.Audited; -import org.hibernate.envers.NotAudited; import org.opensaml.core.xml.AttributeExtensibleXMLObject; import org.opensaml.core.xml.util.AttributeMap; import javax.annotation.Nonnull; -import javax.persistence.Column; import javax.persistence.ElementCollection; -import javax.persistence.MapKeyColumn; import javax.persistence.MappedSuperclass; import javax.persistence.PostLoad; import javax.persistence.PrePersist; diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RequestInitiator.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RequestInitiator.java index 4405d2797..dbd667ff9 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RequestInitiator.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/RequestInitiator.java @@ -4,10 +4,8 @@ import org.opensaml.core.xml.util.AttributeMap; import javax.annotation.Nonnull; -import javax.persistence.Column; import javax.persistence.ElementCollection; import javax.persistence.Entity; -import javax.persistence.MapKeyColumn; import javax.persistence.PostLoad; import javax.persistence.PrePersist; import javax.persistence.Transient; diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/envers/PrincipalAwareRevisionEntity.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/envers/PrincipalAwareRevisionEntity.java index 15c5eca75..0685eba92 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/envers/PrincipalAwareRevisionEntity.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/envers/PrincipalAwareRevisionEntity.java @@ -13,7 +13,6 @@ */ @Entity @RevisionEntity(PrincipalEnhancingRevisionListener.class) -@Table(name = "REVINFO") @Getter @Setter public class PrincipalAwareRevisionEntity extends DefaultTrackingModifiedEntitiesRevisionEntity { diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/hibernate/QNameUserType.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/hibernate/QNameUserType.java index 5c14dd1dd..12cec360f 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/hibernate/QNameUserType.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/hibernate/QNameUserType.java @@ -1,5 +1,6 @@ package edu.internet2.tier.shibboleth.admin.ui.hibernate; +import net.shibboleth.utilities.java.support.xml.QNameSupport; import org.hibernate.HibernateException; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.usertype.UserType; @@ -11,9 +12,13 @@ import java.sql.SQLException; import java.sql.Types; +/** + * Hibernate custom UserType needed to properly persist QName objects. + * Base implementation is taken from {@link https://github.com/tomsontom/emf-databinding-example/blob/0ae7faa67697a84171846852a5c5b0492d9a8f7d/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/QNameUserType.java} + */ public class QNameUserType implements UserType { - private static final int[] SQL_TYPES = new int[] { Types.VARCHAR }; + private static final int[] SQL_TYPES = new int[]{Types.VARCHAR}; /* * (non-Javadoc) @@ -42,25 +47,14 @@ public Serializable disassemble(Object value) throws HibernateException { return (Serializable) value; } - /** Compares the int values of the enumerates */ public boolean equals(Object x, Object y) throws HibernateException { - // todo: check compare on null values - if (x == null && y == null) { + if (x == y) { return true; - } - - if (x == null || y == null) { - return false; - } - - if (x.getClass() != y.getClass()) { + } else if (x == null || y == null) { return false; + } else { + return x.equals(y); } - - final QName q1 = (QName) x; - final QName q2 = (QName) y; - - return q1.toString().compareTo(q2.toString()) == 0; } /* @@ -69,14 +63,49 @@ public boolean equals(Object x, Object y) throws HibernateException { * @see org.hibernate.usertype.UserType#hashCode(java.lang.Object) */ public int hashCode(Object x) throws HibernateException { - return x.toString().hashCode(); + return x.hashCode(); } - /** Not mutable */ + /** + * Not mutable + */ public boolean isMutable() { return false; } + /* + * (non-Javadoc) + * + * @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet, java.lang.String[], + * java.lang.Object) + */ + /*public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor sessionContractImplementor, Object owner) throws HibernateException, SQLException { + final String namespaceURI = rs.getString(names[0]); + if (rs.wasNull()) { + return null; + } + final String localPart = rs.getString(names[1]); + final String prefix = rs.getString(names[2]); + return QNameSupport.constructQName(namespaceURI, localPart, prefix); + }*/ + + /* + * (non-Javadoc) + * + * @see org.hibernate.usertype.UserType#nullSafeSet(java.sql.PreparedStatement, + * java.lang.Object, int) + */ + /*public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor sessionContractImplementor) throws HibernateException, SQLException { + if (value == null) { + st.setNull(index, Types.VARCHAR); + } else { + QName qName = (QName) value; + st.setString(index, qName.getNamespaceURI()); + st.setString(index + 1, qName.getLocalPart()); + st.setString(index + 2, qName.getPrefix()); + } + }*/ + /* * (non-Javadoc) * @@ -115,12 +144,16 @@ public Object replace(Object original, Object target, Object owner) throws Hiber return original; } - /** Returns the parameterizezd enumType */ + /** + * Returns the parameterizezd enumType + */ public Class returnedClass() { return QName.class; } - /** An enum is stored in one varchar */ + /** + * An enum is stored in one varchar + */ public int[] sqlTypes() { return SQL_TYPES; } @@ -145,6 +178,6 @@ protected QName convertFromString(String str) { final String ns = str.substring(1, endIndexNS); final String prefix = str.substring(endIndexNS + 1, prefixIndex); final String localPart = str.substring(prefixIndex + 1); - return new QName(ns, localPart, prefix); + return QNameSupport.constructQName(ns, localPart, prefix); } } From 6e6b9d826ed98a1d0dc9515df6ff2e6bd3713ef5 Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Wed, 11 Dec 2019 14:58:33 -0500 Subject: [PATCH 10/10] Polishing --- .../admin/ui/hibernate/QNameUserType.java | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/hibernate/QNameUserType.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/hibernate/QNameUserType.java index 12cec360f..f87bb8a73 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/hibernate/QNameUserType.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/hibernate/QNameUserType.java @@ -73,39 +73,6 @@ public boolean isMutable() { return false; } - /* - * (non-Javadoc) - * - * @see org.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet, java.lang.String[], - * java.lang.Object) - */ - /*public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor sessionContractImplementor, Object owner) throws HibernateException, SQLException { - final String namespaceURI = rs.getString(names[0]); - if (rs.wasNull()) { - return null; - } - final String localPart = rs.getString(names[1]); - final String prefix = rs.getString(names[2]); - return QNameSupport.constructQName(namespaceURI, localPart, prefix); - }*/ - - /* - * (non-Javadoc) - * - * @see org.hibernate.usertype.UserType#nullSafeSet(java.sql.PreparedStatement, - * java.lang.Object, int) - */ - /*public void nullSafeSet(PreparedStatement st, Object value, int index, SharedSessionContractImplementor sessionContractImplementor) throws HibernateException, SQLException { - if (value == null) { - st.setNull(index, Types.VARCHAR); - } else { - QName qName = (QName) value; - st.setString(index, qName.getNamespaceURI()); - st.setString(index + 1, qName.getLocalPart()); - st.setString(index + 2, qName.getPrefix()); - } - }*/ - /* * (non-Javadoc) *