events) {
 75 |             sc.superPut(EVENTS_DELIVERED_MEMBER, events);
 76 |             return this;
 77 |         }
 78 | 
 79 |         public Builder delivery(final JSONObject config) {
 80 |             sc.superPut(DELIVERY_MEMBER, config);
 81 |             return this;
 82 |         }
 83 | 
 84 |         public Builder minVerificationInterval(final int interval) {
 85 |             sc.superPut(MIN_VERIFICATION_INTERVAL_MEMBER, interval);
 86 |             return this;
 87 |         }
 88 | 
 89 |         public Builder format(final String format) {
 90 |             sc.superPut(FORMAT_MEMBER, format);
 91 |             return this;
 92 |         }
 93 | 
 94 |         public StreamConfiguration build() {
 95 |             return sc;
 96 |         }
 97 |     }
 98 | 
 99 | 
100 | }
101 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/StreamStatus.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model;
 8 | 
 9 | import java.util.HashMap;
10 | import java.util.Map;
11 | 
12 | /**
13 |  * Commonly used SSE stream states for SSE/RISC/CAEP events.
14 |  * 
15 |  * A Transmitter MAY decide to enable, pause or disable updates about a
16 |  * SPAG independently of an update request from a Receiver.  If a
17 |  * Transmitter decides to start or stop events for a SPAG then the
18 |  * Transmitter MUST do the following according to the status of the
19 |  * stream. If the stream is:
20 |  * 
21 |  * Enabled  the Transmitter MUST send a SPAG stream updated
22 |  * (Section 8.1.5) event respectively to the Receiver within the Event Stream.
23 |  * Paused  the Transmitter SHOULD send SPAG stream updated
24 |  * (Section 8.1.5) after the Event Stream is re-started.
25 |  * Disabled  the Transmitter MAY send SPAG stream updated
26 |  * (Section 8.1.5) after the Event Stream is re-enabled.
27 |  */
28 | public enum StreamStatus {
29 | 
30 |     ENABLED("enabled"),
31 |     PAUSED("paused"),
32 |     DISABLED("disabled");
33 | 
34 |     private static final Map BY_NAME = new HashMap<>();
35 | 
36 |     static {
37 |         for (StreamStatus t : values()) {
38 |             BY_NAME.put(t.name, t);
39 |         }
40 |     }
41 | 
42 |     private final String name;
43 | 
44 |     StreamStatus(final String s) {
45 |         name = s;
46 |     }
47 | 
48 |     public static StreamStatus valueOfLabel(final String name) {
49 |         return BY_NAME.get(name);
50 |     }
51 | 
52 |     public static boolean contains(final String name) {
53 |         return BY_NAME.containsKey(name);
54 |     }
55 | 
56 |     public boolean equalsName(final String otherName) {
57 |         return name.equals(otherName);
58 |     }
59 | 
60 |     @Override
61 |     public String toString() {
62 |         return this.name;
63 |     }
64 | 
65 | 
66 | }
67 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/TransmitterConfig.java:
--------------------------------------------------------------------------------
  1 | /*
  2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
  3 |  *
  4 |  * SPDX-License-Identifier: Apache-2.0
  5 |  */
  6 | 
  7 | package com.sailpoint.sse.model;
  8 | 
  9 | import com.nimbusds.jose.shaded.json.JSONObject;
 10 | 
 11 | import java.util.List;
 12 | 
 13 | public class TransmitterConfig extends JSONObject {
 14 | 
 15 |     public static class Builder {
 16 | 
 17 |         /**
 18 |          * REQUIRED.  URL using the https scheme with no query or
 19 |          * fragment component that the Transmitter asserts as its Issuer
 20 |          * Identifier.  This MUST be identical to the iss claim value in
 21 |          * Security Event Tokens issued from this Transmitter.
 22 |          */
 23 |         private static final String ISSUER_MEMBER = "issuer";
 24 | 
 25 | 
 26 |         /**
 27 |          * REQUIRED.  URL of the Transmitter's JSON Web Key Set
 28 |          * [RFC7517] document.  This contains the signing key(s) the Receiver
 29 |          * uses to validate signatures from the Transmitter.
 30 |          */
 31 |         private static final String JWKS_URI_MEMBER = "jwks_uri";
 32 | 
 33 |         /**
 34 |          * RECOMMENDED.  List of supported delivery method URIs.
 35 |          */
 36 |         private static final String DELIVERY_METHODS_SUPPORTED_MEMBER = "delivery_methods_supported";
 37 | 
 38 |         /**
 39 |          * OPTIONAL.  The URL of the Configuration Endpoint.
 40 |          */
 41 |         private static final String CONFIGURATION_ENDPOINT_MEMBER = "configuration_endpoint";
 42 | 
 43 | 
 44 |         /**
 45 |          * OPTIONAL.  The URL of the Status Endpoint.
 46 |          */
 47 |         private static final String STATUS_ENDPOINT_MEMBER = "status_endpoint";
 48 | 
 49 |         /**
 50 |          * OPTIONAL.  The URL of the Add Subject Endpoint.
 51 |          */
 52 |         private static final String ADD_SUBJECT_ENDPOINT_MEMBER = "add_subject_endpoint";
 53 | 
 54 | 
 55 |         /**
 56 |          * OPTIONAL.  The URL of the Remove Subject Endpoint.
 57 |          */
 58 |         private static final String REMOVE_SUBJECT_ENDPOINT_MEMBER = "remove_subject_endpoint";
 59 | 
 60 |         /**
 61 |          * OPTIONAL.  The URL of the Verification Endpoint.
 62 |          */
 63 |         private static final String VERIFICATION_ENDPOINT_MEMBER = "verification_endpoint";
 64 | 
 65 |         // List of Strings
 66 |         private static final String CRITICAL_SUBJECT_MEMBERS_MEMBER = "critical_subject_members";
 67 | 
 68 |         /**
 69 |          * The members.
 70 |          */
 71 |         private final TransmitterConfig members = new TransmitterConfig();
 72 | 
 73 |         public Builder issuer(final String iss) {
 74 | 
 75 |             members.put(ISSUER_MEMBER, iss);
 76 |             return this;
 77 |         }
 78 | 
 79 |         public Builder jwksUri(final String jwks_uri) {
 80 | 
 81 |             members.put(JWKS_URI_MEMBER, jwks_uri);
 82 |             return this;
 83 |         }
 84 | 
 85 |         public Builder deliveryMethods(final List methods) {
 86 |             members.put(DELIVERY_METHODS_SUPPORTED_MEMBER, methods);
 87 |             return this;
 88 |         }
 89 | 
 90 |         public Builder configurationEndpoint(final String endpoint) {
 91 |             members.put(CONFIGURATION_ENDPOINT_MEMBER, endpoint);
 92 |             return this;
 93 |         }
 94 | 
 95 |         public Builder statusEndpoint(final String endpoint) {
 96 |             members.put(STATUS_ENDPOINT_MEMBER, endpoint);
 97 |             return this;
 98 |         }
 99 | 
100 |         public Builder addSubjectEndpoint(final String endpoint) {
101 |             members.put(ADD_SUBJECT_ENDPOINT_MEMBER, endpoint);
102 |             return this;
103 |         }
104 | 
105 |         public Builder removeSubjectEndpoint(final String endpoint) {
106 |             members.put(REMOVE_SUBJECT_ENDPOINT_MEMBER, endpoint);
107 |             return this;
108 |         }
109 | 
110 |         public Builder verificationEndpoint(final String endpoint) {
111 |             members.put(VERIFICATION_ENDPOINT_MEMBER, endpoint);
112 |             return this;
113 |         }
114 | 
115 |         public Builder criticalSubjectMembers(final List subjectMembers) {
116 |             members.put(CRITICAL_SUBJECT_MEMBERS_MEMBER, subjectMembers);
117 |             return this;
118 |         }
119 | 
120 | 
121 |         public TransmitterConfig build() {
122 |             return members;
123 |         }
124 |     }
125 | }
126 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/Utils.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model;
 8 | 
 9 | import com.nimbusds.jose.shaded.json.JSONObject;
10 | 
11 | import java.lang.reflect.InvocationTargetException;
12 | import java.lang.reflect.Method;
13 | 
14 | public class Utils {
15 | 
16 |     protected Utils() {
17 |     }
18 | 
19 |     public static void validateMember(final SSEvent event, final String member, final Class> memberCls) throws ValidationException {
20 |         final SSEventTypes eventType = event.getEventType();
21 |         if (null == eventType) {
22 |             /* Unknown event type, not instantiated via a normal constructor. */
23 |             return;
24 |         }
25 |         JSONObject members = (JSONObject) event.get(eventType.toString());
26 | 
27 |         final Object o = members.get(member);
28 |         if (null == o) {
29 |             throw new ValidationException(event.getClass().getName() + " member " + member + " is missing or null.");
30 |         }
31 | 
32 |         // Fun with reflection to invoke contains() if the enum.name has it (and throw an exception if it does not so we can go fix it
33 |         Method methodToFind;
34 |         try {
35 |             methodToFind = memberCls.getMethod("contains", String.class);
36 |         } catch (NoSuchMethodException | SecurityException e) {
37 |             throw new ValidationException(memberCls.getName() + " does not have a contains() method.");
38 |         }
39 | 
40 |         try {
41 |             final Boolean present = (Boolean) methodToFind.invoke(memberCls, o.toString());
42 |             if (Boolean.FALSE.equals(present)) {
43 |                 throw new ValidationException(event.getClass().getName() + " member " + member + " has an invalid value.");
44 |             }
45 |         } catch (IllegalAccessException e) {
46 |             throw new ValidationException(event.getClass().getName() + " member " + member + " IllegalAccessException: " + e);
47 |         } catch (InvocationTargetException e) {
48 |             throw new ValidationException(event.getClass().getName() + " member " + member + " InvocationTargetException: " + e);
49 |         }
50 |     }
51 | 
52 | }
53 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/ValidationException.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model;
 8 | 
 9 | public class ValidationException extends Exception {
10 |     public ValidationException(final String message) {
11 |         super(message);
12 |     }
13 | }
14 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/caep/CAEPAssuranceLevelChange.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.caep;
 8 | 
 9 | import com.sailpoint.sse.model.SSEventTypes;
10 | import com.sailpoint.sse.model.Utils;
11 | import com.sailpoint.sse.model.ValidationException;
12 | import com.sailpoint.ietf.subjectidentifiers.model.SIValidationException;
13 | 
14 | import java.text.ParseException;
15 | 
16 | public class CAEPAssuranceLevelChange extends CAEPBaseEvent {
17 | 
18 |     private static final String CURRENT_LEVEL = "current_level";
19 |     private static final String PREVIOUS_LEVEL = "previous_level";
20 |     private static final String CHANGE_DIRECTION = "change_direction";
21 | 
22 |     @Override
23 |     public void validate() throws ParseException, SIValidationException, ValidationException {
24 |         super.validate();
25 |         Utils.validateMember(this, CURRENT_LEVEL, NISTAuthenticatorAssuranceLevel.class);
26 |         Utils.validateMember(this, PREVIOUS_LEVEL, NISTAuthenticatorAssuranceLevel.class);
27 |         Utils.validateMember(this, CHANGE_DIRECTION, CAEPAssuranceLevelChangeDirection.class);
28 |     }
29 | 
30 |     public static class Builder extends CAEPBaseEvent.Builder {
31 | 
32 |         public Builder() {
33 |             super(SSEventTypes.CAEP_ASSURANCE_LEVEL_CHANGE);
34 |         }
35 | 
36 |         protected CAEPAssuranceLevelChange createObj() {
37 |             return new CAEPAssuranceLevelChange();
38 |         }
39 | 
40 |         protected CAEPAssuranceLevelChange.Builder getThis() {
41 |             return this;
42 |         }
43 | 
44 |         public Builder currentLevel(final NISTAuthenticatorAssuranceLevel level) {
45 |             members.put(CURRENT_LEVEL, level.toString());
46 |             return thisObj;
47 |         }
48 | 
49 |         public Builder previousLevel(final NISTAuthenticatorAssuranceLevel level) {
50 |             members.put(PREVIOUS_LEVEL, level.toString());
51 |             return thisObj;
52 |         }
53 | 
54 |         public Builder changeDirection(final CAEPAssuranceLevelChangeDirection direction) {
55 |             members.put(CHANGE_DIRECTION, direction.toString());
56 |             return thisObj;
57 |         }
58 |     }
59 | 
60 | }
61 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/caep/CAEPAssuranceLevelChangeDirection.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.caep;
 8 | 
 9 | import java.util.HashMap;
10 | import java.util.Map;
11 | 
12 | public enum CAEPAssuranceLevelChangeDirection {
13 | 
14 |     INCREASE("increase"),
15 |     DECREASE("decrease");
16 | 
17 |     private static final Map BY_NAME = new HashMap<>();
18 | 
19 |     static {
20 |         for (CAEPAssuranceLevelChangeDirection t : values()) {
21 |             BY_NAME.put(t.name, t);
22 |         }
23 |     }
24 | 
25 |     private final String name;
26 | 
27 |     CAEPAssuranceLevelChangeDirection(final String s) {
28 |         name = s;
29 |     }
30 | 
31 |     public static CAEPAssuranceLevelChangeDirection valueOfLabel(final String name) {
32 |         return BY_NAME.get(name);
33 |     }
34 | 
35 |     @SuppressWarnings("unused")
36 |     public static boolean contains(final String name) {
37 |         return BY_NAME.containsKey(name);
38 |     }
39 | 
40 |     public boolean equalsName(final String otherName) {
41 |         return name.equals(otherName);
42 |     }
43 | 
44 |     @Override
45 |     public String toString() {
46 |         return this.name;
47 |     }
48 | 
49 | }
50 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/caep/CAEPBaseEvent.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.caep;
 8 | 
 9 | import com.nimbusds.jose.shaded.json.JSONObject;
10 | import com.sailpoint.sse.model.SSEvent;
11 | import com.sailpoint.sse.model.SSEventTypes;
12 | import com.sailpoint.sse.model.ValidationException;
13 | import com.sailpoint.ietf.subjectidentifiers.model.SIValidationException;
14 | 
15 | import java.text.ParseException;
16 | 
17 | public abstract class CAEPBaseEvent extends SSEvent {
18 |     private static final String EVENT_TIMESTAMP_MEMBER = "event_timestamp";
19 |     private static final String INITIATING_ENTITY_MEMBER = "initiating_entity";
20 |     private static final String REASON_ADMIN_MEMBER = "reason_admin";
21 |     private static final String REASON_USER_MEMBER = "reason_user";
22 | 
23 |     protected CAEPBaseEvent() { }
24 | 
25 |     public JSONObject getEventMembers() throws ValidationException {
26 |         final SSEventTypes eventType = getEventType();
27 |         if (null == eventType) {
28 |             /* Unknown event type, not instantiated via a normal constructor. */
29 |             throw new ValidationException("CAEP Events must set eventType in their constructor");
30 |         }
31 | 
32 |         JSONObject members = (JSONObject) get(eventType.toString());
33 |         if (null == members) {
34 |             throw new ValidationException("CAEP Events must have a container Map whose key is the event type URI");
35 |         }
36 |         return members;
37 |     }
38 | 
39 |     public void validateEventTimestamp() throws ValidationException {
40 |         JSONObject members = getEventMembers();
41 | 
42 |         Object eventTimestamp = members.get(EVENT_TIMESTAMP_MEMBER);
43 |         if (null == eventTimestamp) {
44 |             // event_timestamp is an optional member. Ignore it's absence.
45 |             return;
46 |         }
47 | 
48 |         if (!(eventTimestamp instanceof Long)) {
49 |             throw new ValidationException("CAEP Events event_timestamp must be of type Long.");
50 |         }
51 |         Long eventTimestampL = (Long) eventTimestamp;
52 |         if (eventTimestampL < 0) {
53 |             throw new ValidationException("CAEP Events event_timestamp must be > 0.");
54 |         }
55 |     }
56 | 
57 |     @Override
58 |     public void validate() throws ParseException, SIValidationException, ValidationException {
59 |         super.validate();
60 |         validateEventTimestamp();
61 |     }
62 | 
63 |     public abstract static class Builder>
64 |             extends SSEvent.Builder {
65 | 
66 |         protected Builder(final SSEventTypes eventType) {
67 |             super(eventType);
68 |         }
69 | 
70 |         // Timestamp in milliseconds from epoch
71 |         public B eventTimestamp(final long eventTimestamp) {
72 |             members.put(EVENT_TIMESTAMP_MEMBER, eventTimestamp);
73 |             return thisObj;
74 |         }
75 | 
76 |         public B initiatingEntity(final CAEPInitiatingEntity entity) {
77 |             members.put(INITIATING_ENTITY_MEMBER, entity.toString());
78 |             return thisObj;
79 |         }
80 | 
81 |         public B reasonAdmin(final String s) {
82 |             members.put(REASON_ADMIN_MEMBER, s);
83 |             return thisObj;
84 |         }
85 | 
86 |         public B reasonUser(final String s) {
87 |             members.put(REASON_USER_MEMBER, s);
88 |             return thisObj;
89 |         }
90 | 
91 |     }
92 | 
93 | 
94 | }
95 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/caep/CAEPChangeType.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.caep;
 8 | 
 9 | import java.util.HashMap;
