|
19 | 19 | import java.security.KeyPair; |
20 | 20 | import java.security.cert.CertificateEncodingException; |
21 | 21 | import java.security.cert.X509Certificate; |
22 | | -import java.util.ArrayList; |
23 | 22 | import java.util.Collections; |
24 | 23 | import java.util.Comparator; |
25 | | -import java.util.HashMap; |
26 | | -import java.util.LinkedHashMap; |
27 | 24 | import java.util.LinkedHashSet; |
28 | 25 | import java.util.List; |
29 | | -import java.util.Locale; |
30 | 26 | import java.util.Map; |
31 | 27 | import java.util.Objects; |
32 | 28 | import java.util.Optional; |
|
87 | 83 | import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger; |
88 | 84 | import org.eclipse.milo.opcua.stack.core.types.enumerated.ApplicationType; |
89 | 85 | import org.eclipse.milo.opcua.stack.core.types.enumerated.MessageSecurityMode; |
90 | | -import org.eclipse.milo.opcua.stack.core.types.enumerated.UserTokenType; |
91 | 86 | import org.eclipse.milo.opcua.stack.core.types.structured.ApplicationDescription; |
92 | 87 | import org.eclipse.milo.opcua.stack.core.types.structured.EndpointDescription; |
93 | | -import org.eclipse.milo.opcua.stack.core.types.structured.UserTokenPolicy; |
94 | 88 | import org.eclipse.milo.opcua.stack.core.util.EndpointUtil; |
95 | 89 | import org.eclipse.milo.opcua.stack.core.util.FutureUtils; |
96 | 90 | import org.eclipse.milo.opcua.stack.core.util.Lazy; |
@@ -850,149 +844,24 @@ private boolean isDiscoveryService(UaRequestMessageType requestMessage) { |
850 | 844 | } |
851 | 845 |
|
852 | 846 | private List<EndpointDescription> transformEndpoints(Set<EndpointConfig> endpoints) { |
853 | | - Map<UserTokenPolicyKey, String> userTokenPolicyIds = assignUserTokenPolicyIds(endpoints); |
| 847 | + UserTokenPolicyIds userTokenPolicyIds = UserTokenPolicyIds.assign(endpoints); |
854 | 848 |
|
855 | 849 | return endpoints.stream().map(e -> transformEndpoint(e, userTokenPolicyIds)).toList(); |
856 | 850 | } |
857 | 851 |
|
858 | 852 | private EndpointDescription transformEndpoint( |
859 | | - EndpointConfig endpoint, Map<UserTokenPolicyKey, String> userTokenPolicyIds) { |
| 853 | + EndpointConfig endpoint, UserTokenPolicyIds userTokenPolicyIds) { |
860 | 854 | return new EndpointDescription( |
861 | 855 | endpoint.getEndpointUrl(), |
862 | 856 | getApplicationDescription(), |
863 | 857 | certificateByteString(endpoint.getCertificate()), |
864 | 858 | endpoint.getSecurityMode(), |
865 | 859 | endpoint.getSecurityPolicy().getUri(), |
866 | | - transformUserTokenPolicies(endpoint, userTokenPolicyIds), |
| 860 | + userTokenPolicyIds.policiesFor(endpoint), |
867 | 861 | endpoint.getTransportProfile().getUri(), |
868 | 862 | ubyte(getSecurityLevel(endpoint.getSecurityPolicy(), endpoint.getSecurityMode()))); |
869 | 863 | } |
870 | 864 |
|
871 | | - private UserTokenPolicy[] transformUserTokenPolicies( |
872 | | - EndpointConfig endpoint, Map<UserTokenPolicyKey, String> userTokenPolicyIds) { |
873 | | - |
874 | | - return endpoint.getTokenPolicies().stream() |
875 | | - .map( |
876 | | - tokenPolicy -> { |
877 | | - UserTokenPolicyKey key = UserTokenPolicyKey.from(endpoint, tokenPolicy); |
878 | | - String assignedPolicyId = userTokenPolicyIds.get(key); |
879 | | - |
880 | | - String policyId = |
881 | | - policyIdChanged(tokenPolicy.getPolicyId(), assignedPolicyId) |
882 | | - ? assignedPolicyId |
883 | | - : tokenPolicy.getPolicyId(); |
884 | | - |
885 | | - return new UserTokenPolicy( |
886 | | - policyId, |
887 | | - tokenPolicy.getTokenType(), |
888 | | - tokenPolicy.getIssuedTokenType(), |
889 | | - tokenPolicy.getIssuerEndpointUrl(), |
890 | | - key.securityPolicyUri()); |
891 | | - }) |
892 | | - .toArray(UserTokenPolicy[]::new); |
893 | | - } |
894 | | - |
895 | | - private Map<UserTokenPolicyKey, String> assignUserTokenPolicyIds( |
896 | | - Set<EndpointConfig> endpoints) { |
897 | | - Map<String, List<UserTokenPolicyKey>> keysByPolicyId = new LinkedHashMap<>(); |
898 | | - |
899 | | - for (EndpointConfig endpoint : endpoints) { |
900 | | - for (UserTokenPolicy tokenPolicy : endpoint.getTokenPolicies()) { |
901 | | - UserTokenPolicyKey key = UserTokenPolicyKey.from(endpoint, tokenPolicy); |
902 | | - List<UserTokenPolicyKey> keys = |
903 | | - keysByPolicyId.computeIfAbsent(key.policyId(), ignored -> new ArrayList<>()); |
904 | | - |
905 | | - if (!keys.contains(key)) { |
906 | | - keys.add(key); |
907 | | - } |
908 | | - } |
909 | | - } |
910 | | - |
911 | | - Set<String> reservedPolicyIds = new LinkedHashSet<>(keysByPolicyId.keySet()); |
912 | | - Map<UserTokenPolicyKey, String> assignedPolicyIds = new HashMap<>(); |
913 | | - |
914 | | - for (List<UserTokenPolicyKey> keys : keysByPolicyId.values()) { |
915 | | - if (keys.size() == 1) { |
916 | | - UserTokenPolicyKey key = keys.get(0); |
917 | | - assignedPolicyIds.put(key, key.policyId()); |
918 | | - } else { |
919 | | - UserTokenPolicyKey firstKey = keys.get(0); |
920 | | - assignedPolicyIds.put(firstKey, firstKey.policyId()); |
921 | | - |
922 | | - for (int i = 1; i < keys.size(); i++) { |
923 | | - UserTokenPolicyKey key = keys.get(i); |
924 | | - assignedPolicyIds.put(key, uniquePolicyId(key, reservedPolicyIds)); |
925 | | - } |
926 | | - } |
927 | | - } |
928 | | - |
929 | | - return assignedPolicyIds; |
930 | | - } |
931 | | - |
932 | | - private boolean policyIdChanged(@Nullable String configuredPolicyId, String assignedPolicyId) { |
933 | | - if (Objects.equals(configuredPolicyId, assignedPolicyId)) { |
934 | | - return false; |
935 | | - } else { |
936 | | - return !(isNullOrEmpty(configuredPolicyId) && assignedPolicyId.isEmpty()); |
937 | | - } |
938 | | - } |
939 | | - |
940 | | - private String uniquePolicyId(UserTokenPolicyKey key, Set<String> reservedPolicyIds) { |
941 | | - String base = |
942 | | - key.policyId().isEmpty() |
943 | | - ? key.tokenType().name().toLowerCase(Locale.ROOT) |
944 | | - : key.policyId(); |
945 | | - |
946 | | - String securityPolicyName = securityPolicyName(key.securityPolicyUri()); |
947 | | - |
948 | | - String candidate = base + "-" + securityPolicyName; |
949 | | - if (reservedPolicyIds.add(candidate)) { |
950 | | - return candidate; |
951 | | - } |
952 | | - |
953 | | - candidate = base + "-" + key.tokenType().name() + "-" + securityPolicyName; |
954 | | - if (reservedPolicyIds.add(candidate)) { |
955 | | - return candidate; |
956 | | - } |
957 | | - |
958 | | - for (int i = 2; ; i++) { |
959 | | - String indexedCandidate = candidate + "-" + i; |
960 | | - if (reservedPolicyIds.add(indexedCandidate)) { |
961 | | - return indexedCandidate; |
962 | | - } |
963 | | - } |
964 | | - } |
965 | | - |
966 | | - private String securityPolicyName(String securityPolicyUri) { |
967 | | - int index = securityPolicyUri.lastIndexOf('#'); |
968 | | - String name = index >= 0 ? securityPolicyUri.substring(index + 1) : securityPolicyUri; |
969 | | - |
970 | | - return name.replaceAll("[^A-Za-z0-9_.-]", "-"); |
971 | | - } |
972 | | - |
973 | | - private boolean isNullOrEmpty(@Nullable String value) { |
974 | | - return value == null || value.isEmpty(); |
975 | | - } |
976 | | - |
977 | | - private record UserTokenPolicyKey( |
978 | | - String policyId, |
979 | | - UserTokenType tokenType, |
980 | | - @Nullable String issuedTokenType, |
981 | | - @Nullable String issuerEndpointUrl, |
982 | | - String securityPolicyUri) { |
983 | | - |
984 | | - static UserTokenPolicyKey from(EndpointConfig endpoint, UserTokenPolicy tokenPolicy) { |
985 | | - String policyId = tokenPolicy.getPolicyId(); |
986 | | - |
987 | | - return new UserTokenPolicyKey( |
988 | | - policyId == null ? "" : policyId, |
989 | | - tokenPolicy.getTokenType(), |
990 | | - tokenPolicy.getIssuedTokenType(), |
991 | | - tokenPolicy.getIssuerEndpointUrl(), |
992 | | - endpoint.getEffectiveTokenSecurityPolicyUri(tokenPolicy)); |
993 | | - } |
994 | | - } |
995 | | - |
996 | 865 | private ByteString certificateByteString(@Nullable X509Certificate certificate) { |
997 | 866 | if (certificate != null) { |
998 | 867 | try { |
|
0 commit comments