Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed JmacHttpsTest - certificate authentication #24877

Merged
merged 4 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright (c) 2024 Contributors to the Eclipse Foundation.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/

package com.sun.enterprise.deployment.node.runtime.common;

import java.io.Serializable;
import java.security.Principal;
import java.util.Objects;

import org.glassfish.security.common.UserPrincipal;

/**
* {@link Principal} loaded from XML descriptor.
* When the equals method is used, it compares just principal names and that the other object
* is an {@link Principal} instance too.
*/
// Must be UserPrincipal, because RoleMapper.internalAssignRole knows just that and Group.
public class DescriptorPrincipalName implements UserPrincipal, Serializable {

private static final long serialVersionUID = -640182254691955451L;

private final String name;

/**
* @param name must not be null.
*/
public DescriptorPrincipalName(String name) {
this.name = Objects.requireNonNull(name, "XML principal-name element must not be null.");
}


@Override
public String getName() {
return name;
}


@Override
public int hashCode() {
return name.hashCode();
}


/**
* We match user principals just by name.
* This is used in Jakarta Security to resolve authorisation.
*/
@Override
public boolean equals(Object o) {
if (o instanceof Principal) {
Principal other = (Principal) o;
return getName().equals(other.getName());
}
return false;
}


@Override
public String toString() {
return getClass().getSimpleName() + "[" + getName() + "]";
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 Contributors to the Eclipse Foundation
* Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation
* Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
Expand All @@ -17,11 +17,12 @@

package com.sun.enterprise.deployment.runtime.common;

import com.sun.enterprise.deployment.node.runtime.common.DescriptorPrincipalName;

import java.lang.reflect.Constructor;
import java.security.Principal;

import org.glassfish.deployment.common.Descriptor;
import org.glassfish.security.common.UserNameAndPassword;

/**
* This is an in memory representation of the principal-name with its name of
Expand Down Expand Up @@ -53,7 +54,7 @@ public String getName() {
*/
public String getClassName() {
if (className == null) {
return UserNameAndPassword.class.getName();
return DescriptorPrincipalName.class.getName();
}
return className;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2024 Contributors to the Eclipse Foundation.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/

package org.glassfish.main.itest.tools;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashSet;
import java.util.Set;

/**
* Tools useful just for tests, so they don't belong to any application code.
*/
public final class TestUtilities {

private TestUtilities() {
// hidden
}


/**
* Deletes files if they exist.
* If it existed but was not possible to delete the file, uses NIO to delete it again - NIO
* throws an exception in such case.
* <p>
* Attempts to delete all files and throws the {@link IOException} if any of them was not
* possible to delete. Therefore this method should be the last call in your cleanup method (ie.
* AfterEach or AfterAll)
*
* @param files files to delete
* @throws IOException some files were not deleted.
*/
public static void delete(final File... files) throws IOException {
final Set<File> failed = new HashSet<>(files.length);
for (File file : files) {
if (file == null || !file.exists() || file.delete()) {
continue;
}
failed.add(file);
}
if (failed.isEmpty()) {
return;
}
final IOException failures = new IOException("Could not delete files: " + failed);
for (File file : failed) {
try {
Files.delete(file.toPath());
} catch (IOException e) {
failures.addSuppressed(e);
}
}
throw failures;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 Contributors to the Eclipse Foundation
* Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation
* Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
Expand Down Expand Up @@ -46,6 +46,9 @@
import org.glassfish.security.common.UserNameAndPassword;
import org.glassfish.security.common.UserPrincipal;

import static java.util.logging.Level.FINE;
import static java.util.logging.Level.WARNING;

/**
* This Object maintains a mapping of users and groups to application specific Roles. Using this object this mapping
* information could be maintained and queried at a later time. This is a complete rewrite of the previous RoleMapper
Expand Down Expand Up @@ -195,9 +198,7 @@ public Map<String, Subject> getRoleToSubjectMapping() {
// The method that does the work for assignRole().
private void internalAssignRole(Principal p, Role r) {
String role = r.getName();
if (LOG.isLoggable(Level.FINE)) {
LOG.log(Level.FINE, "SECURITY:RoleMapper Assigning Role {0} to {1}", new Object[] {role, p});
}
LOG.log(FINE, "Assigning Role {0} to {1}", new Object[] {role, p});
addRoleToPrincipal(p, role);
if (p instanceof Group) {
Set<Group> groups = roleToGroup.get(role);
Expand Down Expand Up @@ -307,9 +308,6 @@ public String toString() {
}
s.append(")");
}
if (LOG.isLoggable(Level.FINER)) {
LOG.log(Level.FINER, s.toString());
}
return s.toString();
}

Expand Down Expand Up @@ -365,7 +363,7 @@ private String getDefaultP2RMappingClassName() {
c.newInstance("anystring");
return className;
} catch (Exception e) {
LOG.log(Level.SEVERE, "pc.getDefaultP2RMappingClass: " + e);
LOG.log(Level.SEVERE, "pc.getDefaultP2RMappingClass: " + className, e);
return null;
}
}
Expand Down Expand Up @@ -414,23 +412,17 @@ private void checkAndAddMappings() {

if (topLevelRoles != null && topLevelRoles.contains(r)) {
logConflictWarning();
if (LOG.isLoggable(Level.FINE)) {
LOG.log(Level.FINE,
"Role " + r + " from module " + currentMapping.owner + " is being overridden by top-level mapping.");
}

LOG.log(FINE, "Role {0} from module {1} is being overridden by top-level mapping.",
new Object[] {r, currentMapping.owner});
continue;
}

if (currentMapping.owner.equals(TOP_LEVEL)) {
topLevelRoles.add(r);
if (roleToSubject.keySet().contains(r.getName())) {
logConflictWarning();
if (LOG.isLoggable(Level.FINE)) {
LOG.log(Level.FINE,
"Role " + r + " from top-level mapping descriptor is " + "overriding existing role in sub module.");
}

LOG.log(FINE,
"Role {0} from top-level mapping descriptor is overriding existing role in sub module.", r);
unassignRole(r);
}

Expand All @@ -456,11 +448,8 @@ private boolean roleConflicts(Role r, Set<Principal> ps) {

// check to see if there has been a previous conflict
if (conflictedRoles != null && conflictedRoles.contains(r)) {
if (LOG.isLoggable(Level.FINE)) {
LOG.log(Level.FINE,
"Role " + r + " from module " + currentMapping.owner + " has already had a conflict with other modules.");
}

LOG.log(FINE, "Role {0} from module {1} has already had a conflict with other modules.",
new Object[] {r, currentMapping.owner});
return true;
}

Expand All @@ -477,10 +466,8 @@ private boolean roleConflicts(Role r, Set<Principal> ps) {
actualNum += pSet == null ? 0 : pSet.size();
actualNum += gSet == null ? 0 : gSet.size();
if (targetNumPrin != actualNum) {
if (LOG.isLoggable(Level.FINE)) {
LOG.log(Level.FINE, "Module " + currentMapping.owner + " has different number of mappings for role " + r.getName()
+ " than other mapping files");
}
LOG.log(FINE, "Module {0} has different number of mappings for role {1} than other mapping files",
new Object[] {currentMapping.owner, r.getName()});

if (conflictedRoles == null) {
conflictedRoles = new HashSet<>();
Expand All @@ -503,9 +490,8 @@ private boolean roleConflicts(Role r, Set<Principal> ps) {
}

if (fail) {
if (LOG.isLoggable(Level.FINE)) {
LOG.log(Level.FINE, "Role " + r + " in module " + currentMapping.owner + " is not included in other modules.");
}
LOG.log(FINE, "Role {0} in module {1} is not included in other modules.",
new Object[] {r, currentMapping.owner});

if (conflictedRoles == null) {
conflictedRoles = new HashSet<>();
Expand All @@ -523,7 +509,8 @@ private boolean roleConflicts(Role r, Set<Principal> ps) {

private void logConflictWarning() {
if (!conflictLogged) {
LOG.log(Level.WARNING, "Role mapping conflicts found in application {0}. Some roles may not be mapped.", getName());
LOG.log(WARNING, "Role mapping conflicts found in application {0}. Some roles may not be mapped.",
getName());
conflictLogged = true;
}
}
Expand Down Expand Up @@ -576,8 +563,7 @@ Principal getSameNamedPrincipal(String roleName) {
Principal principal = (Principal) c.newInstance(arg);
return principal;
} catch (Exception e) {
LOG.log(Level.SEVERE, "rm.getSameNamedPrincipal", new Object[] { roleName, e });
throw new RuntimeException("Unable to get principal by default p2r mapping");
throw new RuntimeException("Unable to get principal by default p2r mapping", e);
}
}

Expand Down