10 | import java.util.Map;
11 | 
12 | public enum CAEPChangeType {
13 | 
14 |     CREATE("create"),
15 |     REVOKE("revoke"),
16 |     UPDATE("update"),
17 |     DELETE("delete");
18 | 
19 |     private static final Map BY_NAME = new HashMap<>();
20 | 
21 |     static {
22 |         for (CAEPChangeType t : values()) {
23 |             BY_NAME.put(t.name, t);
24 |         }
25 |     }
26 | 
27 |     private final String name;
28 | 
29 |     CAEPChangeType(final String s) {
30 |         name = s;
31 |     }
32 | 
33 |     public static CAEPChangeType valueOfLabel(String name) {
34 |         return BY_NAME.get(name);
35 |     }
36 | 
37 |     public static boolean contains(final String name) {
38 |         return BY_NAME.containsKey(name);
39 |     }
40 | 
41 |     public boolean equalsName(String otherName) {
42 |         return name.equals(otherName);
43 |     }
44 | 
45 |     @Override
46 |     public String toString() {
47 |         return this.name;
48 |     }
49 | 
50 | }
51 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/caep/CAEPComplianceStatus.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.caep;
 8 | 
 9 | import java.util.HashMap;
10 | import java.util.Map;
11 | 
12 | public enum CAEPComplianceStatus {
13 | 
14 |     COMPLIANT("compliant"),
15 |     NOT_COMPLIANT("not-compliant");
16 | 
17 |     private static final Map BY_NAME = new HashMap<>();
18 | 
19 |     static {
20 |         for (CAEPComplianceStatus t : values()) {
21 |             BY_NAME.put(t.name, t);
22 |         }
23 |     }
24 | 
25 |     private final String name;
26 | 
27 |     CAEPComplianceStatus(final String s) {
28 |         name = s;
29 |     }
30 | 
31 |     public static CAEPComplianceStatus valueOfLabel(final String name) {
32 |         return BY_NAME.get(name);
33 |     }
34 | 
35 |     public static boolean contains(final String name) {
36 |         return BY_NAME.containsKey(name);
37 |     }
38 | 
39 |     public boolean equalsName(final String otherName) {
40 |         return name.equals(otherName);
41 |     }
42 | 
43 |     @Override
44 |     public String toString() {
45 |         return this.name;
46 |     }
47 | 
48 | }
49 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/caep/CAEPCredentialChange.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.caep;
 8 | 
 9 | import com.sailpoint.ietf.subjectidentifiers.model.SIValidationException;
10 | import com.sailpoint.sse.model.SSEventTypes;
11 | import com.sailpoint.sse.model.Utils;
12 | import com.sailpoint.sse.model.ValidationException;
13 | 
14 | import java.text.ParseException;
15 | 
16 | public class CAEPCredentialChange extends CAEPBaseEvent {
17 | 
18 |     private static final String CREDENTIAL_TYPE = "credential_type";
19 |     private static final String CHANGE_TYPE = "change_type";
20 |     private static final String FRIENDLY_NAME = "friendly_name";
21 |     private static final String X509_ISSUER = "x509_issuer";
22 |     private static final String X509_SERIAL = "x509_serial";
23 |     private static final String FIDO2_AAGUID = "fido2_aaguid";
24 | 
25 |     @Override
26 |     public void validate() throws ParseException, SIValidationException, ValidationException {
27 |         super.validate();
28 |         Utils.validateMember(this, CREDENTIAL_TYPE, CAEPCredentialType.class);
29 |         Utils.validateMember(this, CHANGE_TYPE, CAEPChangeType.class);
30 |     }
31 | 
32 |     public static class Builder extends CAEPBaseEvent.Builder {
33 | 
34 | 
35 |         public Builder() {
36 |             super(SSEventTypes.CAEP_CREDENTIAL_CHANGE);
37 |         }
38 | 
39 |         @Override
40 |         protected CAEPCredentialChange createObj() {
41 |             return new CAEPCredentialChange();
42 |         }
43 | 
44 |         protected CAEPCredentialChange.Builder getThis() {
45 |             return this;
46 |         }
47 | 
48 |         public Builder credentialType(final CAEPCredentialType type) {
49 |             super.members.put(CREDENTIAL_TYPE, type.toString());
50 |             return thisObj;
51 |         }
52 | 
53 |         public Builder changeType(final CAEPChangeType type) {
54 |             super.members.put(CHANGE_TYPE, type.toString());
55 |             return thisObj;
56 |         }
57 | 
58 |         public Builder friendlyName(final String name) {
59 |             super.members.put(FRIENDLY_NAME, name);
60 |             return thisObj;
61 |         }
62 | 
63 |         public Builder x509Issuer(final String issuer) {
64 |             super.members.put(X509_ISSUER, issuer);
65 |             return thisObj;
66 |         }
67 | 
68 |         public Builder x509Serial(final String serial) {
69 |             super.members.put(X509_SERIAL, serial);
70 |             return thisObj;
71 |         }
72 | 
73 |         public Builder fido2AAGuid(final String guid) {
74 |             super.members.put(FIDO2_AAGUID, guid);
75 |             return thisObj;
76 |         }
77 | 
78 |     }
79 | 
80 | }
81 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/caep/CAEPCredentialType.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.caep;
 8 | 
 9 | import java.util.HashMap;
10 | import java.util.Map;
11 | 
12 | public enum CAEPCredentialType {
13 | 
14 |     PASSWORD("password"),
15 |     PIN("pin"),
16 |     X509("x509"),
17 |     FIDO2_PLATFORM("fido2-platform"),
18 |     FIDO2_ROAMING("fido2-roaming"),
19 |     FIDO2_U2F("fido-u2f"),
20 |     VERIFIABLE_CREDENTIAL("verifiable-credential"),
21 |     PHONE_VOICE("phone-voice"),
22 |     PHONE_SMS("phone-sms"),
23 |     APP("app");
24 | 
25 |     private static final Map BY_NAME = new HashMap<>();
26 | 
27 |     static {
28 |         for (CAEPCredentialType t : values()) {
29 |             BY_NAME.put(t.name, t);
30 |         }
31 |     }
32 | 
33 |     private final String name;
34 | 
35 |     CAEPCredentialType(final String s) {
36 |         name = s;
37 |     }
38 | 
39 |     public static CAEPCredentialType valueOfLabel(final String name) {
40 |         return BY_NAME.get(name);
41 |     }
42 | 
43 |     public static boolean contains(final String name) {
44 |         return BY_NAME.containsKey(name);
45 |     }
46 | 
47 |     public boolean equalsName(final String otherName) {
48 |         return name.equals(otherName);
49 |     }
50 | 
51 |     @Override
52 |     public String toString() {
53 |         return this.name;
54 |     }
55 | 
56 | }
57 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/caep/CAEPDeviceComplianceChange.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.caep;
 8 | 
 9 | import com.sailpoint.ietf.subjectidentifiers.model.SIValidationException;
10 | import com.sailpoint.sse.model.SSEventTypes;
11 | import com.sailpoint.sse.model.Utils;
12 | import com.sailpoint.sse.model.ValidationException;
13 | 
14 | import java.text.ParseException;
15 | 
16 | public class CAEPDeviceComplianceChange extends CAEPBaseEvent {
17 | 
18 |     private static final String PREVIOUS_STATUS = "previous_status";
19 |     private static final String CURRENT_STATUS = "current_status";
20 | 
21 |     @Override
22 |     public void validate() throws ParseException, SIValidationException, ValidationException {
23 |         super.validate();
24 |         Utils.validateMember(this, PREVIOUS_STATUS, CAEPComplianceStatus.class);
25 |         Utils.validateMember(this, CURRENT_STATUS, CAEPComplianceStatus.class);
26 |     }
27 | 
28 |     public static class Builder extends CAEPBaseEvent.Builder {
29 | 
30 |         public Builder() {
31 |             super(SSEventTypes.CAEP_DEVICE_COMPLIANCE_CHANGE);
32 |         }
33 | 
34 |         protected CAEPDeviceComplianceChange createObj() {
35 |             return new CAEPDeviceComplianceChange();
36 |         }
37 | 
38 |         protected CAEPDeviceComplianceChange.Builder getThis() {
39 |             return this;
40 |         }
41 | 
42 |         public Builder previousStatus(final CAEPComplianceStatus status) {
43 |             members.put(PREVIOUS_STATUS, status.toString());
44 |             return thisObj;
45 |         }
46 | 
47 |         public Builder currentStatus(final CAEPComplianceStatus status) {
48 |             members.put(CURRENT_STATUS, status.toString());
49 |             return thisObj;
50 |         }
51 | 
52 |     }
53 | 
54 | }
55 | 
56 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/caep/CAEPIPAddrChanged.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.caep;
 8 | 
 9 | import com.sailpoint.sse.model.SSEventTypes;
10 | 
11 | public class CAEPIPAddrChanged extends CAEPBaseEvent {
12 |     private static final String IPADDRESS_MEMBER = "ip_address";
13 | 
14 |     public static class Builder extends CAEPBaseEvent.Builder {
15 | 
16 | 
17 |         public Builder() {
18 |             super(SSEventTypes.CAEP_IPADDR_CHANGED);
19 |         }
20 | 
21 |         protected CAEPIPAddrChanged createObj() {
22 |             return new CAEPIPAddrChanged();
23 |         }
24 | 
25 |         protected CAEPIPAddrChanged.Builder getThis() {
26 |             return this;
27 |         }
28 | 
29 |         public Builder ipAddress(final String ipAddress) {
30 |             members.put(IPADDRESS_MEMBER, ipAddress);
31 |             return thisObj;
32 |         }
33 |     }
34 | 
35 | 
36 | }
37 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/caep/CAEPInitiatingEntity.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.caep;
 8 | 
 9 | import java.util.HashMap;
10 | import java.util.Map;
11 | 
12 | public enum CAEPInitiatingEntity {
13 |     ADMIN("admin"),
14 |     USER("user"),
15 |     POLICY("policy"),
16 |     SYSTEM("system");
17 | 
18 |     private static final Map BY_NAME = new HashMap<>();
19 | 
20 |     static {
21 |         for (CAEPInitiatingEntity t : values()) {
22 |             BY_NAME.put(t.name, t);
23 |         }
24 |     }
25 | 
26 |     private final String name;
27 | 
28 |     CAEPInitiatingEntity(final String s) {
29 |         name = s;
30 |     }
31 | 
32 |     public static CAEPInitiatingEntity valueOfLabel(final String name) {
33 |         return BY_NAME.get(name);
34 |     }
35 | 
36 |     public static boolean contains(final String name) {
37 |         return BY_NAME.containsKey(name);
38 |     }
39 | 
40 |     public boolean equalsName(final String otherName) {
41 |         return name.equals(otherName);
42 |     }
43 | 
44 |     @Override
45 |     public String toString() {
46 |         return this.name;
47 |     }
48 | 
49 | 
50 | }
51 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/caep/CAEPSessionRevoked.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.caep;
 8 | 
 9 | import com.sailpoint.sse.model.SSEventTypes;
10 | 
11 | public class CAEPSessionRevoked extends CAEPBaseEvent {
12 | 
13 |     public static class Builder extends CAEPBaseEvent.Builder {
14 | 
15 |         public Builder() {
16 |             super(SSEventTypes.CAEP_SESSION_REVOKED);
17 |         }
18 | 
19 |         protected CAEPSessionRevoked createObj() {
20 |             return new CAEPSessionRevoked();
21 |         }
22 | 
23 |         protected CAEPSessionRevoked.Builder getThis() {
24 |             return this;
25 |         }
26 |     }
27 | }
28 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/caep/CAEPStreamUpdated.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.caep;
 8 | 
 9 | import com.sailpoint.sse.model.SSEventTypes;
10 | 
11 | public class CAEPStreamUpdated extends CAEPBaseEvent {
12 | 
13 |     public static class Builder extends CAEPBaseEvent.Builder {
14 | 
15 |         public Builder() {
16 |             super(SSEventTypes.SSE_STREAM_UPDATED);
17 |         }
18 | 
19 |         protected CAEPStreamUpdated createObj() {
20 |             return new CAEPStreamUpdated();
21 |         }
22 | 
23 |         protected CAEPStreamUpdated.Builder getThis() {
24 |             return this;
25 |         }
26 |     }
27 | }
28 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/caep/CAEPTokenClaimsChange.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.caep;
 8 | 
 9 | import com.nimbusds.jose.shaded.json.JSONObject;
10 | import com.sailpoint.ietf.subjectidentifiers.model.SIValidationException;
11 | import com.sailpoint.sse.model.SSEventTypes;
12 | import com.sailpoint.sse.model.ValidationException;
13 | 
14 | import java.text.ParseException;
15 | 
16 | public class CAEPTokenClaimsChange extends CAEPBaseEvent {
17 | 
18 |     private static final String CLAIMS = "claims";
19 | 
20 |     @Override
21 |     public void validate() throws ParseException, SIValidationException, ValidationException {
22 |         super.validate();
23 |         JSONObject members = getEventMembers();
24 |         final Object o = members.get(CLAIMS);
25 |         if (null == o) {
26 |             throw new ValidationException(this.getClass().getName() + " member " + CLAIMS + " is missing or null.");
27 |         }
28 |     }
29 | 
30 |     public static class Builder extends CAEPBaseEvent.Builder {
31 | 
32 |         public Builder() {
33 |             super(SSEventTypes.CAEP_TOKEN_CLAIMS_CHANGE);
34 |         }
35 | 
36 |         protected CAEPTokenClaimsChange createObj() {
37 |             return new CAEPTokenClaimsChange();
38 |         }
39 | 
40 |         protected CAEPTokenClaimsChange.Builder getThis() {
41 |             return this;
42 |         }
43 | 
44 |         public CAEPTokenClaimsChange.Builder claims(final JSONObject newClaims) {
45 |             members.put(CLAIMS, newClaims);
46 |             return thisObj;
47 |         }
48 | 
49 | 
50 |     }
51 | 
52 | 
53 | }
54 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/caep/NISTAuthenticatorAssuranceLevel.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.caep;
 8 | 
 9 | import java.util.HashMap;
