Fix java/equals-on-unrelated-types CodeQL alerts (#781)
7 files modified
4 files added
| | |
| | | * |
| | | * Copyright 2008-2010 Sun Microsystems, Inc. |
| | | * Portions Copyright 2012-2016 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.guitools.controlpanel.browser; |
| | | |
| | |
| | | } |
| | | conn = connectionPool.getConnection(url); |
| | | remoteDn = DN.valueOf(url.getRawBaseDN()); |
| | | if (remoteDn == null || "".equals(remoteDn)) |
| | | if (remoteDn.isRootDN()) |
| | | { |
| | | /* The referral has not a target DN specified: we |
| | | have to use the DN of the entry that contains the |
| | |
| | | * |
| | | * Copyright 2008-2010 Sun Microsystems, Inc. |
| | | * Portions Copyright 2013-2016 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.guitools.controlpanel.task; |
| | | |
| | |
| | | while (entryDNs.hasNext()) |
| | | { |
| | | SearchResultEntry sr = entryDNs.readEntry(); |
| | | if (!sr.getName().equals("")) |
| | | if (!sr.getName().isRootDN()) |
| | | { |
| | | deleteSubtreeRecursively(conn, sr.getName(), null, toNotify); |
| | | } |
| | |
| | | * |
| | | * Copyright 2009-2010 Sun Microsystems, Inc. |
| | | * Portions Copyright 2012-2016 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | |
| | | package org.opends.guitools.controlpanel.ui; |
| | |
| | | import org.forgerock.opendj.ldap.AttributeDescription; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.forgerock.opendj.ldap.DN; |
| | | import org.forgerock.opendj.ldap.DecodeException; |
| | | import org.forgerock.opendj.ldap.Entry; |
| | | import org.forgerock.opendj.ldap.schema.MatchingRule; |
| | | import org.forgerock.opendj.ldap.schema.Schema; |
| | | import org.opends.guitools.controlpanel.browser.BrowserController; |
| | | import org.opends.guitools.controlpanel.browser.ConnectionWithControls; |
| | | import org.opends.guitools.controlpanel.ui.nodes.BasicNode; |
| | |
| | | @Override |
| | | protected String getLDIF() |
| | | { |
| | | String dn = this.dn.getText(); |
| | | return getLDIF(entryToDuplicate, dn.getText(), rdnAttribute, new String(password.getPassword()), |
| | | getInfo().getServerDescriptor().getSchema()); |
| | | } |
| | | |
| | | /** |
| | | * Returns the LDIF representation of the duplicated entry. |
| | | * |
| | | * @param entryToDuplicate the entry that is being duplicated. |
| | | * @param dn the DN of the new entry. |
| | | * @param rdnAttribute the name of the attribute used in the RDN of the entry being duplicated. |
| | | * @param password the password typed by the user, empty if the user typed none. |
| | | * @param schema the schema of the server, {@code null} if it could not be read. |
| | | * @return the LDIF representation of the duplicated entry. |
| | | */ |
| | | static String getLDIF(Entry entryToDuplicate, String dn, String rdnAttribute, String password, Schema schema) |
| | | { |
| | | StringBuilder sb = new StringBuilder(); |
| | | sb.append("dn: ").append(dn); |
| | | for (Attribute attr : entryToDuplicate.getAllAttributes()) |
| | | { |
| | | AttributeDescription attrDesc = attr.getAttributeDescription(); |
| | | String attrName = attr.getAttributeDescriptionAsString(); |
| | | if (attrDesc.equals(getUserPasswordAttributeType())) |
| | | if (attrDesc.getAttributeType().equals(getUserPasswordAttributeType())) |
| | | { |
| | | sb.append("\n"); |
| | | String pwd = new String(password.getPassword()); |
| | | if (!pwd.isEmpty()) |
| | | // The password is optional: the original password must not be copied and no line at all |
| | | // must be written when the user typed none. Writing an empty line would terminate the |
| | | // LDIF record and silently drop every attribute that comes after this one. |
| | | if (!password.isEmpty()) |
| | | { |
| | | sb.append(attrName).append(": ").append(pwd); |
| | | sb.append("\n").append(attrName).append(": ").append(password); |
| | | } |
| | | } |
| | | else if (!attrName.equalsIgnoreCase(rdnAttribute)) |
| | | { |
| | | if (!ViewEntryPanel.isEditable(attrDesc, |
| | | getInfo().getServerDescriptor().getSchema())) |
| | | if (!ViewEntryPanel.isEditable(attrDesc, schema)) |
| | | { |
| | | continue; |
| | | } |
| | | for (ByteString value : attr) |
| | | { |
| | | sb.append("\n"); |
| | | if (isBinary(attrName)) |
| | | if (Utilities.hasBinarySyntax(attrName, schema)) |
| | | { |
| | | sb.append(attrName).append(":: ").append(value.toBase64String()); |
| | | } |
| | |
| | | for (ByteString value : attr) |
| | | { |
| | | sb.append("\n"); |
| | | if (oldValue.equals(value)) |
| | | if (isRDNValue(attrDesc, value, oldValue)) |
| | | { |
| | | sb.append(attrName).append(": ").append(newValue); |
| | | } |
| | |
| | | return sb.toString(); |
| | | } |
| | | |
| | | private String getFirstValue(DN dn) |
| | | /** |
| | | * Returns whether the provided value is the value the RDN of the entry being duplicated asserts. |
| | | * <p> |
| | | * The attributes used in an RDN usually have a case insensitive equality matching rule |
| | | * ({@code cn}, {@code ou} or {@code uid} for instance) and the value stored in the entry may |
| | | * therefore differ from the value written in the DN. The comparison must consequently be done |
| | | * through the equality matching rule of the attribute and not with {@link String#equals(Object)}. |
| | | */ |
| | | private static boolean isRDNValue(AttributeDescription attrDesc, ByteString value, String rdnValue) |
| | | { |
| | | MatchingRule equalityMatchingRule = attrDesc.getAttributeType().getEqualityMatchingRule(); |
| | | if (equalityMatchingRule != null) |
| | | { |
| | | try |
| | | { |
| | | return equalityMatchingRule.normalizeAttributeValue(value) |
| | | .equals(equalityMatchingRule.normalizeAttributeValue(ByteString.valueOfUtf8(rdnValue))); |
| | | } |
| | | catch (DecodeException e) |
| | | { |
| | | // The values cannot be normalized: fall back to the case insensitive comparison below. |
| | | } |
| | | } |
| | | return rdnValue.equalsIgnoreCase(value.toString()); |
| | | } |
| | | |
| | | private static String getFirstValue(DN dn) |
| | | { |
| | | return dn.rdn().getFirstAVA().getAttributeValue().toString(); |
| | | } |
| | |
| | | * |
| | | * Copyright 2008-2010 Sun Microsystems, Inc. |
| | | * Portions Copyright 2013-2016 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.guitools.controlpanel.ui; |
| | | |
| | |
| | | { |
| | | if (OBJECTCLASS_ATTRIBUTE_TYPE_NAME.equalsIgnoreCase(attr)) |
| | | { |
| | | int nOcs = 0; |
| | | for (ByteString v : values) |
| | | { |
| | | if (!"top".equals(v)) |
| | | { |
| | | nOcs++; |
| | | } |
| | | } |
| | | return nOcs > 1 ? GridBagConstraints.NORTHWEST : GridBagConstraints.WEST; |
| | | return countObjectClassesBesidesTop(values) > 1 ? GridBagConstraints.NORTHWEST : GridBagConstraints.WEST; |
| | | } |
| | | else if (isSingleValue(attr)) |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Returns the number of object classes of an entry, not counting {@code top}. |
| | | * |
| | | * @param values the values of the object class attribute of the entry. |
| | | * @return the number of object classes, not counting {@code top}. |
| | | */ |
| | | static int countObjectClassesBesidesTop(List<ByteString> values) |
| | | { |
| | | int nOcs = 0; |
| | | for (ByteString v : values) |
| | | { |
| | | // Object class values are case insensitive. |
| | | if (!OC_TOP.equalsIgnoreCase(v.toString())) |
| | | { |
| | | nOcs++; |
| | | } |
| | | } |
| | | return nOcs; |
| | | } |
| | | |
| | | private int anchor1(List<ByteString> values) |
| | | { |
| | | int size = values.size(); |
| | |
| | | } |
| | | // Handle the root entry separately: most of its attributes are operational |
| | | // so we filter a list of hardcoded attributes. |
| | | boolean isRootEntry = "".equals(sr.getName()); |
| | | boolean isRootEntry = sr.getName().isRootDN(); |
| | | Schema schema = getInfo().getServerDescriptor().getSchema(); |
| | | if (isRootEntry) |
| | | { |
| | |
| | | else if (isConfirmPassword(attrName) || isPassword(attrName)) |
| | | { |
| | | JPasswordField pf = Utilities.createPasswordField(); |
| | | if (!"".equals(v)) |
| | | if (!v.isEmpty()) |
| | | { |
| | | pf.setText(getPasswordStringValue(getAttributeForConfirmPasswordKey(attrName), v)); |
| | | } |
| | |
| | | * |
| | | * Copyright 2008-2010 Sun Microsystems, Inc. |
| | | * Portions Copyright 2014-2016 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.guitools.controlpanel.ui; |
| | | |
| | |
| | | return tableModel.getValues(attrName); |
| | | } |
| | | |
| | | /** |
| | | * Returns whether the provided attribute must be displayed as an {@link ObjectClassValue} |
| | | * instead of as a plain list of values. |
| | | * <p> |
| | | * The object class descriptor cannot be built without the schema, so when the schema could not |
| | | * be read the raw values must be displayed instead: otherwise the object class attribute would |
| | | * not be displayed at all. |
| | | * |
| | | * @param attrDesc the description of the attribute. |
| | | * @param schema the schema of the server, {@code null} if it could not be read. |
| | | * @return {@code true} if the attribute must be displayed as an {@link ObjectClassValue}, |
| | | * {@code false} otherwise. |
| | | */ |
| | | static boolean isObjectClassWithSchema(AttributeDescription attrDesc, Schema schema) |
| | | { |
| | | return schema != null && attrDesc.getAttributeType().equals(getObjectClassAttributeType()); |
| | | } |
| | | |
| | | /** |
| | | * Returns whether the provided attribute is one of the required attributes of the entry. |
| | | * |
| | | * @param requiredAttrs the names of the required attributes, in lower case. |
| | | * @param attrDesc the description of the attribute. |
| | | * @return {@code true} if the attribute is required, {@code false} otherwise. |
| | | */ |
| | | static boolean isRequired(Set<String> requiredAttrs, AttributeDescription attrDesc) |
| | | { |
| | | // The required attributes are stored in lower case since attribute names are case insensitive. |
| | | return requiredAttrs.contains(attrDesc.getNameOrOID().toLowerCase()); |
| | | } |
| | | |
| | | /** The table model used by the tree in the panel. */ |
| | | private class LDAPEntryTableModel extends SortableTableModel |
| | | implements Comparator<AttributeValuePair> |
| | |
| | | for (Attribute attr : searchResult.getAllAttributes()) |
| | | { |
| | | AttributeDescription attrDesc = attr.getAttributeDescription(); |
| | | if (attrDesc.equals(getObjectClassAttributeType())) |
| | | if (isObjectClassWithSchema(attrDesc, schema)) |
| | | { |
| | | if (schema != null) |
| | | { |
| | | ocs = attr; |
| | | ObjectClassValue ocValue = getObjectClassDescriptor(ocs, schema); |
| | | allSortedValues.add(new AttributeValuePair(attrDesc, ocValue)); |
| | | } |
| | | ocs = attr; |
| | | ObjectClassValue ocValue = getObjectClassDescriptor(ocs, schema); |
| | | allSortedValues.add(new AttributeValuePair(attrDesc, ocValue)); |
| | | } |
| | | else |
| | | { |
| | |
| | | |
| | | private boolean isRequired(AttributeValuePair value) |
| | | { |
| | | return requiredAttrs.contains(value.attrDesc.getNameOrOID()); |
| | | return TableViewEntryPanel.isRequired(requiredAttrs, value.attrDesc); |
| | | } |
| | | |
| | | private boolean hasValue(AttributeValuePair value) |
| | |
| | | * information: "Portions Copyright [year] [name of copyright owner]". |
| | | * |
| | | * Copyright 2014-2016 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.server.replication.server.changelog.file; |
| | | |
| | |
| | | |
| | | private void tracePurgeDetails(final CSN purgeCSN, final CSN oldestNotPurgedCSN, final long sleepTime) |
| | | { |
| | | if (purgeCSN.equals(oldestNotPurgedCSN.toStringUI())) |
| | | if (purgeCSN.equals(oldestNotPurgedCSN)) |
| | | { |
| | | logger.trace("Purged up to %s. " |
| | | + "now sleeping until next purge during %s", |
| | |
| | | * |
| | | * Copyright 2008-2010 Sun Microsystems, Inc. |
| | | * Portions Copyright 2011-2016 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.server.util.cli; |
| | | |
| | |
| | | { |
| | | logger.warn(ERROR_CERTIFICATE_NULL_AUTH_TYPE.get()); |
| | | } |
| | | else |
| | | { |
| | | app.println(ApplicationTrustManager.Cause.NOT_TRUSTED.equals(authType) |
| | | ? INFO_CERTIFICATE_NOT_TRUSTED_TEXT_CLI.get(host, port) |
| | | : INFO_CERTIFICATE_NAME_MISMATCH_TEXT_CLI.get(host, port, host, host, port)); |
| | | } |
| | | // The explanation only depends on the cause of the rejection, so it must be displayed even |
| | | // when the authentication type is unknown: otherwise the user is prompted to accept a |
| | | // certificate without being told what is wrong with it. |
| | | app.println(getCertificateRejectionMessage(cause, host, port)); |
| | | |
| | | final X509Certificate[] chain = usedTrustManager.getLastRefusedChain(); |
| | | if (chain == null) |
| | |
| | | } |
| | | |
| | | /** |
| | | * Returns the message explaining why the certificate presented by the server was rejected. |
| | | * |
| | | * @param cause the reason why the certificate was rejected. |
| | | * @param host the host name of the server. |
| | | * @param port the port of the server. |
| | | * @return the message explaining why the certificate was rejected. |
| | | */ |
| | | static LocalizableMessage getCertificateRejectionMessage(ApplicationTrustManager.Cause cause, String host, int port) |
| | | { |
| | | return cause == ApplicationTrustManager.Cause.NOT_TRUSTED |
| | | ? INFO_CERTIFICATE_NOT_TRUSTED_TEXT_CLI.get(host, port) |
| | | : INFO_CERTIFICATE_NAME_MISMATCH_TEXT_CLI.get(host, port, host, host, port); |
| | | } |
| | | |
| | | /** |
| | | * Sets the heading that is displayed in interactive mode. |
| | | * |
| | | * @param heading |
| New file |
| | |
| | | /* |
| | | * The contents of this file are subject to the terms of the Common Development and |
| | | * Distribution License (the License). You may not use this file except in compliance with the |
| | | * License. |
| | | * |
| | | * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the |
| | | * specific language governing permission and limitations under the License. |
| | | * |
| | | * When distributing Covered Software, include this CDDL Header Notice in each file and include |
| | | * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL |
| | | * Header, with the fields enclosed by brackets [] replaced by your own identifying |
| | | * information: "Portions copyright [year] [name of copyright owner]". |
| | | * |
| | | * Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.guitools.controlpanel.ui; |
| | | |
| | | import static org.assertj.core.api.Assertions.assertThat; |
| | | |
| | | import java.io.IOException; |
| | | import java.io.StringReader; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | import org.forgerock.opendj.ldap.Attribute; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.forgerock.opendj.ldap.DN; |
| | | import org.forgerock.opendj.ldap.Entry; |
| | | import org.forgerock.opendj.ldap.LinkedHashMapEntry; |
| | | import org.forgerock.opendj.ldap.schema.Schema; |
| | | import org.forgerock.opendj.ldif.LDIFEntryReader; |
| | | import org.opends.server.DirectoryServerTestCase; |
| | | import org.testng.annotations.Test; |
| | | |
| | | /** Tests the LDIF generated by {@link DuplicateEntryPanel}. */ |
| | | @SuppressWarnings("javadoc") |
| | | public class DuplicateEntryPanelTestCase extends DirectoryServerTestCase |
| | | { |
| | | private static final Schema SCHEMA = Schema.getCoreSchema(); |
| | | private static final String NEW_DN = "uid=user.2,ou=people,dc=example,dc=com"; |
| | | |
| | | /** An entry whose RDN attribute is single valued and which holds a password. */ |
| | | private static Entry userEntry() |
| | | { |
| | | return new LinkedHashMapEntry( |
| | | "dn: uid=user.1,ou=people,dc=example,dc=com", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "objectClass: organizationalPerson", |
| | | "objectClass: inetOrgPerson", |
| | | "uid: user.1", |
| | | "userPassword: {SSHA}originalHashOfTheEntryBeingDuplicated", |
| | | "cn: User 1", |
| | | "sn: One"); |
| | | } |
| | | |
| | | /** |
| | | * When the user types no password, the original password must not be copied and no empty line |
| | | * must be written: an empty line terminates the LDIF record and every attribute written after |
| | | * the password would be silently dropped. |
| | | */ |
| | | @Test |
| | | public void testEmptyPasswordDoesNotTruncateTheEntry() throws Exception |
| | | { |
| | | String ldif = DuplicateEntryPanel.getLDIF(userEntry(), NEW_DN, "uid", "", SCHEMA); |
| | | |
| | | assertThat(ldif).doesNotContain("\n\n"); |
| | | Entry duplicate = readEntry(ldif); |
| | | assertThat((Object) duplicate.getName()).isEqualTo(DN.valueOf(NEW_DN)); |
| | | assertThat(valuesOf(duplicate, "userPassword")).isEmpty(); |
| | | assertThat(valuesOf(duplicate, "objectClass")) |
| | | .containsExactly("top", "person", "organizationalPerson", "inetOrgPerson"); |
| | | assertThat(valuesOf(duplicate, "uid")).containsExactly("user.2"); |
| | | assertThat(valuesOf(duplicate, "cn")).containsExactly("User 1"); |
| | | assertThat(valuesOf(duplicate, "sn")).containsExactly("One"); |
| | | } |
| | | |
| | | /** The password of the duplicated entry is the one typed by the user, not the original hash. */ |
| | | @Test |
| | | public void testTypedPasswordReplacesTheOriginalOne() throws Exception |
| | | { |
| | | String ldif = DuplicateEntryPanel.getLDIF(userEntry(), NEW_DN, "uid", "typedPassword", SCHEMA); |
| | | |
| | | Entry duplicate = readEntry(ldif); |
| | | assertThat(valuesOf(duplicate, "userPassword")).containsExactly("typedPassword"); |
| | | assertThat(valuesOf(duplicate, "sn")).containsExactly("One"); |
| | | } |
| | | |
| | | /** The value of the RDN of the new entry replaces the value of the RDN of the original entry. */ |
| | | @Test |
| | | public void testSingleValuedRDNAttributeUsesTheNewValue() throws Exception |
| | | { |
| | | String ldif = DuplicateEntryPanel.getLDIF(userEntry(), NEW_DN, "uid", "", SCHEMA); |
| | | |
| | | assertThat(valuesOf(readEntry(ldif), "uid")).containsExactly("user.2"); |
| | | } |
| | | |
| | | /** |
| | | * The attributes used in an RDN have a case insensitive equality matching rule, so the value |
| | | * stored in the entry may differ from the value written in the DN. The old value must be |
| | | * replaced nonetheless, otherwise the duplicated entry keeps the value of the original RDN. |
| | | */ |
| | | @Test |
| | | public void testMultiValuedRDNAttributeReplacesTheOldValueCaseInsensitively() throws Exception |
| | | { |
| | | Entry entry = new LinkedHashMapEntry( |
| | | "dn: cn=John Smith,ou=people,dc=example,dc=com", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "cn: john smith", |
| | | "cn: Johnny", |
| | | "sn: Smith"); |
| | | |
| | | String ldif = DuplicateEntryPanel.getLDIF(entry, "cn=John Smith-1,ou=people,dc=example,dc=com", "cn", "", SCHEMA); |
| | | |
| | | assertThat(valuesOf(readEntry(ldif), "cn")).containsExactlyInAnyOrder("John Smith-1", "Johnny"); |
| | | } |
| | | |
| | | /** Attributes the user cannot modify must not be copied into the duplicated entry. */ |
| | | @Test |
| | | public void testNoUserModificationAttributesAreNotCopied() throws Exception |
| | | { |
| | | Entry entry = new LinkedHashMapEntry( |
| | | "dn: uid=user.1,ou=people,dc=example,dc=com", |
| | | "objectClass: top", |
| | | "objectClass: person", |
| | | "uid: user.1", |
| | | "createTimestamp: 20260101000000Z", |
| | | "sn: One"); |
| | | |
| | | String ldif = DuplicateEntryPanel.getLDIF(entry, NEW_DN, "uid", "", SCHEMA); |
| | | |
| | | Entry duplicate = readEntry(ldif); |
| | | assertThat(valuesOf(duplicate, "createTimestamp")).isEmpty(); |
| | | assertThat(valuesOf(duplicate, "sn")).containsExactly("One"); |
| | | } |
| | | |
| | | /** Attributes with a binary syntax must be base64 encoded. */ |
| | | @Test |
| | | public void testBinaryAttributesAreBase64Encoded() throws Exception |
| | | { |
| | | Entry entry = new LinkedHashMapEntry(DN.valueOf("uid=user.1,ou=people,dc=example,dc=com")) |
| | | .addAttribute("objectClass", "top", "person") |
| | | .addAttribute("uid", "user.1") |
| | | .addAttribute("sn", "One") |
| | | .addAttribute("userCertificate", ByteString.wrap(new byte[] { 0x30, 0x00, (byte) 0xFF })); |
| | | |
| | | String ldif = DuplicateEntryPanel.getLDIF(entry, NEW_DN, "uid", "", SCHEMA); |
| | | |
| | | // "MAD/" is the base64 encoding of the three bytes above. |
| | | assertThat(ldif).contains("userCertificate:: MAD/"); |
| | | assertThat(valuesOf(readEntry(ldif), "sn")).containsExactly("One"); |
| | | } |
| | | |
| | | /** |
| | | * Reads the generated LDIF the same way {@code AbstractNewEntryPanel.getEntry()} does: an empty |
| | | * line terminates the record, so anything written after one is not part of the entry that is |
| | | * added to the server. |
| | | */ |
| | | private static Entry readEntry(String ldif) throws IOException |
| | | { |
| | | try (LDIFEntryReader reader = new LDIFEntryReader(new StringReader(ldif))) |
| | | { |
| | | return reader.readEntry(); |
| | | } |
| | | } |
| | | |
| | | private static List<String> valuesOf(Entry entry, String attrName) |
| | | { |
| | | List<String> values = new ArrayList<>(); |
| | | Attribute attr = entry.getAttribute(attrName); |
| | | if (attr != null) |
| | | { |
| | | for (ByteString value : attr) |
| | | { |
| | | values.add(value.toString()); |
| | | } |
| | | } |
| | | return values; |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * The contents of this file are subject to the terms of the Common Development and |
| | | * Distribution License (the License). You may not use this file except in compliance with the |
| | | * License. |
| | | * |
| | | * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the |
| | | * specific language governing permission and limitations under the License. |
| | | * |
| | | * When distributing Covered Software, include this CDDL Header Notice in each file and include |
| | | * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL |
| | | * Header, with the fields enclosed by brackets [] replaced by your own identifying |
| | | * information: "Portions copyright [year] [name of copyright owner]". |
| | | * |
| | | * Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.guitools.controlpanel.ui; |
| | | |
| | | import static org.assertj.core.api.Assertions.assertThat; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.opends.server.DirectoryServerTestCase; |
| | | import org.testng.annotations.DataProvider; |
| | | import org.testng.annotations.Test; |
| | | |
| | | /** Tests the object class counting done by {@link SimplifiedViewEntryPanel}. */ |
| | | @SuppressWarnings("javadoc") |
| | | public class SimplifiedViewEntryPanelTestCase extends DirectoryServerTestCase |
| | | { |
| | | @DataProvider |
| | | public Object[][] objectClassValues() |
| | | { |
| | | return new Object[][] { |
| | | { Collections.<String> emptyList(), 0 }, |
| | | { list("top"), 0 }, |
| | | // Object class values are case insensitive: "top" must be filtered out whatever its case is. |
| | | { list("TOP"), 0 }, |
| | | { list("Top"), 0 }, |
| | | { list("top", "person"), 1 }, |
| | | { list("TOP", "person"), 1 }, |
| | | { list("top", "person", "organizationalPerson"), 2 }, |
| | | { list("person", "organizationalPerson"), 2 }, |
| | | }; |
| | | } |
| | | |
| | | @Test(dataProvider = "objectClassValues") |
| | | public void testCountObjectClassesBesidesTop(List<String> objectClasses, int expectedCount) |
| | | { |
| | | assertThat(SimplifiedViewEntryPanel.countObjectClassesBesidesTop(byteStrings(objectClasses))) |
| | | .isEqualTo(expectedCount); |
| | | } |
| | | |
| | | private static List<String> list(String... values) |
| | | { |
| | | List<String> result = new ArrayList<>(); |
| | | Collections.addAll(result, values); |
| | | return result; |
| | | } |
| | | |
| | | private static List<ByteString> byteStrings(List<String> values) |
| | | { |
| | | List<ByteString> result = new ArrayList<>(); |
| | | for (String value : values) |
| | | { |
| | | result.add(ByteString.valueOfUtf8(value)); |
| | | } |
| | | return result; |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * The contents of this file are subject to the terms of the Common Development and |
| | | * Distribution License (the License). You may not use this file except in compliance with the |
| | | * License. |
| | | * |
| | | * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the |
| | | * specific language governing permission and limitations under the License. |
| | | * |
| | | * When distributing Covered Software, include this CDDL Header Notice in each file and include |
| | | * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL |
| | | * Header, with the fields enclosed by brackets [] replaced by your own identifying |
| | | * information: "Portions copyright [year] [name of copyright owner]". |
| | | * |
| | | * Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.guitools.controlpanel.ui; |
| | | |
| | | import static org.assertj.core.api.Assertions.assertThat; |
| | | import static org.opends.server.util.CollectionUtils.newHashSet; |
| | | |
| | | import java.util.Set; |
| | | |
| | | import org.forgerock.opendj.ldap.AttributeDescription; |
| | | import org.forgerock.opendj.ldap.schema.Schema; |
| | | import org.opends.server.DirectoryServerTestCase; |
| | | import org.testng.annotations.Test; |
| | | |
| | | /** Tests how {@link TableViewEntryPanel} decides what to display for a given attribute. */ |
| | | @SuppressWarnings("javadoc") |
| | | public class TableViewEntryPanelTestCase extends DirectoryServerTestCase |
| | | { |
| | | private static final Schema SCHEMA = Schema.getCoreSchema(); |
| | | private static final AttributeDescription OBJECT_CLASS = AttributeDescription.valueOf("objectClass", SCHEMA); |
| | | |
| | | @Test |
| | | public void testObjectClassIsDisplayedAsADescriptorWhenTheSchemaIsAvailable() |
| | | { |
| | | assertThat(TableViewEntryPanel.isObjectClassWithSchema(OBJECT_CLASS, SCHEMA)).isTrue(); |
| | | } |
| | | |
| | | /** |
| | | * The object class descriptor cannot be built without the schema: the raw values must then be |
| | | * displayed instead, otherwise the object class attribute disappears from the table. |
| | | */ |
| | | @Test |
| | | public void testObjectClassFallsBackToItsRawValuesWithoutSchema() |
| | | { |
| | | assertThat(TableViewEntryPanel.isObjectClassWithSchema(OBJECT_CLASS, null)).isFalse(); |
| | | } |
| | | |
| | | @Test |
| | | public void testOtherAttributesAreNeverDisplayedAsADescriptor() |
| | | { |
| | | assertThat(TableViewEntryPanel.isObjectClassWithSchema(AttributeDescription.valueOf("cn", SCHEMA), SCHEMA)) |
| | | .isFalse(); |
| | | } |
| | | |
| | | /** Attribute names are case insensitive, and the required attributes are stored in lower case. */ |
| | | @Test |
| | | public void testRequiredAttributesAreMatchedCaseInsensitively() |
| | | { |
| | | Set<String> requiredAttrs = newHashSet("objectclass", "sn", "cn"); |
| | | |
| | | assertThat(TableViewEntryPanel.isRequired(requiredAttrs, OBJECT_CLASS)).isTrue(); |
| | | assertThat(TableViewEntryPanel.isRequired(requiredAttrs, AttributeDescription.valueOf("sn", SCHEMA))).isTrue(); |
| | | assertThat(TableViewEntryPanel.isRequired(requiredAttrs, AttributeDescription.valueOf("description", SCHEMA))) |
| | | .isFalse(); |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * The contents of this file are subject to the terms of the Common Development and |
| | | * Distribution License (the License). You may not use this file except in compliance with the |
| | | * License. |
| | | * |
| | | * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the |
| | | * specific language governing permission and limitations under the License. |
| | | * |
| | | * When distributing Covered Software, include this CDDL Header Notice in each file and include |
| | | * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL |
| | | * Header, with the fields enclosed by brackets [] replaced by your own identifying |
| | | * information: "Portions copyright [year] [name of copyright owner]". |
| | | * |
| | | * Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.server.util.cli; |
| | | |
| | | import static org.assertj.core.api.Assertions.assertThat; |
| | | import static org.opends.messages.ToolMessages.INFO_CERTIFICATE_NAME_MISMATCH_TEXT_CLI; |
| | | import static org.opends.messages.ToolMessages.INFO_CERTIFICATE_NOT_TRUSTED_TEXT_CLI; |
| | | |
| | | import org.opends.admin.ads.util.ApplicationTrustManager; |
| | | import org.opends.server.DirectoryServerTestCase; |
| | | import org.testng.annotations.Test; |
| | | |
| | | /** Tests the message shown when the certificate presented by a server is rejected. */ |
| | | @SuppressWarnings("javadoc") |
| | | public class LDAPConnectionConsoleInteractionTestCase extends DirectoryServerTestCase |
| | | { |
| | | private static final String HOST = "localhost"; |
| | | private static final int PORT = 4444; |
| | | |
| | | @Test |
| | | public void testUntrustedCertificateIsReported() |
| | | { |
| | | assertThat(rejectionMessage(ApplicationTrustManager.Cause.NOT_TRUSTED)) |
| | | .isEqualTo(INFO_CERTIFICATE_NOT_TRUSTED_TEXT_CLI.get(HOST, PORT).toString()); |
| | | } |
| | | |
| | | @Test |
| | | public void testHostNameMismatchIsReported() |
| | | { |
| | | assertThat(rejectionMessage(ApplicationTrustManager.Cause.HOST_NAME_MISMATCH)) |
| | | .isEqualTo(INFO_CERTIFICATE_NAME_MISMATCH_TEXT_CLI.get(HOST, PORT, HOST, HOST, PORT).toString()); |
| | | } |
| | | |
| | | /** The two causes must not lead to the same message: the user needs to know what is wrong. */ |
| | | @Test |
| | | public void testTheTwoCausesAreReportedDifferently() |
| | | { |
| | | assertThat(rejectionMessage(ApplicationTrustManager.Cause.NOT_TRUSTED)) |
| | | .isNotEqualTo(rejectionMessage(ApplicationTrustManager.Cause.HOST_NAME_MISMATCH)); |
| | | } |
| | | |
| | | private static String rejectionMessage(ApplicationTrustManager.Cause cause) |
| | | { |
| | | return LDAPConnectionConsoleInteraction.getCertificateRejectionMessage(cause, HOST, PORT).toString(); |
| | | } |
| | | } |