10 | import java.util.Map;
11 | 
12 | public enum NISTAuthenticatorAssuranceLevel {
13 | 
14 |     NIST_AAL1("nist-aal1"),
15 |     NIST_AAL2("nist-aal2"),
16 |     NIST_AAL3("nist-aal3");
17 | 
18 |     private static final Map BY_NAME = new HashMap<>();
19 | 
20 |     static {
21 |         for (NISTAuthenticatorAssuranceLevel t : values()) {
22 |             BY_NAME.put(t.name, t);
23 |         }
24 |     }
25 | 
26 |     private final String name;
27 | 
28 |     NISTAuthenticatorAssuranceLevel(final String s) {
29 |         name = s;
30 |     }
31 | 
32 |     public static NISTAuthenticatorAssuranceLevel valueOfLabel(final String name) {
33 |         return BY_NAME.get(name);
34 |     }
35 | 
36 |     public static boolean contains(final String name) {
37 |         return BY_NAME.containsKey(name);
38 |     }
39 | 
40 |     public boolean equalsName(final String otherName) {
41 |         return name.equals(otherName);
42 |     }
43 | 
44 |     @Override
45 |     public String toString() {
46 |         return this.name;
47 |     }
48 | 
49 | 
50 | }
51 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/risc/RISCAccountCredentialChangeRequired.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.risc;
 8 | 
 9 | import com.sailpoint.sse.model.SSEvent;
10 | import com.sailpoint.sse.model.SSEventTypes;
11 | 
12 | public class RISCAccountCredentialChangeRequired extends SSEvent {
13 | 
14 |     public static class Builder extends SSEvent.Builder {
15 | 
16 |         public Builder() {
17 |             super(SSEventTypes.RISC_ACCOUNT_CREDENTIAL_CHANGE_REQUIRED);
18 |         }
19 | 
20 |         @Override
21 |         protected RISCAccountCredentialChangeRequired createObj() {
22 |             return new RISCAccountCredentialChangeRequired();
23 |         }
24 | 
25 |         protected RISCAccountCredentialChangeRequired.Builder getThis() {
26 |             return this;
27 |         }
28 |     }
29 | 
30 | }
31 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/risc/RISCAccountDisabled.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.risc;
 8 | 
 9 | import com.sailpoint.ietf.subjectidentifiers.model.SIValidationException;
10 | import com.sailpoint.sse.model.SSEvent;
11 | import com.sailpoint.sse.model.SSEventTypes;
12 | import com.sailpoint.sse.model.Utils;
13 | import com.sailpoint.sse.model.ValidationException;
14 | 
15 | import java.text.ParseException;
16 | 
17 | public class RISCAccountDisabled extends SSEvent {
18 | 
19 |     private static final String REASON_MEMBER = "reason";
20 | 
21 |     @Override
22 |     public void validate() throws ParseException, SIValidationException, ValidationException {
23 |         super.validate();
24 |         Utils.validateMember(this, REASON_MEMBER, RISCAccountDisabledReasons.class);
25 |     }
26 | 
27 |     public static class Builder extends SSEvent.Builder {
28 | 
29 |         public Builder() {
30 |             super(SSEventTypes.RISC_ACCOUNT_DISABLED);
31 |         }
32 | 
33 |         @Override
34 |         protected RISCAccountDisabled createObj() {
35 |             return new RISCAccountDisabled();
36 |         }
37 | 
38 |         protected RISCAccountDisabled.Builder getThis() {
39 |             return this;
40 |         }
41 | 
42 |         public RISCAccountDisabled.Builder reason(final RISCAccountDisabledReasons reason) {
43 |             members.put(REASON_MEMBER, reason.toString());
44 |             return thisObj;
45 |         }
46 | 
47 |     }
48 | 
49 | }
50 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/risc/RISCAccountDisabledReasons.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.risc;
 8 | 
 9 | import java.util.HashMap;
10 | import java.util.Map;
11 | 
12 | public enum RISCAccountDisabledReasons {
13 | 
14 |     HIJACKING("hijacking"),
15 |     BULK_ACCOUNT("bulk-account");
16 | 
17 |     private static final Map BY_NAME = new HashMap<>();
18 | 
19 |     static {
20 |         for (RISCAccountDisabledReasons t : values()) {
21 |             BY_NAME.put(t.name, t);
22 |         }
23 |     }
24 | 
25 |     private final String name;
26 | 
27 |     RISCAccountDisabledReasons(final String s) {
28 |         name = s;
29 |     }
30 | 
31 |     public static RISCAccountDisabledReasons valueOfLabel(final String name) {
32 |         return BY_NAME.get(name);
33 |     }
34 | 
35 |     public static boolean contains(final String name) {
36 |         return BY_NAME.containsKey(name);
37 |     }
38 | 
39 |     public boolean equalsName(final String otherName) {
40 |         return name.equals(otherName);
41 |     }
42 | 
43 |     @Override
44 |     public String toString() {
45 |         return this.name;
46 |     }
47 | }
48 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/risc/RISCAccountEnabled.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.risc;
 8 | 
 9 | import com.sailpoint.sse.model.SSEvent;
10 | import com.sailpoint.sse.model.SSEventTypes;
11 | 
12 | public class RISCAccountEnabled extends SSEvent {
13 | 
14 |     public static class Builder extends SSEvent.Builder {
15 | 
16 |         public Builder() {
17 |             super(SSEventTypes.RISC_ACCOUNT_ENABLED);
18 |         }
19 | 
20 |         @Override
21 |         protected RISCAccountEnabled createObj() {
22 |             return new RISCAccountEnabled();
23 |         }
24 | 
25 |         protected RISCAccountEnabled.Builder getThis() {
26 |             return this;
27 |         }
28 |     }
29 | 
30 | }
31 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/risc/RISCAccountPurged.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.risc;
 8 | 
 9 | import com.sailpoint.sse.model.SSEvent;
10 | import com.sailpoint.sse.model.SSEventTypes;
11 | 
12 | public class RISCAccountPurged extends SSEvent {
13 | 
14 |     public static class Builder extends SSEvent.Builder {
15 | 
16 |         public Builder() {
17 |             super(SSEventTypes.RISC_ACCOUNT_PURGED);
18 |         }
19 | 
20 |         @Override
21 |         protected RISCAccountPurged createObj() {
22 |             return new RISCAccountPurged();
23 |         }
24 | 
25 |         protected RISCAccountPurged.Builder getThis() {
26 |             return this;
27 |         }
28 |     }
29 | 
30 | }
31 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/risc/RISCIdentifierChanged.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.risc;
 8 | 
 9 | import com.sailpoint.ietf.subjectidentifiers.model.SIValidationException;
10 | import com.sailpoint.sse.model.SSEvent;
11 | import com.sailpoint.sse.model.SSEventTypes;
12 | import com.sailpoint.sse.model.ValidationException;
13 | 
14 | import java.text.ParseException;
15 | 
16 | public class RISCIdentifierChanged extends SSEvent {
17 | 
18 |     private static final String NEW_VALUE_MEMBER = "new-value";
19 | 
20 |     @Override
21 |     public void validate() throws ParseException, SIValidationException, ValidationException {
22 |         super.validate();
23 |         Object oNewValue = getMember(NEW_VALUE_MEMBER);
24 |         if (null == oNewValue) {
25 |             throw new ValidationException(String.format("RISC Identifier Changed event member %s must be present.", NEW_VALUE_MEMBER));
26 |         }
27 |         if (!(oNewValue instanceof String)) {
28 |             throw new ValidationException(String.format("RISC Identifier Changed event member %s must be a String", NEW_VALUE_MEMBER));
29 |         }
30 |     }
31 | 
32 |     public static class Builder extends SSEvent.Builder {
33 | 
34 |         public Builder() {
35 |             super(SSEventTypes.RISC_IDENTIFIER_CHANGED);
36 |         }
37 | 
38 |         @Override
39 |         protected RISCIdentifierChanged createObj() {
40 |             return new RISCIdentifierChanged();
41 |         }
42 | 
43 |         protected RISCIdentifierChanged.Builder getThis() {
44 |             return this;
45 |         }
46 | 
47 |         public RISCIdentifierChanged.Builder newValue(final String value) {
48 |             members.put(NEW_VALUE_MEMBER, value);
49 |             return thisObj;
50 |         }
51 | 
52 |     }
53 | 
54 | }
55 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/risc/RISCIdentifierRecycled.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.risc;
 8 | 
 9 | import com.sailpoint.ietf.subjectidentifiers.model.SIValidationException;
10 | import com.sailpoint.ietf.subjectidentifiers.model.SubjectIdentifier;
11 | import com.sailpoint.ietf.subjectidentifiers.model.SubjectIdentifierFormats;
12 | import com.sailpoint.ietf.subjectidentifiers.model.SubjectIdentifierMembers;
13 | import com.sailpoint.sse.model.SSEvent;
14 | import com.sailpoint.sse.model.SSEventTypes;
15 | import com.sailpoint.sse.model.ValidationException;
16 | 
17 | import java.text.ParseException;
18 | 
19 | public class RISCIdentifierRecycled extends SSEvent {
20 | 
21 |     /*
22 |      *  The subject type MUST be either "email" or "phone".
23 |      */
24 |     @Override
25 |     public void validate() throws ParseException, SIValidationException, ValidationException {
26 |         super.validate();
27 |         SubjectIdentifier subj = getSubjectIdentifier();
28 |         final String type = subj.getString(SubjectIdentifierMembers.FORMAT);
29 |         if (SubjectIdentifierFormats.EMAIL.equalsName(type) || SubjectIdentifierFormats.PHONE_NUMBER.equalsName(type)) {
30 |             return;
31 |         }
32 |         throw new ValidationException("RISC Identifier Recycled event must have a subject_type of email or phone_number");
33 |     }
34 | 
35 |     public static class Builder extends SSEvent.Builder {
36 | 
37 |         public Builder() {
38 |             super(SSEventTypes.RISC_IDENTIFIER_RECYCLED);
39 |         }
40 | 
41 |         @Override
42 |         protected RISCIdentifierRecycled createObj() {
43 |             return new RISCIdentifierRecycled();
44 |         }
45 | 
46 |         protected RISCIdentifierRecycled.Builder getThis() {
47 |             return this;
48 |         }
49 |     }
50 | 
51 | }
52 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/risc/RISCOptIn.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.risc;
 8 | 
 9 | import com.sailpoint.sse.model.SSEvent;
10 | import com.sailpoint.sse.model.SSEventTypes;
11 | 
12 | public class RISCOptIn extends SSEvent {
13 | 
14 |     public static class Builder extends SSEvent.Builder {
15 | 
16 |         public Builder() {
17 |             super(SSEventTypes.RISC_OPT_IN);
18 |         }
19 | 
20 |         @Override
21 |         protected RISCOptIn createObj() {
22 |             return new RISCOptIn();
23 |         }
24 | 
25 |         protected RISCOptIn.Builder getThis() {
26 |             return this;
27 |         }
28 |     }
29 | 
30 | }
31 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/risc/RISCOptOutCancelled.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.risc;
 8 | 
 9 | import com.sailpoint.sse.model.SSEvent;
10 | import com.sailpoint.sse.model.SSEventTypes;
11 | 
12 | public class RISCOptOutCancelled extends SSEvent {
13 | 
14 |     public static class Builder extends SSEvent.Builder {
15 | 
16 |         public Builder() {
17 |             super(SSEventTypes.RISC_OPT_OUT_CANCELLED);
18 |         }
19 | 
20 |         @Override
21 |         protected RISCOptOutCancelled createObj() {
22 |             return new RISCOptOutCancelled();
23 |         }
24 | 
25 |         protected RISCOptOutCancelled.Builder getThis() {
26 |             return this;
27 |         }
28 |     }
29 | 
30 | }
31 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/risc/RISCOptOutEffective.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.risc;
 8 | 
 9 | import com.sailpoint.sse.model.SSEvent;
10 | import com.sailpoint.sse.model.SSEventTypes;
11 | 
12 | public class RISCOptOutEffective extends SSEvent {
13 | 
14 |     public static class Builder extends SSEvent.Builder {
15 | 
16 |         public Builder() {
17 |             super(SSEventTypes.RISC_OPT_OUT_EFFECTIVE);
18 |         }
19 | 
20 |         @Override
21 |         protected RISCOptOutEffective createObj() {
22 |             return new RISCOptOutEffective();
23 |         }
24 | 
25 |         protected RISCOptOutEffective.Builder getThis() {
26 |             return this;
27 |         }
28 |     }
29 | 
30 | }
31 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/risc/RISCOptOutInitiated.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.risc;
 8 | 
 9 | import com.sailpoint.sse.model.SSEvent;
10 | import com.sailpoint.sse.model.SSEventTypes;
11 | 
12 | public class RISCOptOutInitiated extends SSEvent {
13 | 
14 |     public static class Builder extends SSEvent.Builder {
15 | 
16 |         public Builder() {
17 |             super(SSEventTypes.RISC_OPT_OUT_INITIATED);
18 |         }
19 | 
20 |         @Override
21 |         protected RISCOptOutInitiated createObj() {
22 |             return new RISCOptOutInitiated();
23 |         }
24 | 
25 |         protected RISCOptOutInitiated.Builder getThis() {
26 |             return this;
27 |         }
28 |     }
29 | 
30 | }
31 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/risc/RISCRecoveryActivated.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.risc;
 8 | 
 9 | import com.sailpoint.sse.model.SSEvent;
10 | import com.sailpoint.sse.model.SSEventTypes;
11 | 
12 | public class RISCRecoveryActivated extends SSEvent {
13 | 
14 |     public static class Builder extends SSEvent.Builder {
15 | 
16 |         public Builder() {
17 |             super(SSEventTypes.RISC_RECOVERY_ACTIVATED);
18 |         }
19 | 
20 |         @Override
21 |         protected RISCRecoveryActivated createObj() {
22 |             return new RISCRecoveryActivated();
23 |         }
24 | 
25 |         protected RISCRecoveryActivated.Builder getThis() {
26 |             return this;
27 |         }
28 |     }
29 | 
30 | }
31 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/risc/RISCRecoveryInformationChanged.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.risc;
 8 | 
 9 | import com.sailpoint.sse.model.SSEvent;
10 | import com.sailpoint.sse.model.SSEventTypes;
11 | 
12 | public class RISCRecoveryInformationChanged extends SSEvent {
13 | 
14 |     public static class Builder extends SSEvent.Builder {
15 | 
16 |         public Builder() {
17 |             super(SSEventTypes.RISC_RECOVERY_INFORMATION_CHANGED);
18 |         }
19 | 
20 |         @Override
21 |         protected RISCRecoveryInformationChanged createObj() {
22 |             return new RISCRecoveryInformationChanged();
23 |         }
24 | 
25 |         protected RISCRecoveryInformationChanged.Builder getThis() {
26 |             return this;
27 |         }
28 |     }
29 | 
30 | }
31 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/risc/RISCSessionsRevoked.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.risc;
 8 | 
 9 | import com.sailpoint.sse.model.SSEvent;
10 | import com.sailpoint.sse.model.SSEventTypes;
11 | 
12 | public class RISCSessionsRevoked extends SSEvent {
13 | 
14 |     public static class Builder extends SSEvent.Builder {
15 | 
16 |         public Builder() {
17 |             super(SSEventTypes.RISC_SESSIONS_REVOKED);
18 |         }
19 | 
20 |         @Override
21 |         protected RISCSessionsRevoked createObj() {
22 |             return new RISCSessionsRevoked();
23 |         }
24 | 
25 |         protected RISCSessionsRevoked.Builder getThis() {
26 |             return this;
27 |         }
28 |     }
29 | 
30 | }
31 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/sse/SSEStreamUpdated.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.sse;
 8 | 
 9 | import com.sailpoint.sse.model.*;
10 | 
11 | public class SSEStreamUpdated extends SSEvent {
12 | 
13 |     private static final String STATUS_MEMBER = "status";
14 | 
15 |     public static class Builder extends SSEvent.Builder {
16 | 
17 |         public Builder() {
18 |             super(SSEventTypes.SSE_STREAM_UPDATED);
19 |         }
20 | 
21 |         @Override
22 |         protected SSEStreamUpdated createObj() {
23 |             return new SSEStreamUpdated();
24 |         }
25 | 
26 |         protected SSEStreamUpdated.Builder getThis() {
27 |             return this;
28 |         }
29 | 
30 |         public Builder status(final StreamStatus status) {
31 |             members.put(STATUS_MEMBER, status.toString());
32 |             return thisObj;
33 |         }
34 | 
35 |     }
36 | 
37 |     @Override
38 |     public void validate() throws ValidationException {
39 |         super.validateEventTypeName();
40 |         Utils.validateMember(this, STATUS_MEMBER, StreamStatus.class);
41 |     }
42 | 
43 | }
44 | 
--------------------------------------------------------------------------------
/src/main/java/com/sailpoint/sse/model/sse/SSEVerification.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model.sse;
 8 | 
 9 | import com.sailpoint.sse.model.*;
10 | 
11 | public class SSEVerification extends SSEvent {
12 | 
13 |     private static final String STATE_MEMBER = "state";
14 | 
15 |     @Override
16 |     public void validate() throws ValidationException {
17 |         super.validateEventTypeName();
18 |     }
19 | 
20 | 
21 | 
22 |     public static class Builder extends SSEvent.Builder {
23 | 
24 |         public Builder() {
25 |             super(SSEventTypes.SSE_VERIFICATION);
26 |         }
27 | 
28 |         @Override
29 |         protected SSEVerification createObj() {
30 |             return new SSEVerification();
31 |         }
32 | 
33 |         protected SSEVerification.Builder getThis() {
34 |             return this;
35 |         }
36 | 
37 |         public Builder state(final String state) {
38 |             super.members.put(STATE_MEMBER, state);
39 |             return thisObj;
40 |         }
41 |     }
42 | 
43 | }
44 | 
--------------------------------------------------------------------------------
/src/main/java/module-info.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | module com.sailpoint.sse.model {
 8 |     exports com.sailpoint.sse.model;
 9 |     exports com.sailpoint.sse.model.caep;
10 |     exports com.sailpoint.sse.model.risc;
11 |     exports com.sailpoint.sse.model.sse;
12 |     requires transitive com.nimbusds.jose.jwt;
13 |     requires com.sailpoint.ietf.subjectidentifiers.model;
14 | }
15 | 
--------------------------------------------------------------------------------
/src/test/java/com/sailpoint/sse/model/CAEPAssuranceLevelChangeTest.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model;
 8 | 
 9 | import com.nimbusds.jose.shaded.json.JSONObject;
10 | import com.nimbusds.jose.util.JSONObjectUtils;
11 | import com.nimbusds.jwt.JWTClaimsSet;
12 | import com.nimbusds.jwt.util.DateUtils;
13 | import com.sailpoint.sse.model.caep.CAEPAssuranceLevelChange;
14 | import com.sailpoint.sse.model.caep.CAEPAssuranceLevelChangeDirection;
15 | import com.sailpoint.sse.model.caep.CAEPInitiatingEntity;
16 | import com.sailpoint.sse.model.caep.NISTAuthenticatorAssuranceLevel;
17 | import com.sailpoint.ietf.subjectidentifiers.model.IssSubSubjectIdentifier;
18 | import com.sailpoint.ietf.subjectidentifiers.model.SIValidationException;
19 | import org.junit.Test;
20 | 
21 | import java.text.ParseException;
22 | 
23 | import static org.junit.Assert.assertEquals;
24 | 
25 | public class CAEPAssuranceLevelChangeTest {
26 |     /**
27 |      * Figure 9: Example: Assurance Level Increase - Simple Subject +
28 |      *                               optional claims
29 |      */
30 | 
31 |     @Test
32 |     public void Figure9() throws ParseException, SIValidationException, ValidationException {
33 |         IssSubSubjectIdentifier subj = new IssSubSubjectIdentifier.Builder()
34 |                 .issuer("https://idp.example.com/3456789/")
35 |                 .subject("jane.smith@example.com")
36 |                 .build();
37 | 
38 |         CAEPAssuranceLevelChange evt = new CAEPAssuranceLevelChange.Builder()
39 |                 .currentLevel(NISTAuthenticatorAssuranceLevel.NIST_AAL2)
40 |                 .previousLevel(NISTAuthenticatorAssuranceLevel.NIST_AAL1)
41 |                 .changeDirection(CAEPAssuranceLevelChangeDirection.INCREASE)
42 |                 .eventTimestamp(1615304991643L)
43 |                 .initiatingEntity(CAEPInitiatingEntity.USER)
44 |                 .subject(subj)
45 |                 .build();
46 | 
47 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
48 |                 .issuer("https://idp.example.com/3456789/")
49 |                 .jwtID("07efd930f0977e4fcc1149a733ce7f78")
50 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1615305159L))
51 |                 .audience("https://sp.example2.net/caep")
52 |                 .claim(SEToken.EVENTS_CLAIM, evt)
53 |                 .build();
54 | 
55 |         final String figure_text = "   {\n" +
56 |                 "       \"iss\": \"https://idp.example.com/3456789/\",\n" +
57 |                 "       \"jti\": \"07efd930f0977e4fcc1149a733ce7f78\",\n" +
58 |                 "       \"iat\": 1615305159,\n" +
59 |                 "       \"aud\": \"https://sp.example2.net/caep\",\n" +
60 |                 "       \"events\": {\n" +
61 |                 "           \"https://schemas.openid.net/secevent/caep/event-type/assurance-level-change\": {\n" +
62 |                 "               \"subject\": {\n" +
63 |                 "                   \"format\": \"iss_sub\",\n" +
64 |                 "                   \"iss\": \"https://idp.example.com/3456789/\",\n" +
65 |                 "                   \"sub\": \"jane.smith@example.com\"\n" +
66 |                 "               },\n" +
67 |                 "               \"current_level\": \"nist-aal2\",\n" +
68 |                 "               \"previous_level\": \"nist-aal1\",\n" +
69 |                 "               \"change_direction\": \"increase\",\n" +
70 |                 "               \"initiating_entity\": \"user\",\n" +
71 |                 "               \"event_timestamp\": 1615304991643\n" +
72 |                 "           }\n" +
73 |                 "       }\n" +
74 |                 "   }\n";
75 | 
76 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
77 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
78 |         assertEquals(figureJson, setJson);
79 |         evt.validate();
80 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
81 |     }
82 | }
--------------------------------------------------------------------------------
/src/test/java/com/sailpoint/sse/model/CAEPCredentialChangeTest.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model;
 8 | 
 9 | import com.nimbusds.jose.shaded.json.JSONObject;
10 | import com.nimbusds.jose.util.JSONObjectUtils;
11 | import com.nimbusds.jwt.JWTClaimsSet;
12 | import com.nimbusds.jwt.util.DateUtils;
13 | import com.sailpoint.sse.model.caep.CAEPChangeType;
14 | import com.sailpoint.sse.model.caep.CAEPCredentialChange;
15 | import com.sailpoint.sse.model.caep.CAEPCredentialType;
16 | import com.sailpoint.sse.model.caep.CAEPInitiatingEntity;
17 | import com.sailpoint.ietf.subjectidentifiers.model.IssSubSubjectIdentifier;
18 | import com.sailpoint.ietf.subjectidentifiers.model.SIValidationException;
19 | import org.junit.Test;
20 | 
21 | import java.text.ParseException;
22 | 
23 | import static org.junit.Assert.assertEquals;
24 | 
25 | public class CAEPCredentialChangeTest {
26 |     /**
27 |      * Figure 8: Example: Provisioning a new FIDO2 authenticator - Simple
28 |      *                          Subject + optional claims
29 |      */
30 | 
31 |     @Test
32 |     public void Figure8() throws ParseException, SIValidationException, ValidationException {
33 |         IssSubSubjectIdentifier subj = new IssSubSubjectIdentifier.Builder()
34 |                 .issuer("https://idp.example.com/3456789/")
35 |                 .subject("jane.smith@example.com")
36 |                 .build();
37 | 
38 |         CAEPCredentialChange evt = new CAEPCredentialChange.Builder()
39 |                 .credentialType(CAEPCredentialType.FIDO2_ROAMING)
40 |                 .changeType(CAEPChangeType.CREATE)
41 |                 .fido2AAGuid("accced6a-63f5-490a-9eea-e59bc1896cfc")
42 |                 .eventTimestamp(1615304991643L)
43 |                 .initiatingEntity(CAEPInitiatingEntity.USER)
44 |                 .subject(subj)
45 |                 .reasonAdmin("User self-enrollment")
46 |                 .friendlyName("Jane's USB authenticator")
47 |                 .build();
48 | 
49 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
50 |                 .issuer("https://idp.example.com/3456789/")
51 |                 .jwtID("07efd930f0977e4fcc1149a733ce7f78")
52 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1615305159L))
53 |                 .audience("https://sp.example2.net/caep")
54 |                 .claim(SEToken.EVENTS_CLAIM, evt)
55 |                 .build();
56 | 
57 |         final String figure_text = "   {\n" +
58 |                 "       \"iss\": \"https://idp.example.com/3456789/\",\n" +
59 |                 "       \"jti\": \"07efd930f0977e4fcc1149a733ce7f78\",\n" +
60 |                 "       \"iat\": 1615305159,\n" +
61 |                 "       \"aud\": \"https://sp.example2.net/caep\",\n" +
62 |                 "       \"events\": {\n" +
63 |                 "           \"https://schemas.openid.net/secevent/caep/event-type/credential-change\": {\n" +
64 |                 "               \"subject\": {\n" +
65 |                 "                   \"format\": \"iss_sub\",\n" +
66 |                 "                   \"iss\": \"https://idp.example.com/3456789/\",\n" +
67 |                 "                   \"sub\": \"jane.smith@example.com\"\n" +
68 |                 "               },\n" +
69 |                 "               \"credential_type\": \"fido2-roaming\",\n" +
70 |                 "               \"change_type\": \"create\",\n" +
71 |                 "               \"fido2_aaguid\": \"accced6a-63f5-490a-9eea-e59bc1896cfc\",\n" +
72 |                 "               \"friendly_name\": \"Jane's USB authenticator\",\n" +
73 |                 "               \"initiating_entity\": \"user\",\n" +
74 |                 "               \"reason_admin\": \"User self-enrollment\",\n" +
75 |                 "               \"event_timestamp\": 1615304991643\n" +
76 |                 "           }\n" +
77 |                 "       }\n" +
78 |                 "   }";
79 | 
80 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
81 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
82 |         assertEquals(figureJson, setJson);
83 |         evt.validate();
84 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
85 |     }
86 | }
--------------------------------------------------------------------------------
/src/test/java/com/sailpoint/sse/model/CAEPDeviceComplianceChangeTest.java:
--------------------------------------------------------------------------------
  1 | /*
  2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
  3 |  *
  4 |  * SPDX-License-Identifier: Apache-2.0
  5 |  */
  6 | 
  7 | package com.sailpoint.sse.model;
  8 | 
  9 | import com.nimbusds.jose.shaded.json.JSONObject;
 10 | import com.nimbusds.jose.util.JSONObjectUtils;
 11 | import com.nimbusds.jwt.JWTClaimsSet;
 12 | import com.nimbusds.jwt.util.DateUtils;
 13 | import com.sailpoint.ietf.subjectidentifiers.model.IssSubSubjectIdentifier;
 14 | import com.sailpoint.ietf.subjectidentifiers.model.OpaqueSubjectIdentifier;
 15 | import com.sailpoint.ietf.subjectidentifiers.model.SIValidationException;
 16 | import com.sailpoint.ietf.subjectidentifiers.model.SubjectIdentifier;
 17 | import com.sailpoint.sse.model.caep.CAEPComplianceStatus;
 18 | import com.sailpoint.sse.model.caep.CAEPDeviceComplianceChange;
 19 | import com.sailpoint.sse.model.caep.CAEPInitiatingEntity;
 20 | import org.junit.Test;
 21 | 
 22 | import java.text.ParseException;
 23 | 
 24 | import static org.junit.Assert.assertEquals;
 25 | 
 26 | public class CAEPDeviceComplianceChangeTest {
 27 |     /**
 28 |      *   Figure 10: Example: Device No Longer Compliant - Complex Subject +
 29 |      *                               optional claims
 30 |      */
 31 | 
 32 |     @Test
 33 |     public void Figure10() throws ParseException, SIValidationException, ValidationException {
 34 |         IssSubSubjectIdentifier device = new IssSubSubjectIdentifier.Builder()
 35 |                 .issuer("https://idp.example.com/123456789/")
 36 |                 .subject("e9297990-14d2-42ec-a4a9-4036db86509a")
 37 |                 .build();
 38 | 
 39 |         OpaqueSubjectIdentifier tenant = new OpaqueSubjectIdentifier.Builder()
 40 |                 .id("123456789")
 41 |                 .build();
 42 | 
 43 |         SubjectIdentifier subj = new SubjectIdentifier.Builder()
 44 |                 .device(device)
 45 |                 .tenant(tenant)
 46 |                 .build();
 47 | 
 48 |         CAEPDeviceComplianceChange evt = new CAEPDeviceComplianceChange.Builder()
 49 |                 .previousStatus(CAEPComplianceStatus.COMPLIANT)
 50 |                 .currentStatus(CAEPComplianceStatus.NOT_COMPLIANT)
 51 |                 .initiatingEntity(CAEPInitiatingEntity.POLICY)
 52 |                 .reasonAdmin("Location Policy Violation: C076E82F")
 53 |                 .reasonUser("Device is no longer in a trusted location.")
 54 |                 .eventTimestamp(1615304991643L)
 55 |                 .subject(subj)
 56 |                 .build();
 57 | 
 58 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
 59 |                 .issuer("https://idp.example.com/123456789/")
 60 |                 .jwtID("24c63fb56e5a2d77a6b512616ca9fa24")
 61 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1615305159L))
 62 |                 .audience("https://sp.example.com/caep")
 63 |                 .claim(SEToken.EVENTS_CLAIM, evt)
 64 |                 .build();
 65 | 
 66 |         final String figure_text = "{\n" +
 67 |                 "    \"iss\": \"https://idp.example.com/123456789/\",\n" +
 68 |                 "    \"jti\": \"24c63fb56e5a2d77a6b512616ca9fa24\",\n" +
 69 |                 "    \"iat\": 1615305159,\n" +
 70 |                 "    \"aud\": \"https://sp.example.com/caep\",\n" +
 71 |                 "    \"events\": {\n" +
 72 |                 "        \"https://schemas.openid.net/secevent/caep/event-type/device-compliance-change\": {\n" +
 73 |                 "            \"subject\": {\n" +
 74 |                 "                \"device\": {\n" +
 75 |                 "                    \"format\": \"iss_sub\",\n" +
 76 |                 "                    \"iss\": \"https://idp.example.com/123456789/\",\n" +
 77 |                 "                    \"sub\": \"e9297990-14d2-42ec-a4a9-4036db86509a\"\n" +
 78 |                 "                },\n" +
 79 |                 "                \"tenant\": {\n" +
 80 |                 "                    \"format\": \"opaque\",\n" +
 81 |                 "                    \"id\": \"123456789\"\n" +
 82 |                 "                }\n" +
 83 |                 "            },\n" +
 84 |                 "            \"current_status\": \"not-compliant\",\n" +
 85 |                 "            \"previous_status\": \"compliant\",\n" +
 86 |                 "            \"initiating_entity\": \"policy\",\n" +
 87 |                 "            \"reason_admin\": \"Location Policy Violation: C076E82F\",\n" +
 88 |                 "            \"reason_user\": \"Device is no longer in a trusted location.\",\n" +
 89 |                 "            \"event_timestamp\": 1615304991643\n" +
 90 |                 "        }\n" +
 91 |                 "    }\n" +
 92 |                 "}\n";
 93 | 
 94 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
 95 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
 96 |         assertEquals(figureJson, setJson);
 97 |         evt.validate();
 98 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
 99 |     }
100 | }
--------------------------------------------------------------------------------
/src/test/java/com/sailpoint/sse/model/CAEPSessionRevokedTest.java:
--------------------------------------------------------------------------------
  1 | /*
  2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
  3 |  *
  4 |  * SPDX-License-Identifier: Apache-2.0
  5 |  */
  6 | 
  7 | package com.sailpoint.sse.model;
  8 | 
  9 | import com.nimbusds.jose.shaded.json.JSONObject;
 10 | import com.nimbusds.jose.util.JSONObjectUtils;
 11 | import com.nimbusds.jwt.JWTClaimsSet;
 12 | import com.nimbusds.jwt.util.DateUtils;
 13 | import com.sailpoint.sse.model.caep.CAEPInitiatingEntity;
 14 | import com.sailpoint.sse.model.caep.CAEPSessionRevoked;
 15 | import com.sailpoint.ietf.subjectidentifiers.model.SubjectIdentifier;
 16 | import com.sailpoint.ietf.subjectidentifiers.model.OpaqueSubjectIdentifier;
 17 | import com.sailpoint.ietf.subjectidentifiers.model.IssSubSubjectIdentifier;
 18 | import com.sailpoint.ietf.subjectidentifiers.model.SubjectIdentifierFormats;
 19 | import com.sailpoint.ietf.subjectidentifiers.model.SIValidationException;
 20 | import org.junit.Test;
 21 | 
 22 | import java.text.ParseException;
 23 | 
 24 | import static org.junit.Assert.assertEquals;
 25 | 
 26 | public class CAEPSessionRevokedTest {
 27 |     /**
 28 |      * Figure 1: Example: Session Revoked - Required claims + Simple Subject
 29 |      */
 30 |     @Test
 31 |     public void Figure1() throws ParseException, SIValidationException, ValidationException {
 32 |         OpaqueSubjectIdentifier subj = new OpaqueSubjectIdentifier.Builder()
 33 |                 .id("dMTlD|1600802906337.16|16008.16")
 34 |                 .build();
 35 | 
 36 |         CAEPSessionRevoked evt = new CAEPSessionRevoked.Builder()
 37 |                 .eventTimestamp(1615304991643L)
 38 |                 .subject(subj)
 39 |                 .build();
 40 | 
 41 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
 42 |                 .issuer("https://idp.example.com/123456789/")
 43 |                 .jwtID("24c63fb56e5a2d77a6b512616ca9fa24")
 44 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1615305159L))
 45 |                 .audience("https://sp.example.com/caep")
 46 |                 .claim(SEToken.EVENTS_CLAIM, evt)
 47 |                 .build();
 48 | 
 49 |         final String figure_text = "   {\n" +
 50 |                 "       \"iss\": \"https://idp.example.com/123456789/\",\n" +
 51 |                 "       \"jti\": \"24c63fb56e5a2d77a6b512616ca9fa24\",\n" +
 52 |                 "       \"iat\": 1615305159,\n" +
 53 |                 "       \"aud\": \"https://sp.example.com/caep\",\n" +
 54 |                 "       \"events\": {\n" +
 55 |                 "           \"https://schemas.openid.net/secevent/caep/event-type/session-revoked\": {\n" +
 56 |                 "               \"subject\": {\n" +
 57 |                 "                   \"format\": \"opaque\",\n" +
 58 |                 "                   \"id\": \"dMTlD|1600802906337.16|16008.16\"\n" +
 59 |                 "               },\n" +
 60 |                 "               \"event_timestamp\": 1615304991643\n" +
 61 |                 "           }\n" +
 62 |                 "       }\n" +
 63 |                 "   }\n";
 64 | 
 65 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
 66 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
 67 |         assertEquals(figureJson, setJson);
 68 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
 69 |     }
 70 | 
 71 | 
 72 |     /**
 73 |      * Figure 2: Example: Session Revoked - Complex Subject describing user
 74 |      *              + session ID + device (includes optional claims)
 75 |      */
 76 | 
 77 |     @Test
 78 |     public void Figure2() throws ParseException, SIValidationException, ValidationException {
 79 |         OpaqueSubjectIdentifier session = new OpaqueSubjectIdentifier.Builder()
 80 |                 .id("dMTlD|1600802906337.16|16008.16")
 81 |                 .build();
 82 | 
 83 |         IssSubSubjectIdentifier user = new IssSubSubjectIdentifier.Builder()
 84 |                 .issuer("https://idp.example.com/123456789/")
 85 |                 .subject("dMTlD|1600802906337.16|16008.16")
 86 |                 .build();
 87 | 
 88 |         OpaqueSubjectIdentifier tenant = new OpaqueSubjectIdentifier.Builder()
 89 |                 .id("123456789")
 90 |                 .build();
 91 | 
 92 |         SubjectIdentifier subj = new SubjectIdentifier.Builder()
 93 |                 .session(session)
 94 |                 .user(user)
 95 |                 .tenant(tenant)
 96 |                 .build();
 97 | 
 98 |         CAEPSessionRevoked evt = new CAEPSessionRevoked.Builder()
 99 |                 .initiatingEntity(CAEPInitiatingEntity.POLICY)
100 |                 .reasonAdmin("Landspeed Policy Violation: C076E82F")
101 |                 .reasonUser("Access attempt from multiple regions.")
102 |                 .eventTimestamp(1615304991643L)
103 |                 .subject(subj)
104 |                 .build();
105 | 
106 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
107 |                 .issuer("https://idp.example.com/123456789/")
108 |                 .jwtID("24c63fb56e5a2d77a6b512616ca9fa24")
109 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1615305159L))
110 |                 .audience("https://sp.example.com/caep")
111 |                 .claim(SEToken.EVENTS_CLAIM, evt)
112 |                 .build();
113 | 
114 |         final String figure_text = "   {\n" +
115 |                 "       \"iss\": \"https://idp.example.com/123456789/\",\n" +
116 |                 "       \"jti\": \"24c63fb56e5a2d77a6b512616ca9fa24\",\n" +
117 |                 "       \"iat\": 1615305159,\n" +
118 |                 "       \"aud\": \"https://sp.example.com/caep\",\n" +
119 |                 "       \"events\": {\n" +
120 |                 "           \"https://schemas.openid.net/secevent/caep/event-type/session-revoked\": {\n" +
121 |                 "               \"subject\": {\n" +
122 |                 "                   \"session\": {\n" +
123 |                 "                     \"format\": \"opaque\",\n" +
124 |                 "                     \"id\": \"dMTlD|1600802906337.16|16008.16\"\n" +
125 |                 "                   },\n" +
126 |                 "                   \"user\": {\n" +
127 |                 "                     \"format\": \"iss_sub\",\n" +
128 |                 "                     \"iss\": \"https://idp.example.com/123456789/\",\n" +
129 |                 "                     \"sub\": \"dMTlD|1600802906337.16|16008.16\"\n" +
130 |                 "                   },\n" +
131 |                 "                   \"tenant\": {\n" +
132 |                 "                     \"format\": \"opaque\",\n" +
133 |                 "                     \"id\": \"123456789\"\n" +
134 |                 "                   }\n" +
135 |                 "               },\n" +
136 |                 "               \"initiating_entity\": \"policy\",\n" +
137 |                 "               \"reason_admin\": \"Landspeed Policy Violation: C076E82F\",\n" +
138 |                 "               \"reason_user\": \"Access attempt from multiple regions.\",\n" +
139 |                 "               \"event_timestamp\": 1615304991643\n" +
140 |                 "           }\n" +
141 |                 "       }\n" +
142 |                 "   }\n";
143 | 
144 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
145 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
146 |         assertEquals(figureJson, setJson);
147 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
148 |     }
149 | 
150 |     /**
151 |      * Figure 3: Example: Session Revoked - subject as `sub` claim (includes
152 |      *                              optional claims)
153 |      */
154 | 
155 |     @Test
156 |     public void Figure3() throws ParseException, SIValidationException, ValidationException {
157 |         CAEPSessionRevoked evt = new CAEPSessionRevoked.Builder()
158 |                 .initiatingEntity(CAEPInitiatingEntity.POLICY)
159 |                 .reasonAdmin("Landspeed Policy Violation: C076E82F")
160 |                 .reasonUser("Access attempt from multiple regions.")
161 |                 .eventTimestamp(1615304991643L)
162 |                 .build();
163 | 
164 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
165 |                 .issuer("https://idp.example.com/123456789/")
166 |                 .jwtID("24c63fb56e5a2d77a6b512616ca9fa24")
167 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1615305159L))
168 |                 .audience("https://sp.example.com/caep")
169 |                 .subject("jane.smith@example.com")
170 |                 .claim(SEToken.EVENTS_CLAIM, evt)
171 |                 .build();
172 | 
173 |         final String figure_text = "   {\n" +
174 |                 "       \"iss\": \"https://idp.example.com/123456789/\",\n" +
175 |                 "       \"jti\": \"24c63fb56e5a2d77a6b512616ca9fa24\",\n" +
176 |                 "       \"iat\": 1615305159,\n" +
177 |                 "       \"aud\": \"https://sp.example.com/caep\",\n" +
178 |                 "       \"sub\": \"jane.smith@example.com\",\n" +
179 |                 "       \"events\": {\n" +
180 |                 "           \"https://schemas.openid.net/secevent/caep/event-type/session-revoked\": {\n" +
181 |                 "               \"initiating_entity\": \"policy\",\n" +
182 |                 "               \"reason_admin\": \"Landspeed Policy Violation: C076E82F\",\n" +
183 |                 "               \"reason_user\": \"Access attempt from multiple regions.\",\n" +
184 |                 "               \"event_timestamp\": 1615304991643\n" +
185 |                 "           }\n" +
186 |                 "       }\n" +
187 |                 "   }";
188 | 
189 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
190 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
191 |         assertEquals(figureJson, setJson);
192 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
193 |     }
194 | 
195 |     /**
196 |      *   Figure 4: Example: Session Revoked - Complex Subject describing user
197 |      *                + device + tenant (includes optional claims)
198 |      */
199 | 
200 |     @Test
201 |     public void Figure4() throws ParseException, SIValidationException, ValidationException {
202 |         IssSubSubjectIdentifier user = new IssSubSubjectIdentifier.Builder()
203 |                 .issuer("https://idp.example.com/123456789/")
204 |                 .subject("jane.smith@example.com")
205 |                 .build();
206 | 
207 |         IssSubSubjectIdentifier device = new IssSubSubjectIdentifier.Builder()
208 |                 .issuer("https://idp.example.com/123456789/")
209 |                 .subject("e9297990-14d2-42ec-a4a9-4036db86509a")
210 |                 .build();
211 | 
212 |         OpaqueSubjectIdentifier tenant = new OpaqueSubjectIdentifier.Builder()
213 |                 .id("123456789")
214 |                 .build();
215 | 
216 |         SubjectIdentifier subj = new SubjectIdentifier.Builder()
217 |                 .user(user)
218 |                 .device(device)
219 |                 .tenant(tenant)
220 |                 .build();
221 | 
222 |         CAEPSessionRevoked evt = new CAEPSessionRevoked.Builder()
223 |                 .initiatingEntity(CAEPInitiatingEntity.POLICY)
224 |                 .reasonAdmin("Policy Violation: C076E82F")
225 |                 .reasonUser("This device is no longer compliant.")
226 |                 .eventTimestamp(1615304991643L)
227 |                 .subject(subj)
228 |                 .build();
229 | 
230 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
231 |                 .issuer("https://idp.example.com/123456789/")
232 |                 .jwtID("24c63fb56e5a2d77a6b512616ca9fa24")
233 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1615305159L))
234 |                 .audience("https://sp.example.com/caep")
235 |                 .claim(SEToken.EVENTS_CLAIM, evt)
236 |                 .build();
237 | 
238 |         final String figure_text = "   {\n" +
239 |                 "       \"iss\": \"https://idp.example.com/123456789/\",\n" +
240 |                 "       \"jti\": \"24c63fb56e5a2d77a6b512616ca9fa24\",\n" +
241 |                 "       \"iat\": 1615305159,\n" +
242 |                 "       \"aud\": \"https://sp.example.com/caep\",\n" +
243 |                 "       \"events\": {\n" +
244 |                 "           \"https://schemas.openid.net/secevent/caep/event-type/session-revoked\": {\n" +
245 |                 "               \"subject\": {\n" +
246 |                 "                   \"user\": {\n" +
247 |                 "                       \"format\": \"iss_sub\",\n" +
248 |                 "                       \"iss\": \"https://idp.example.com/123456789/\",\n" +
249 |                 "                       \"sub\": \"jane.smith@example.com\"\n" +
250 |                 "                   },\n" +
251 |                 "                   \"device\": {\n" +
252 |                 "                       \"format\": \"iss_sub\",\n" +
253 |                 "                       \"iss\": \"https://idp.example.com/123456789/\",\n" +
254 |                 "                       \"sub\": \"e9297990-14d2-42ec-a4a9-4036db86509a\"\n" +
255 |                 "                   },\n" +
256 |                 "                   \"tenant\": {\n" +
257 |                 "                     \"format\": \"opaque\",\n" +
258 |                 "                     \"id\": \"123456789\"\n" +
259 |                 "                   }\n" +
260 |                 "               },\n" +
261 |                 "               \"initiating_entity\": \"policy\",\n" +
262 |                 "               \"reason_admin\": \"Policy Violation: C076E82F\",\n" +
263 |                 "               \"reason_user\": \"This device is no longer compliant.\",\n" +
264 |                 "               \"event_timestamp\": 1615304991643\n" +
265 |                 "           }\n" +
266 |                 "       }\n" +
267 |                 "   }\n";
268 | 
269 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
270 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
271 |         assertEquals(figureJson, setJson);
272 | 
273 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
274 |     }
275 | 
276 | }
--------------------------------------------------------------------------------
/src/test/java/com/sailpoint/sse/model/CAEPTokenClaimsChangeTest.java:
--------------------------------------------------------------------------------
  1 | /*
  2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
  3 |  *
  4 |  * SPDX-License-Identifier: Apache-2.0
  5 |  */
  6 | 
  7 | package com.sailpoint.sse.model;
  8 | 
  9 | import com.nimbusds.jose.shaded.json.JSONObject;
 10 | import com.nimbusds.jose.util.JSONObjectUtils;
 11 | import com.nimbusds.jwt.JWTClaimsSet;
 12 | import com.nimbusds.jwt.util.DateUtils;
 13 | import com.sailpoint.sse.model.caep.CAEPInitiatingEntity;
 14 | import com.sailpoint.sse.model.caep.CAEPTokenClaimsChange;
 15 | import com.sailpoint.ietf.subjectidentifiers.model.SubjectIdentifier;
 16 | import com.sailpoint.ietf.subjectidentifiers.model.SubjectIdentifierFormats;
 17 | import com.sailpoint.ietf.subjectidentifiers.model.SIValidationException;
 18 | import org.junit.Test;
 19 | 
 20 | import java.text.ParseException;
 21 | 
 22 | import static org.junit.Assert.assertEquals;
 23 | 
 24 | public class CAEPTokenClaimsChangeTest {
 25 |     /**
 26 |      * Figure 5: Example: OIDC ID Token Claims Change - Required claims only
 27 |      */
 28 | 
 29 |     @Test
 30 |     public void Figure5() throws ParseException, SIValidationException, ValidationException {
 31 |         SubjectIdentifier subj = new SubjectIdentifier.Builder()
 32 |                 .format(SubjectIdentifierFormats.JWT_ID)
 33 |                 .issuer("https://idp.example.com/987654321/")
 34 |                 .jwtID("f61t6e20zdo3px56gepu8rzlsp4c1dpc0fx7")
 35 |                 .build();
 36 | 
 37 |         JSONObject claims = new JSONObject();
 38 |         claims.put("role", "ro-admin");
 39 | 
 40 |         CAEPTokenClaimsChange evt = new CAEPTokenClaimsChange.Builder()
 41 |                 .eventTimestamp(1615304991643L)
 42 |                 .subject(subj)
 43 |                 .claims(claims)
 44 |                 .build();
 45 | 
 46 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
 47 |                 .issuer("https://idp.example.com/987654321/")
 48 |                 .jwtID("9afce1e4e642b165fcaacdd0e7aa4903")
 49 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1615305159L))
 50 |                 .audience("https://sp.example2.net/caep")
 51 |                 .claim(SEToken.EVENTS_CLAIM, evt)
 52 |                 .build();
 53 | 
 54 |         final String figure_text = "   {\n" +
 55 |                 "       \"iss\": \"https://idp.example.com/987654321/\",\n" +
 56 |                 "       \"jti\": \"9afce1e4e642b165fcaacdd0e7aa4903\",\n" +
 57 |                 "       \"iat\": 1615305159,\n" +
 58 |                 "       \"aud\": \"https://sp.example2.net/caep\",\n" +
 59 |                 "       \"events\": {\n" +
 60 |                 "           \"https://schemas.openid.net/secevent/caep/event-type/token-claims-change\": {\n" +
 61 |                 "               \"subject\": {\n" +
 62 |                 "                   \"format\": \"jwt_id\",\n" +
 63 |                 "                   \"iss\": \"https://idp.example.com/987654321/\",\n" +
 64 |                 "                   \"jti\": \"f61t6e20zdo3px56gepu8rzlsp4c1dpc0fx7\"\n" +
 65 |                 "               },\n" +
 66 |                 "               \"event_timestamp\": 1615304991643,\n" +
 67 |                 "               \"claims\": {\n" +
 68 |                 "                   \"role\": \"ro-admin\"\n" +
 69 |                 "               }\n" +
 70 |                 "           }\n" +
 71 |                 "       }\n" +
 72 |                 "   }\n";
 73 | 
 74 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
 75 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
 76 |         assertEquals(figureJson, setJson);
 77 |         evt.validate();
 78 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
 79 | 
 80 |     }
 81 |     /**
 82 |      * Figure 6: Example: OIDC ID Token Claims Change - Optional claims
 83 |      */
 84 | 
 85 |     @Test
 86 |     public void Figure6() throws ParseException, SIValidationException, ValidationException {
 87 |         SubjectIdentifier subj = new SubjectIdentifier.Builder()
 88 |                 .format(SubjectIdentifierFormats.JWT_ID)
 89 |                 .issuer("https://idp.example.com/987654321/")
 90 |                 .jwtID("f61t6e20zdo3px56gepu8rzlsp4c1dpc0fx7")
 91 |                 .build();
 92 | 
 93 |         JSONObject claims = new JSONObject();
 94 |         claims.put("trusted_network", "false");
 95 | 
 96 |         CAEPTokenClaimsChange evt = new CAEPTokenClaimsChange.Builder()
 97 |                 .eventTimestamp(1615304991643L)
 98 |                 .subject(subj)
 99 |                 .claims(claims)
100 |                 .initiatingEntity(CAEPInitiatingEntity.POLICY)
101 |                 .reasonAdmin("User left trusted network: CorpNet3")
102 |                 .reasonUser("You're no longer connected to a trusted network.")
103 |                 .build();
104 | 
105 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
106 |                 .issuer("https://idp.example.com/987654321/")
107 |                 .jwtID("9afce1e4e642b165fcaacdd0e7aa4903")
108 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1615305159L))
109 |                 .audience("https://sp.example2.net/caep")
110 |                 .claim(SEToken.EVENTS_CLAIM, evt)
111 |                 .build();
112 | 
113 |         final String figure_text = "{\n" +
114 |                 "    \"iss\": \"https://idp.example.com/987654321/\",\n" +
115 |                 "    \"jti\": \"9afce1e4e642b165fcaacdd0e7aa4903\",\n" +
116 |                 "    \"iat\": 1615305159,\n" +
117 |                 "    \"aud\": \"https://sp.example2.net/caep\",\n" +
118 |                 "    \"events\": {\n" +
119 |                 "        \"https://schemas.openid.net/secevent/caep/event-type/token-claims-change\": {\n" +
120 |                 "            \"subject\": {\n" +
121 |                 "                \"format\": \"jwt_id\",\n" +
122 |                 "                \"iss\": \"https://idp.example.com/987654321/\",\n" +
123 |                 "                \"jti\": \"f61t6e20zdo3px56gepu8rzlsp4c1dpc0fx7\"\n" +
124 |                 "            },\n" +
125 |                 "            \"event_timestamp\": 1615304991643,\n" +
126 |                 "            \"initiating_entity\": \"policy\",\n" +
127 |                 "            \"reason_admin\": \"User left trusted network: CorpNet3\",\n" +
128 |                 "            \"reason_user\": \"You're no longer connected to a trusted network.\",\n" +
129 |                 "            \"claims\": {\n" +
130 |                 "                \"trusted_network\": \"false\"\n" +
131 |                 "            }\n" +
132 |                 "        }\n" +
133 |                 "    }\n" +
134 |                 "}";
135 | 
136 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
137 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
138 |         assertEquals(figureJson, setJson);
139 |         evt.validate();
140 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
141 | 
142 |     }
143 | 
144 |     /**
145 |      * Figure 7: Example: SAML Assertion Claims Change - Required claims
146 |      *                                    only
147 |      */
148 | 
149 |     @Test
150 |     public void Figure7() throws ParseException, SIValidationException, ValidationException {
151 |         SubjectIdentifier subj = new SubjectIdentifier.Builder()
152 |                 .format(SubjectIdentifierFormats.SAML_ASSERTION_ID)
153 |                 .issuer("https://idp.example.com/987654321/")
154 |                 .samlAssertionID("_a75adf55-01d7-dbd8372ebdfc")
155 |                 .build();
156 | 
157 |         JSONObject claims = new JSONObject();
158 |         claims.put("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role",
159 |                 "ro-admin");
160 | 
161 |         CAEPTokenClaimsChange evt = new CAEPTokenClaimsChange.Builder()
162 |                 .eventTimestamp(1615304991643L)
163 |                 .subject(subj)
164 |                 .member("claims", claims)
165 |                 .build();
166 | 
167 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
168 |                 .issuer("https://idp.example.com/987654321/")
169 |                 .jwtID("dae94fed5f459881efa38b65c6772ddc")
170 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1615305159L))
171 |                 .audience("https://sp.example2.net/caep")
172 |                 .claim(SEToken.EVENTS_CLAIM, evt)
173 |                 .build();
174 | 
175 |         final String figure_text = "   {\n" +
176 |                 "       \"iss\": \"https://idp.example.com/987654321/\",\n" +
177 |                 "       \"jti\": \"dae94fed5f459881efa38b65c6772ddc\",\n" +
178 |                 "       \"iat\": 1615305159,\n" +
179 |                 "       \"aud\": \"https://sp.example2.net/caep\",\n" +
180 |                 "       \"events\": {\n" +
181 |                 "           \"https://schemas.openid.net/secevent/caep/event-type/token-claims-change\": {\n" +
182 |                 "               \"subject\": {\n" +
183 |                 "                   \"format\": \"saml_assertion_id\",\n" +
184 |                 "                   \"issuer\": \"https://idp.example.com/987654321/\",\n" +
185 |                 "                   \"assertion_id\": \"_a75adf55-01d7-dbd8372ebdfc\"\n" +
186 |                 "               },\n" +
187 |                 "               \"event_timestamp\": 1615304991643,\n" +
188 |                 "               \"claims\": {\n" +
189 |                 "                   \"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role\": \"ro-admin\"\n" +
190 |                 "               }\n" +
191 |                 "           }\n" +
192 |                 "       }\n" +
193 |                 "   }\n";
194 | 
195 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
196 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
197 |         assertEquals(figureJson, setJson);
198 |         evt.validate();
199 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
200 |     }
201 | }
--------------------------------------------------------------------------------
/src/test/java/com/sailpoint/sse/model/EventStreamTests.java:
--------------------------------------------------------------------------------
  1 | /*
  2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
  3 |  *
  4 |  * SPDX-License-Identifier: Apache-2.0
  5 |  */
  6 | 
  7 | package com.sailpoint.sse.model;
  8 | 
  9 | import com.nimbusds.jose.shaded.json.JSONObject;
 10 | import com.nimbusds.jose.util.JSONObjectUtils;
 11 | import com.nimbusds.jwt.JWTClaimsSet;
 12 | import com.nimbusds.jwt.util.DateUtils;
 13 | import com.sailpoint.sse.model.sse.SSEStreamUpdated;
 14 | import com.sailpoint.sse.model.sse.SSEVerification;
 15 | import com.sailpoint.ietf.subjectidentifiers.model.SubjectIdentifier;
 16 | import com.sailpoint.ietf.subjectidentifiers.model.IssSubSubjectIdentifier;
 17 | import com.sailpoint.ietf.subjectidentifiers.model.SubjectIdentifierFormats;
 18 | import com.sailpoint.ietf.subjectidentifiers.model.SIValidationException;
 19 | 
 20 | import org.junit.Test;
 21 | 
 22 | import java.text.ParseException;
 23 | 
 24 | import static org.junit.Assert.assertEquals;
 25 | 
 26 | public class EventStreamTests {
 27 |     /**
 28 |      * Figure 31: Example: Verification SET
 29 |      */
 30 |     @Test()
 31 |     public void Figure31() throws ParseException, SIValidationException, ValidationException {
 32 | 
 33 |         SSEVerification evt = new SSEVerification.Builder()
 34 |                 .state("VGhpcyBpcyBhbiBleGFtcGxlIHN0YXRlIHZhbHVlLgo=")
 35 |                 .build();
 36 | 
 37 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
 38 |                 .issuer("https://transmitter.example.com")
 39 |                 .jwtID("123456")
 40 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1493856000L))
 41 |                 .audience("receiver.example.com")
 42 |                 .claim(SEToken.EVENTS_CLAIM, evt)
 43 |                 .build();
 44 | 
 45 |         final String figure_text = " {\n" +
 46 |                 "   \"jti\": \"123456\",\n" +
 47 |                 "   \"iss\": \"https://transmitter.example.com\",\n" +
 48 |                 "   \"aud\": \"receiver.example.com\",\n" +
 49 |                 "   \"iat\": 1493856000,\n" +
 50 |                 "   \"events\": {\n" +
 51 |                 "     \"https://schemas.openid.net/secevent/sse/event-type/verification\":{\n" +
 52 |                 "       \"state\": \"VGhpcyBpcyBhbiBleGFtcGxlIHN0YXRlIHZhbHVlLgo=\"\n" +
 53 |                 "     }\n" +
 54 |                 "   }\n" +
 55 |                 " }";
 56 | 
 57 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
 58 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
 59 |         assertEquals(figureJson, setJson);
 60 |         evt.validate();
 61 | 
 62 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
 63 |     }
 64 | 
 65 |     /**
 66 |      * Figure 32: Example: Stream Updated SET
 67 |      */
 68 |     @Test()
 69 |     public void Figure32() throws ParseException, SIValidationException, ValidationException {
 70 |         IssSubSubjectIdentifier tenant = new IssSubSubjectIdentifier.Builder()
 71 |                 .issuer("http://example.com/idp1")
 72 |                 .subject("1234")
 73 |                 .build();
 74 | 
 75 |         SubjectIdentifier subj = new SubjectIdentifier.Builder()
 76 |                 .tenant(tenant)
 77 |                 .build();
 78 | 
 79 |         SSEStreamUpdated evt = new SSEStreamUpdated.Builder()
 80 |                 .subject(subj)
 81 |                 .status(StreamStatus.PAUSED)
 82 |                 .reason("License is not valid")
 83 |                 .build();
 84 | 
 85 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
 86 |                 .issuer("https://transmitter.example.com")
 87 |                 .jwtID("123456")
 88 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1493856000L))
 89 |                 .audience("receiver.example.com")
 90 |                 .claim(SEToken.EVENTS_CLAIM, evt)
 91 |                 .build();
 92 | 
 93 |         final String figure_text = "{\n" +
 94 |                 "  \"jti\": \"123456\",\n" +
 95 |                 "  \"iss\": \"https://transmitter.example.com\",\n" +
 96 |                 "  \"aud\": \"receiver.example.com\",\n" +
 97 |                 "  \"iat\": 1493856000,\n" +
 98 |                 "  \"events\": {\n" +
 99 |                 "    \"https://schemas.openid.net/secevent/sse/event-type/stream-updated\": {\n" +
100 |                 "      \"subject\": {\n" +
101 |                 "        \"tenant\" : {\n" +
102 |                 "          \"format\": \"iss_sub\",\n" +
103 |                 "          \"iss\" : \"http://example.com/idp1\",\n" +
104 |                 "          \"sub\" : \"1234\"\n" +
105 |                 "        }\n" +
106 |                 "      },\n" +
107 |                 "      \"status\": \"paused\",\n" +
108 |                 "      \"reason\": \"License is not valid\"\n" +
109 |                 "    }\n" +
110 |                 "  }\n" +
111 |                 "}";
112 | 
113 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
114 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
115 |         assertEquals(figureJson, setJson);
116 |         evt.validate();
117 | 
118 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
119 |     }
120 | 
121 | }
122 | 
--------------------------------------------------------------------------------
/src/test/java/com/sailpoint/sse/model/GoogleTests.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model;
 8 | 
 9 | import com.nimbusds.jose.shaded.json.JSONObject;
10 | import com.nimbusds.jose.util.JSONObjectUtils;
11 | import com.nimbusds.jwt.JWTClaimsSet;
12 | import com.nimbusds.jwt.util.DateUtils;
13 | import com.sailpoint.sse.model.risc.*;
14 | import com.sailpoint.ietf.subjectidentifiers.model.SubjectIdentifier;
15 | import com.sailpoint.ietf.subjectidentifiers.model.SIValidationException;
16 | import org.junit.Test;
17 | 
18 | import java.text.ParseException;
19 | 
20 | import static org.junit.Assert.assertEquals;
21 | 
22 | public class GoogleTests {
23 |     /*
24 |      *  https://developers.google.com/identity/protocols/risc#handle_events
25 |      *  Note: This uses the original subject_type member and value format with dashes
26 |      *    rather than the newer (April 2021) format "iss_sub"
27 |      */
28 |     @Test
29 |     public void AccountDisabled() throws ParseException, SIValidationException, ValidationException {
30 |         SubjectIdentifier subj = new SubjectIdentifier.Builder()
31 |                 .member("subject_type", "iss-sub")
32 |                 .issuer("https://accounts.google.com/")
33 |                 .subject("7375626A656374")
34 |                 .build();
35 | 
36 |         RISCAccountDisabled evt = new RISCAccountDisabled.Builder()
37 |                 .subject(subj)
38 |                 .reason(RISCAccountDisabledReasons.HIJACKING)
39 |                 .build();
40 | 
41 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
42 |                 .issuer("https://accounts.google.com/")
43 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1508184845L))
44 |                 .audience("123456789-abcedfgh.apps.googleusercontent.com")
45 |                 .jwtID("756E69717565206964656E746966696572")
46 |                 .claim(SEToken.EVENTS_CLAIM, evt)
47 |                 .build();
48 | 
49 |         final String figure_text = "{\n" +
50 |                 "  \"iss\": \"https://accounts.google.com/\",\n" +
51 |                 "  \"aud\": \"123456789-abcedfgh.apps.googleusercontent.com\",\n" +
52 |                 "  \"iat\": 1508184845,\n" +
53 |                 "  \"jti\": \"756E69717565206964656E746966696572\",\n" +
54 |                 "  \"events\": {\n" +
55 |                 "    \"https://schemas.openid.net/secevent/risc/event-type/account-disabled\": {\n" +
56 |                 "      \"subject\": {\n" +
57 |                 "        \"subject_type\": \"iss-sub\",\n" +
58 |                 "        \"iss\": \"https://accounts.google.com/\",\n" +
59 |                 "        \"sub\": \"7375626A656374\"\n" +
60 |                 "      },\n" +
61 |                 "      \"reason\": \"hijacking\"\n" +
62 |                 "    }\n" +
63 |                 "  }\n" +
64 |                 "}";
65 | 
66 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
67 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
68 |         assertEquals(figureJson, setJson);
69 |         subj.validate();
70 |         evt.validate();
71 | 
72 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
73 |     }
74 | }
75 | 
--------------------------------------------------------------------------------
/src/test/java/com/sailpoint/sse/model/OpenIDSSEProfileTest.java:
--------------------------------------------------------------------------------
  1 | /*
  2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
  3 |  *
  4 |  * SPDX-License-Identifier: Apache-2.0
  5 |  */
  6 | 
  7 | package com.sailpoint.sse.model;
  8 | 
  9 | import com.nimbusds.jose.shaded.json.JSONObject;
 10 | import com.nimbusds.jose.util.JSONObjectUtils;
 11 | import com.nimbusds.jwt.JWTClaimsSet;
 12 | import com.nimbusds.jwt.util.DateUtils;
 13 | import com.sailpoint.ietf.subjectidentifiers.model.*;
 14 | import com.sailpoint.sse.model.caep.CAEPSessionRevoked;
 15 | import com.sailpoint.sse.model.caep.CAEPTokenClaimsChange;
 16 | import com.sailpoint.sse.model.risc.RISCAccountEnabled;
 17 | import org.junit.Test;
 18 | 
 19 | import java.text.ParseException;
 20 | import java.util.Map;
 21 | import java.util.stream.Collectors;
 22 | import java.util.stream.IntStream;
 23 | 
 24 | import static org.junit.Assert.assertEquals;
 25 | 
 26 | public class OpenIDSSEProfileTest {
 27 | 
 28 |     private void dumpMapRecursive(Map map, int level) {
 29 |         for (String k : map.keySet()) {
 30 |             Object o = map.get(k);
 31 |             // Can't use String.repeat() here until Java 11, we support 9+ at the moment.
 32 |             String sb = IntStream.range(0, level).mapToObj(i -> "\t").collect(Collectors.joining());
 33 |             System.out.printf("%s%s -> (%s) %s%n", sb, k, o.getClass(), o);
 34 |             if (o instanceof JSONObject) {
 35 |                 dumpMapRecursive((JSONObject) o, level + 1);
 36 |             }
 37 |         }
 38 |     }
 39 | 
 40 |     private void dumpJWT(JWTClaimsSet set) {
 41 |         Map map = set.getClaims();
 42 |         dumpMapRecursive(map, 1);
 43 |     }
 44 | 
 45 | 
 46 |     /**
 47 |      * Figure 1: Example: Simple Subject
 48 |      */
 49 |     @Test
 50 |     public void Figure1() throws ParseException, SIValidationException {
 51 |         EmailSubjectIdentifier subj = new EmailSubjectIdentifier.Builder()
 52 |                 .email("foo@example.com")
 53 |                 .build();
 54 | 
 55 |         JSONObject container = new JSONObject();
 56 |         container.put("transferor", subj);
 57 | 
 58 |         final String figure_text = "   {\"transferor\": {\n" +
 59 |                 "     \"format\": \"email\",\n" +
 60 |                 "     \"email\": \"foo@example.com\"\n" +
 61 |                 "   }}\n";
 62 | 
 63 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
 64 |         assertEquals(figureJson, container);
 65 |         subj.validate();
 66 |     }
 67 | 
 68 |     /**
 69 |      * Figure 2: Example: Complex Subject
 70 |      */
 71 |     @Test
 72 |     public void Figure2() throws ParseException, SIValidationException {
 73 |         EmailSubjectIdentifier user = new EmailSubjectIdentifier.Builder()
 74 |                 .email("bar@example.com")
 75 |                 .build();
 76 | 
 77 |         IssSubSubjectIdentifier tenant = new IssSubSubjectIdentifier.Builder()
 78 |                 .issuer("http://example.com/idp1")
 79 |                 .subject("1234")
 80 |                 .build();
 81 | 
 82 |         SubjectIdentifier transferee = new SubjectIdentifier.Builder()
 83 |                 .user(user)
 84 |                 .tenant(tenant)
 85 |                 .build();
 86 | 
 87 |         JSONObject container = new JSONObject();
 88 |         container.put("transferee", transferee);
 89 | 
 90 |         final String figure_text = "   {\"transferee\": {\n" +
 91 |                 "     \"user\" : {\n" +
 92 |                 "       \"format\": \"email\",\n" +
 93 |                 "       \"email\": \"bar@example.com\"\n" +
 94 |                 "     },\n" +
 95 |                 "     \"tenant\" : {\n" +
 96 |                 "       \"format\": \"iss_sub\",\n" +
 97 |                 "       \"iss\" : \"http://example.com/idp1\",\n" +
 98 |                 "       \"sub\" : \"1234\"\n" +
 99 |                 "     }\n" +
100 |                 "   }}";
101 | 
102 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
103 |         assertEquals(figureJson, container);
104 |         transferee.validate();
105 |     }
106 | 
107 |     /**
108 |      * Figure 3: Example: 'jwt-id' Subject Identifier
109 |      */
110 | 
111 |     @Test
112 |     public void Figure3() throws ParseException, SIValidationException {
113 |         SubjectIdentifier jwtid = new SubjectIdentifier.Builder()
114 |                 .format(SubjectIdentifierFormats.JWT_ID)
115 |                 .issuer("https://idp.example.com/123456789/")
116 |                 .jwtID("B70BA622-9515-4353-A866-823539EECBC8")
117 |                 .build();
118 |         final String figure_text = "   {\n" +
119 |                 "       \"format\": \"jwt_id\",\n" +
120 |                 "       \"iss\": \"https://idp.example.com/123456789/\",\n" +
121 |                 "       \"jti\": \"B70BA622-9515-4353-A866-823539EECBC8\"\n" +
122 |                 "   }\n";
123 | 
124 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
125 |         assertEquals(figureJson, jwtid);
126 |         jwtid.validate();
127 |     }
128 | 
129 |     /**
130 |      * Figure 4:    {
131 |      * "format": "saml-assertion-id",
132 |      * "issuer": "https://idp.example.com/123456789/",
133 |      * "assertion_id": "_8e8dc5f69a98cc4c1ff3427e5ce34606fd672f91e6"
134 |      * }
135 |      */
136 |     @Test
137 |     public void Figure4() throws ParseException, SIValidationException {
138 |         SubjectIdentifier jwtid = new SubjectIdentifier.Builder()
139 |                 .format(SubjectIdentifierFormats.SAML_ASSERTION_ID)
140 |                 .issuer("https://idp.example.com/123456789/")
141 |                 .samlAssertionID("_8e8dc5f69a98cc4c1ff3427e5ce34606fd672f91e6")
142 |                 .build();
143 | 
144 |         final String figure_text = "   {\n" +
145 |                 "       \"format\": \"saml_assertion_id\",\n" +
146 |                 "       \"issuer\": \"https://idp.example.com/123456789/\",\n" +
147 |                 "       \"assertion_id\": \"_8e8dc5f69a98cc4c1ff3427e5ce34606fd672f91e6\"\n" +
148 |                 "   }\n";
149 | 
150 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
151 |         assertEquals(figureJson, jwtid);
152 |         jwtid.validate();
153 |     }
154 | 
155 |     /**
156 |      * Figure 5: Example: SET Containing a SSE Event with a Simple Subject Claim
157 |      */
158 | 
159 |     @Test
160 |     public void Figure5() throws ParseException, SIValidationException, ValidationException {
161 |         EmailSubjectIdentifier subj = new EmailSubjectIdentifier.Builder()
162 |                 .email("foo@example.com")
163 |                 .build();
164 | 
165 |         RISCAccountEnabled evt = new RISCAccountEnabled.Builder()
166 |                 .subject(subj)
167 |                 .build();
168 | 
169 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
170 |                 .issuer("https://idp.example.com/")
171 |                 .jwtID("756E69717565206964656E746966696572")
172 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1520364019))
173 |                 .audience("636C69656E745F6964")
174 |                 .claim(SEToken.EVENTS_CLAIM, evt)
175 |                 .build();
176 | 
177 |         final String figure_text = "{\n" +
178 |                 "  \"iss\": \"https://idp.example.com/\",\n" +
179 |                 "  \"jti\": \"756E69717565206964656E746966696572\",\n" +
180 |                 "  \"iat\": 1520364019,\n" +
181 |                 "  \"aud\": \"636C69656E745F6964\",\n" +
182 |                 "  \"events\": {\n" +
183 |                 "    \"https://schemas.openid.net/secevent/risc/event-type/account-enabled\": {\n" +
184 |                 "      \"subject\": {\n" +
185 |                 "        \"format\": \"email\",\n" +
186 |                 "        \"email\": \"foo@example.com\"\n" +
187 |                 "      }\n" +
188 |                 "    }\n" +
189 |                 "  }\n" +
190 |                 "}";
191 | 
192 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
193 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
194 |         assertEquals(figureJson, setJson);
195 |         evt.validate();
196 | 
197 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
198 |     }
199 | 
200 | 
201 |     /**
202 |      * Figure 6: Example: SET Containing a SSE Event with a Complex Subject Claim
203 |      */
204 | 
205 |     @Test
206 |     public void Figure6() throws ParseException, SIValidationException, ValidationException {
207 |         IssSubSubjectIdentifier user = new IssSubSubjectIdentifier.Builder()
208 |                 .issuer("https://idp.example.com/3957ea72-1b66-44d6-a044-d805712b9288/")
209 |                 .subject("jane.smith@example.com")
210 |                 .build();
211 | 
212 |         IssSubSubjectIdentifier device = new IssSubSubjectIdentifier.Builder()
213 |                 .issuer("https://idp.example.com/3957ea72-1b66-44d6-a044-d805712b9288/")
214 |                 .subject("e9297990-14d2-42ec-a4a9-4036db86509a")
215 |                 .build();
216 | 
217 |         SubjectIdentifier subj = new SubjectIdentifier.Builder()
218 |                 .user(user)
219 |                 .device(device)
220 |                 .build();
221 | 
222 |         CAEPSessionRevoked evt = new CAEPSessionRevoked.Builder()
223 |                 .eventTimestamp(1615304991643L)
224 |                 .subject(subj)
225 |                 .build();
226 | 
227 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
228 |                 .issuer("https://idp.example.com/")
229 |                 .jwtID("756E69717565206964656E746966696572")
230 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1520364019))
231 |                 .audience("636C69656E745F6964")
232 |                 .claim(SEToken.EVENTS_CLAIM, evt)
233 |                 .build();
234 | 
235 |         final String figure_text = "{\n" +
236 |                 "  \"iss\": \"https://idp.example.com/\",\n" +
237 |                 "  \"jti\": \"756E69717565206964656E746966696572\",\n" +
238 |                 "  \"iat\": 1520364019,\n" +
239 |                 "  \"aud\": \"636C69656E745F6964\",\n" +
240 |                 "  \"events\": {\n" +
241 |                 "    \"https://schemas.openid.net/secevent/caep/event-type/session-revoked\": {\n" +
242 |                 "    \"subject\": {\n" +
243 |                 "        \"user\": {\n" +
244 |                 "            \"format\": \"iss_sub\",\n" +
245 |                 "            \"iss\": \"https://idp.example.com/3957ea72-1b66-44d6-a044-d805712b9288/\",\n" +
246 |                 "            \"sub\": \"jane.smith@example.com\"\n" +
247 |                 "        },\n" +
248 |                 "        \"device\": {\n" +
249 |                 "            \"format\": \"iss_sub\",\n" +
250 |                 "            \"iss\": \"https://idp.example.com/3957ea72-1b66-44d6-a044-d805712b9288/\",\n" +
251 |                 "            \"sub\": \"e9297990-14d2-42ec-a4a9-4036db86509a\"\n" +
252 |                 "        }\n" + // closes device
253 |                 "      },\n" + // closes subject
254 |                 "   \"event_timestamp\": 1615304991643\n" +
255 |                 "    }\n" +
256 |                 "  }\n" +
257 |                 "}\n";
258 | 
259 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
260 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
261 |         assertEquals(figureJson, setJson);
262 |         evt.validate();
263 | 
264 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
265 |     }
266 | 
267 | 
268 |     /**
269 |      * Figure 7: Example: SET Containing a SSE Event with a Simple Subject
270 |      * and a Property Claim
271 |      */
272 |     @Test()
273 |     public void Figure7() throws ParseException, SIValidationException, ValidationException {
274 |         EmailSubjectIdentifier subj = new EmailSubjectIdentifier.Builder()
275 |                 .email("foo@example2.com")
276 |                 .build();
277 | 
278 |         JSONObject newClaims = new JSONObject();
279 |         newClaims.put("ip_address", "123.45.67.89");
280 | 
281 |         CAEPTokenClaimsChange evt = new CAEPTokenClaimsChange.Builder()
282 |                 .eventTimestamp(1615304991643L)
283 |                 .subject(subj)
284 |                 .claims(newClaims)
285 |                 .build();
286 | 
287 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
288 |                 .issuer("https://sp.example2.com/")
289 |                 .jwtID("756E69717565206964656E746966696572")
290 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1520364019))
291 |                 .audience("636C69656E745F6964")
292 |                 .claim(SEToken.EVENTS_CLAIM, evt)
293 |                 .build();
294 | 
295 |         final String figure_text = "{\n" +
296 |                 "  \"iss\": \"https://sp.example2.com/\",\n" +
297 |                 "  \"jti\": \"756E69717565206964656E746966696572\",\n" +
298 |                 "  \"iat\": 1520364019,\n" +
299 |                 "  \"aud\": \"636C69656E745F6964\",\n" +
300 |                 "  \"events\": {\n" +
301 |                 "    \"https://schemas.openid.net/secevent/caep/event-type/token-claims-change\": {\n" +
302 |                 "      \"subject\": {\n" +
303 |                 "        \"format\": \"email\",\n" +
304 |                 "        \"email\": \"foo@example2.com\"\n" +
305 |                 "      },\n" +
306 |                 "    \"claims\": {\n" +
307 |                 "      \"ip_address\" : \"123.45.67.89\"\n" +
308 |                 "     },\n" +
309 |                 "    \"event_timestamp\": 1615304991643\n" +
310 |                 "    }\n" +
311 |                 "  }\n" +
312 |                 "}";
313 | 
314 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
315 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
316 |         assertEquals(figureJson, setJson);
317 | 
318 |         subj.validate();
319 |         evt.validate();
320 | 
321 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
322 |     }
323 | 
324 |     /**
325 |      * Figure 8: Example: SET Containing a SSE Event with a Proprietary format
326 |      */
327 |     @Test()
328 |     public void Figure8() throws ParseException, SIValidationException, ValidationException {
329 |         SubjectIdentifier subj = new SubjectIdentifier.Builder()
330 |                 .member("format", "catalog_item")
331 |                 .member("catalog_id", "c0384/winter/2354122")
332 |                 .build();
333 | 
334 |         JSONObject newClaims = new JSONObject();
335 |         newClaims.put("role", "ro-admin");
336 | 
337 | 
338 |         CAEPTokenClaimsChange evt = new CAEPTokenClaimsChange.Builder()
339 |                 .eventTimestamp(1600975810L)
340 |                 .subject(subj)
341 |                 .claims(newClaims)
342 |                 .build();
343 | 
344 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
345 |                 .issuer("https://myservice.example3.com/")
346 |                 .jwtID("756E69717565206964656E746966696534")
347 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(15203800012L))
348 |                 .audience("636C69656E745F6324")
349 |                 .claim(SEToken.EVENTS_CLAIM, evt)
350 |                 .build();
351 | 
352 |         final String figure_text = "{\n" +
353 |                 "  \"iss\": \"https://myservice.example3.com/\",\n" +
354 |                 "  \"jti\": \"756E69717565206964656E746966696534\",\n" +
355 |                 "  \"iat\": 15203800012,\n" +
356 |                 "  \"aud\": \"636C69656E745F6324\",\n" +
357 |                 "  \"events\": {\n" +
358 |                 "    \"https://schemas.openid.net/secevent/caep/event-type/token-claims-change\": {\n" +
359 |                 "    \"subject\": {\n" +
360 |                 "        \"format\": \"catalog_item\",\n" +
361 |                 "        \"catalog_id\": \"c0384/winter/2354122\"\n" +
362 |                 "      },\n" +
363 |                 "      \"event_timestamp\": 1600975810,\n" +
364 |                 "      \"claims\": {\n" +
365 |                 "         \"role\": \"ro-admin\"\n" +
366 |                 "      }\n" +
367 |                 "    }\n" +
368 |                 "  }\n" +
369 |                 "}";
370 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
371 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
372 |         assertEquals(figureJson, setJson);
373 | 
374 |         subj.validate();
375 |         evt.validate();
376 | 
377 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
378 |     }
379 | 
380 |     /**
381 |      * SET Containing a SSE Event with a Simple Subject Claim
382 |      * and an undefined event type
383 |      */
384 | 
385 |     @Test
386 |     public void UndefinedEventParseTest() throws ParseException, SIValidationException, ValidationException {
387 |         EmailSubjectIdentifier subj = new EmailSubjectIdentifier.Builder()
388 |                 .email("foo@example.com")
389 |                 .build();
390 | 
391 |         NonstandardSSEvent evt = new NonstandardSSEvent.Builder()
392 |                 .eventName("https://schemas.openid.net/secevent/unknown/event-type/unknown")
393 |                 .subject(subj)
394 |                 .build();
395 | 
396 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
397 |                 .issuer("https://idp.example.com/")
398 |                 .jwtID("756E69717565206964656E746966696572")
399 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1520364019))
400 |                 .audience("636C69656E745F6964")
401 |                 .claim(SEToken.EVENTS_CLAIM, evt)
402 |                 .build();
403 | 
404 |         final String figure_text = "{\n" +
405 |                 "  \"iss\": \"https://idp.example.com/\",\n" +
406 |                 "  \"jti\": \"756E69717565206964656E746966696572\",\n" +
407 |                 "  \"iat\": 1520364019,\n" +
408 |                 "  \"aud\": \"636C69656E745F6964\",\n" +
409 |                 "  \"events\": {\n" +
410 |                 "    \"https://schemas.openid.net/secevent/unknown/event-type/unknown\": {\n" +
411 |                 "      \"subject\": {\n" +
412 |                 "        \"format\": \"email\",\n" +
413 |                 "        \"email\": \"foo@example.com\"\n" +
414 |                 "      }\n" +
415 |                 "    }\n" +
416 |                 "  }\n" +
417 |                 "}";
418 | 
419 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
420 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
421 |         assertEquals(figureJson, setJson);
422 |         evt.validate();
423 | 
424 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
425 |     }
426 | }
427 | 
--------------------------------------------------------------------------------
/src/test/java/com/sailpoint/sse/model/RISCProfileTests.java:
--------------------------------------------------------------------------------
  1 | /*
  2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
  3 |  *
  4 |  * SPDX-License-Identifier: Apache-2.0
  5 |  */
  6 | 
  7 | package com.sailpoint.sse.model;
  8 | 
  9 | import com.nimbusds.jose.shaded.json.JSONObject;
 10 | import com.nimbusds.jose.util.JSONObjectUtils;
 11 | import com.nimbusds.jwt.JWTClaimsSet;
 12 | import com.nimbusds.jwt.util.DateUtils;
 13 | import com.sailpoint.ietf.subjectidentifiers.model.*;
 14 | import com.sailpoint.sse.model.risc.*;
 15 | import org.junit.Test;
 16 | 
 17 | import java.text.ParseException;
 18 | 
 19 | import static org.junit.Assert.assertEquals;
 20 | 
 21 | public class RISCProfileTests {
 22 |     /*
 23 |      *  Figure 1:  Example: Account Credential Change Required
 24 |      */
 25 |     @Test
 26 |     public void Figure1() throws ParseException, SIValidationException, ValidationException {
 27 |         IssSubSubjectIdentifier subj = new IssSubSubjectIdentifier.Builder()
 28 |                 .issuer("https://idp.example.com/")
 29 |                 .subject("7375626A656374")
 30 |                 .build();
 31 | 
 32 |         RISCAccountCredentialChangeRequired evt = new RISCAccountCredentialChangeRequired.Builder()
 33 |                 .subject(subj)
 34 |                 .build();
 35 | 
 36 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
 37 |                 .issuer("https://idp.example.com/")
 38 |                 .jwtID("756E69717565206964656E746966696572")
 39 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1508184845))
 40 |                 .audience("636C69656E745F6964")
 41 |                 .claim(SEToken.EVENTS_CLAIM, evt)
 42 |                 .build();
 43 | 
 44 |         final String figure_text = "   {\n" +
 45 |                 "     \"iss\": \"https://idp.example.com/\",\n" +
 46 |                 "     \"jti\": \"756E69717565206964656E746966696572\",\n" +
 47 |                 "     \"iat\": 1508184845,\n" +
 48 |                 "     \"aud\": \"636C69656E745F6964\",\n" +
 49 |                 "     \"events\": {\n" +
 50 |                 "       \"https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required\": {\n" +
 51 |                 "         \"subject\": {\n" +
 52 |                 "           \"format\": \"iss_sub\",\n" +
 53 |                 "           \"iss\": \"https://idp.example.com/\",\n" +
 54 |                 "           \"sub\": \"7375626A656374\"\n" +
 55 |                 "         }\n" +
 56 |                 "       }\n" +
 57 |                 "     }\n" +
 58 |                 "   }\n";
 59 | 
 60 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
 61 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
 62 |         assertEquals(figureJson, setJson);
 63 |         subj.validate();
 64 |         evt.validate();
 65 | 
 66 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
 67 |     }
 68 | 
 69 | 
 70 |     /**
 71 |      * Figure 2: Example: Account Disabled
 72 |      */
 73 |     @Test
 74 |     public void Figure2() throws ParseException, SIValidationException, ValidationException {
 75 |         IssSubSubjectIdentifier subj = new IssSubSubjectIdentifier.Builder()
 76 |                 .issuer("https://idp.example.com/")
 77 |                 .subject("7375626A656374")
 78 |                 .build();
 79 | 
 80 |         RISCAccountDisabled evt = new RISCAccountDisabled.Builder()
 81 |                 .reason(RISCAccountDisabledReasons.HIJACKING)
 82 |                 .subject(subj)
 83 |                 .build();
 84 | 
 85 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
 86 |                 .issuer("https://idp.example.com/")
 87 |                 .jwtID("756E69717565206964656E746966696572")
 88 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1508184845))
 89 |                 .audience("636C69656E745F6964")
 90 |                 .claim(SEToken.EVENTS_CLAIM, evt)
 91 |                 .build();
 92 | 
 93 |         final String figure_text = "   {\n" +
 94 |                 "     \"iss\": \"https://idp.example.com/\",\n" +
 95 |                 "     \"jti\": \"756E69717565206964656E746966696572\",\n" +
 96 |                 "     \"iat\": 1508184845,\n" +
 97 |                 "     \"aud\": \"636C69656E745F6964\",\n" +
 98 |                 "     \"events\": {\n" +
 99 |                 "       \"https://schemas.openid.net/secevent/risc/event-type/account-disabled\": {\n" +
100 |                 "         \"subject\": {\n" +
101 |                 "           \"format\": \"iss_sub\",\n" +
102 |                 "           \"iss\": \"https://idp.example.com/\",\n" +
103 |                 "           \"sub\": \"7375626A656374\"\n" +
104 |                 "         },\n" +
105 |                 "         \"reason\": \"hijacking\"\n" +
106 |                 "       }\n" +
107 |                 "     }\n" +
108 |                 "   }\n";
109 | 
110 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
111 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
112 |         assertEquals(figureJson, setJson);
113 |         subj.validate();
114 |         evt.validate();
115 | 
116 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
117 |     }
118 | 
119 |     /**
120 |      * Figure 3: Example: Identifier Changed
121 |      */
122 |     @Test
123 |     public void Figure3() throws ParseException, SIValidationException, ValidationException {
124 |         EmailSubjectIdentifier subj = new EmailSubjectIdentifier.Builder()
125 |                 .email("john.doe@example.com")
126 |                 .build();
127 | 
128 |         RISCIdentifierChanged evt = new RISCIdentifierChanged.Builder()
129 |                 .subject(subj)
130 |                 .newValue("john.roe@example.com")
131 |                 .build();
132 | 
133 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
134 |                 .issuer("https://idp.example.com/")
135 |                 .jwtID("756E69717565206964656E746966696572")
136 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1508184845))
137 |                 .audience("636C69656E745F6964")
138 |                 .claim(SEToken.EVENTS_CLAIM, evt)
139 |                 .build();
140 | 
141 |         final String figure_text = "   {\n" +
142 |                 "     \"iss\": \"https://idp.example.com/\",\n" +
143 |                 "     \"jti\": \"756E69717565206964656E746966696572\",\n" +
144 |                 "     \"iat\": 1508184845,\n" +
145 |                 "     \"aud\": \"636C69656E745F6964\",\n" +
146 |                 "     \"events\": {\n" +
147 |                 "       \"https://schemas.openid.net/secevent/risc/event-type/identifier-changed\": {\n" +
148 |                 "         \"subject\": {\n" +
149 |                 "           \"format\": \"email\",\n" +
150 |                 "           \"email\": \"john.doe@example.com\"\n" +
151 |                 "         },\n" +
152 |                 "         \"new-value\": \"john.roe@example.com\"\n" +
153 |                 "       }\n" +
154 |                 "     }\n" +
155 |                 "   }\n";
156 | 
157 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
158 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
159 |         assertEquals(figureJson, setJson);
160 |         subj.validate();
161 |         evt.validate();
162 | 
163 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
164 |     }
165 | 
166 |     /**
167 |      * Figure 4: Example: Identifier Recycled
168 |      */
169 |     @Test
170 |     public void Figure4() throws ParseException, SIValidationException, ValidationException {
171 |         EmailSubjectIdentifier subj = new EmailSubjectIdentifier.Builder()
172 |                 .email("foo@example.com")
173 |                 .build();
174 | 
175 |         RISCIdentifierRecycled evt = new RISCIdentifierRecycled.Builder()
176 |                 .subject(subj)
177 |                 .build();
178 | 
179 |         JWTClaimsSet set = new JWTClaimsSet.Builder()
180 |                 .issuer("https://idp.example.com/")
181 |                 .jwtID("756E69717565206964656E746966696572")
182 |                 .issueTime(DateUtils.fromSecondsSinceEpoch(1508184845))
183 |                 .audience("636C69656E745F6964")
184 |                 .claim(SEToken.EVENTS_CLAIM, evt)
185 |                 .build();
186 | 
187 |         final String figure_text = "   {\n" +
188 |                 "     \"iss\": \"https://idp.example.com/\",\n" +
189 |                 "     \"jti\": \"756E69717565206964656E746966696572\",\n" +
190 |                 "     \"iat\": 1508184845,\n" +
191 |                 "     \"aud\": \"636C69656E745F6964\",\n" +
192 |                 "     \"events\": {\n" +
193 |                 "       \"https://schemas.openid.net/secevent/risc/event-type/identifier-recycled\": {\n" +
194 |                 "         \"subject\": {\n" +
195 |                 "           \"format\": \"email\",\n" +
196 |                 "           \"email\": \"foo@example.com\"\n" +
197 |                 "         }\n" +
198 |                 "       }\n" +
199 |                 "     }\n" +
200 |                 "   }\n";
201 | 
202 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
203 |         final JSONObject setJson = new JSONObject(set.toJSONObject());
204 |         assertEquals(figureJson, setJson);
205 |         subj.validate();
206 |         evt.validate();
207 | 
208 |         JWTClaimsSet parsedSet = SEToken.parse(figure_text);
209 |     }
210 | }
211 | 
--------------------------------------------------------------------------------
/src/test/java/com/sailpoint/sse/model/TransmitterConfigTest.java:
--------------------------------------------------------------------------------
 1 | /*
 2 |  * Copyright (c) 2021 SailPoint Technologies, Inc.
 3 |  *
 4 |  * SPDX-License-Identifier: Apache-2.0
 5 |  */
 6 | 
 7 | package com.sailpoint.sse.model;
 8 | 
 9 | import com.nimbusds.jose.shaded.json.JSONObject;
10 | import com.nimbusds.jose.util.JSONObjectUtils;
11 | import org.junit.Test;
12 | 
13 | import java.text.ParseException;
14 | import java.util.ArrayList;
15 | import java.util.Arrays;
16 | 
17 | import static org.junit.Assert.assertEquals;
18 | 
19 | public class TransmitterConfigTest {
20 | 
21 |     @Test()
22 |     public void Figure15() throws ParseException {
23 |         final String iss = "https://tr.example.com";
24 |         final String ssePrefix = "/sse/mgmt";
25 |         final String[] deliveryMethods = {DeliveryMethods.PUSH.toString(),
26 |                 DeliveryMethods.POLL.toString()};
27 |         final ArrayList criticalMembers = new ArrayList<>(Arrays.asList("tenant", "user"));
28 | 
29 |         TransmitterConfig txCfg = new TransmitterConfig.Builder()
30 |                 .issuer(iss)
31 |                 .jwksUri(iss + "/jwks.json")
32 |                 .deliveryMethods(Arrays.asList(deliveryMethods))
33 |                 .configurationEndpoint(iss + ssePrefix + "/stream")
34 |                 .statusEndpoint(iss + ssePrefix + "/status")
35 |                 .addSubjectEndpoint(iss + ssePrefix + "/subject:add")
36 |                 .removeSubjectEndpoint(iss + ssePrefix + "/subject:remove")
37 |                 .verificationEndpoint(iss + ssePrefix + "/verification")
38 |                 .criticalSubjectMembers(criticalMembers)
39 |                 .build();
40 | 
41 |         final String figure_text = "   {\n" +
42 |                 "     \"issuer\":\n" +
43 |                 "       \"https://tr.example.com\",\n" +
44 |                 "     \"jwks_uri\":\n" +
45 |                 "       \"https://tr.example.com/jwks.json\",\n" +
46 |                 "     \"delivery_methods_supported\": [\n" +
47 |                 "       \"https://schemas.openid.net/secevent/risc/delivery-method/push\",\n" +
48 |                 "       \"https://schemas.openid.net/secevent/risc/delivery-method/poll\"],\n" +
49 |                 "     \"configuration_endpoint\":\n" +
50 |                 "       \"https://tr.example.com/sse/mgmt/stream\",\n" +
51 |                 "     \"status_endpoint\":\n" +
52 |                 "       \"https://tr.example.com/sse/mgmt/status\",\n" +
53 |                 "     \"add_subject_endpoint\":\n" +
54 |                 "       \"https://tr.example.com/sse/mgmt/subject:add\",\n" +
55 |                 "     \"remove_subject_endpoint\":\n" +
56 |                 "       \"https://tr.example.com/sse/mgmt/subject:remove\",\n" +
57 |                 "     \"verification_endpoint\":\n" +
58 |                 "       \"https://tr.example.com/sse/mgmt/verification\",\n" +
59 |                 "     \"critical_subject_members\": [ \"tenant\", \"user\" ]\n" +
60 |                 "   }";
61 | 
62 |         final JSONObject figureJson = new JSONObject(JSONObjectUtils.parse(figure_text));
63 |         assertEquals(figureJson, txCfg);
64 |     }
65 | 
66 | }
67 | 
--------------------------------------------------------------------------------