Skip to content

Commit 9ccd837

Browse files
committed
handle revocation events through single stream and publisher. refactor code.
1 parent 3d44b52 commit 9ccd837

File tree

11 files changed

+145
-261
lines changed

11 files changed

+145
-261
lines changed

components/apimgt/org.wso2.carbon.apimgt.gateway/src/main/java/org/wso2/carbon/apimgt/gateway/listeners/GatewayTokenRevocationMessageListener.java

+56-48
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,20 @@
2121
import com.fasterxml.jackson.core.JsonProcessingException;
2222
import com.fasterxml.jackson.databind.JsonNode;
2323
import com.fasterxml.jackson.databind.ObjectMapper;
24+
import org.apache.commons.codec.binary.Base64;
2425
import org.apache.commons.lang3.StringUtils;
2526
import org.apache.commons.logging.Log;
2627
import org.apache.commons.logging.LogFactory;
2728
import org.wso2.carbon.apimgt.gateway.internal.ServiceReferenceHolder;
2829
import org.wso2.carbon.apimgt.gateway.jwt.RevokedJWTDataHolder;
2930
import org.wso2.carbon.apimgt.impl.APIConstants;
3031

31-
import javax.jms.*;
32+
import javax.jms.JMSException;
33+
import javax.jms.Message;
34+
import javax.jms.MessageListener;
35+
import javax.jms.TextMessage;
36+
import javax.jms.Topic;
37+
import java.util.HashMap;
3238

3339
public class GatewayTokenRevocationMessageListener implements MessageListener {
3440

@@ -58,25 +64,6 @@ public void onMessage(Message message) {
5864
payloadData.get(APIConstants.REVOKED_TOKEN_EXPIRY_TIME).asLong(),
5965
payloadData.get(APIConstants.REVOKED_TOKEN_TYPE).asText());
6066
}
61-
62-
if (payloadData.get(APIConstants.INTERNAL_REVOCATION_EVENT_TYPE) != null
63-
&& payloadData.get(APIConstants.INTERNAL_REVOCATION_EVENT_TYPE).asText()
64-
.equals(APIConstants.NotificationEvent.CONSUMER_APP_REVOCATION_EVENT)) {
65-
handleInternallyRevokedConsumerKeyMessage(
66-
payloadData.get(APIConstants.INTERNAL_REVOCATION_CONSUMER_KEY).asText(),
67-
payloadData.get(APIConstants.INTERNAL_REVOCATION_TIME).asLong(),
68-
payloadData.get(APIConstants.INTERNAL_REVOCATION_EVENT_TYPE).asText());
69-
}
70-
71-
if (payloadData.get(APIConstants.INTERNAL_REVOCATION_EVENT_TYPE) != null
72-
&& payloadData.get(APIConstants.INTERNAL_REVOCATION_EVENT_TYPE).asText()
73-
.equals(APIConstants.NotificationEvent.SUBJECT_ENTITY_REVOCATION_EVENT)) {
74-
handleInternallyRevokedUserEventMessage(
75-
payloadData.get(APIConstants.INTERNAL_REVOCATION_ENTITY_ID).asText(),
76-
payloadData.get(APIConstants.INTERNAL_REVOCATION_ENTITY_TYPE).asText(),
77-
payloadData.get(APIConstants.INTERNAL_REVOCATION_TIME).asLong(),
78-
payloadData.get(APIConstants.INTERNAL_REVOCATION_EVENT_TYPE).asText());
79-
}
8067
}
8168
} else {
8269
log.warn("Event dropped due to unsupported message type " + message.getClass());
@@ -89,45 +76,66 @@ public void onMessage(Message message) {
8976
}
9077
}
9178

92-
private void handleRevokedTokenMessage(String revokedToken, long expiryTime,String tokenType) {
79+
private void handleRevokedTokenMessage(String revokedToken, long expiryTime, String tokenType) {
9380

9481
boolean isJwtToken = false;
9582
if (StringUtils.isEmpty(revokedToken)) {
9683
return;
9784
}
9885

99-
//handle JWT tokens
100-
if (APIConstants.API_KEY_AUTH_TYPE.equals(tokenType) || APIConstants.JWT.equals(tokenType)) {
101-
ServiceReferenceHolder.getInstance().getRevokedTokenService()
102-
.addRevokedJWTIntoMap(revokedToken, expiryTime);
103-
// Add revoked token to revoked JWT map
104-
isJwtToken = true;
105-
}
106-
if (APIConstants.API_KEY_AUTH_TYPE.equals(tokenType)) {
107-
ServiceReferenceHolder.getInstance().getRevokedTokenService()
108-
.removeApiKeyFromGatewayCache(revokedToken);
86+
if (APIConstants.NotificationEvent.CONSUMER_APP_REVOCATION_EVENT.equals(tokenType)) {
87+
HashMap<String, Object> revokedTokenMap = base64Decode(revokedToken);
88+
if (revokedTokenMap.containsKey(APIConstants.NotificationEvent.CONSUMER_KEY) &&
89+
revokedTokenMap.get(APIConstants.NotificationEvent.CONSUMER_KEY) != null &&
90+
revokedTokenMap.containsKey(APIConstants.NotificationEvent.REVOCATION_TIME) &&
91+
revokedTokenMap.get(APIConstants.NotificationEvent.REVOCATION_TIME) != null) {
92+
RevokedJWTDataHolder.getInstance().addRevokedConsumerKeyToMap(
93+
(String) revokedTokenMap.get(APIConstants.NotificationEvent.CONSUMER_KEY),
94+
(long) revokedTokenMap.get(APIConstants.NotificationEvent.REVOCATION_TIME));
95+
}
96+
} else if (APIConstants.NotificationEvent.SUBJECT_ENTITY_REVOCATION_EVENT.equals(tokenType)) {
97+
HashMap<String, Object> revokedTokenMap = base64Decode(revokedToken);
98+
if (revokedTokenMap.get(APIConstants.NotificationEvent.ENTITY_TYPE) != null &&
99+
revokedTokenMap.get(APIConstants.NotificationEvent.REVOCATION_TIME) != null &&
100+
revokedTokenMap.get(APIConstants.NotificationEvent.ENTITY_ID) != null) {
101+
String entityType = (String) revokedTokenMap.get(APIConstants.NotificationEvent.ENTITY_TYPE);
102+
long revocationTime = (long) revokedTokenMap.get(APIConstants.NotificationEvent.REVOCATION_TIME);
103+
String entityId = (String) revokedTokenMap.get(APIConstants.NotificationEvent.ENTITY_ID);
104+
if (APIConstants.NotificationEvent.ENTITY_TYPE_USER_ID.equals(entityType)) {
105+
RevokedJWTDataHolder.getInstance().addRevokedSubjectEntityUserToMap(entityId, revocationTime);
106+
} else if (APIConstants.NotificationEvent.ENTITY_TYPE_CLIENT_ID.equals(entityType)) {
107+
RevokedJWTDataHolder.getInstance()
108+
.addRevokedSubjectEntityConsumerAppToMap(entityId, revocationTime);
109+
}
110+
}
109111
} else {
110-
ServiceReferenceHolder.getInstance().getRevokedTokenService()
111-
.removeTokenFromGatewayCache(revokedToken, isJwtToken);
112-
}
113-
}
114-
115-
private void handleInternallyRevokedConsumerKeyMessage(String consumerKey, long revocationTime, String type) {
116-
if (APIConstants.NotificationEvent.CONSUMER_APP_REVOCATION_EVENT.equals(type)) {
117-
RevokedJWTDataHolder.getInstance().addRevokedConsumerKeyToMap(consumerKey, revocationTime);
112+
//handle JWT tokens
113+
if (APIConstants.API_KEY_AUTH_TYPE.equals(tokenType) || APIConstants.JWT.equals(tokenType)) {
114+
ServiceReferenceHolder.getInstance().getRevokedTokenService()
115+
.addRevokedJWTIntoMap(revokedToken, expiryTime);
116+
// Add revoked token to revoked JWT map
117+
isJwtToken = true;
118+
}
119+
if (APIConstants.API_KEY_AUTH_TYPE.equals(tokenType)) {
120+
ServiceReferenceHolder.getInstance().getRevokedTokenService()
121+
.removeApiKeyFromGatewayCache(revokedToken);
122+
} else {
123+
ServiceReferenceHolder.getInstance().getRevokedTokenService()
124+
.removeTokenFromGatewayCache(revokedToken, isJwtToken);
125+
}
118126
}
119127
}
120128

121-
private void handleInternallyRevokedUserEventMessage(String subjectId, String subjectIdType,
122-
long revocationTime, String type) {
129+
private HashMap<String, Object> base64Decode(String encodedRevokedToken) {
123130

124-
if (APIConstants.NotificationEvent.SUBJECT_ENTITY_REVOCATION_EVENT.equals(type)) {
125-
if ("USER_ID".equals(subjectIdType)) {
126-
RevokedJWTDataHolder.getInstance().addRevokedSubjectEntityUserToMap(subjectId, revocationTime);
127-
} else if ("CLIENT_ID".equals(subjectIdType)) {
128-
RevokedJWTDataHolder.getInstance().addRevokedSubjectEntityConsumerAppToMap(subjectId,
129-
revocationTime);
130-
}
131+
byte[] eventDecoded = Base64.decodeBase64(encodedRevokedToken);
132+
String eventJson = new String(eventDecoded);
133+
ObjectMapper objectMapper = new ObjectMapper();
134+
try {
135+
return objectMapper.readValue(eventJson, HashMap.class);
136+
} catch (JsonProcessingException e) {
137+
log.error("Error while decoding revoked token event.");
131138
}
139+
return new HashMap<>();
132140
}
133141
}

components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java

+2-8
Original file line numberDiff line numberDiff line change
@@ -565,9 +565,6 @@ public final class APIConstants {
565565
public static final String IS_ENABLED = "is_enabled";
566566
public static final String BLOCKING_CONDITIONS_STREAM_ID = "org.wso2.blocking.request.stream:1.0.0";
567567
public static final String TOKEN_REVOCATION_STREAM_ID = "org.wso2.apimgt.token.revocation.stream:1.0.0";
568-
public static final String SUBJECT_ENTITY_REVOCATION_STREAM_ID =
569-
"org.wso2.apimgt.subjectEntity.revocation.stream:1.0.0";
570-
public static final String APP_REVOCATION_EVENT_STREAM_ID = "org.wso2.apimgt.app.revocation.stream:1.0.0";
571568
public static final String CACHE_INVALIDATION_STREAM_ID = "org.wso2.apimgt.cache.invalidation.stream:1.0.0";
572569
public static final String NOTIFICATION_STREAM_ID = "org.wso2.apimgt.notification.stream:1.0.0";
573570
public static final String WEBHOOKS_SUBSCRIPTION_STREAM_ID = "org.wso2.apimgt.webhooks.request.stream:1.0.0";
@@ -593,11 +590,6 @@ public final class APIConstants {
593590
public static final String KEY_MANAGER_CONSUMER_KEY = "consumer_key";
594591
public static final String KEY_MANAGER_CONSUMER_SECRET = "consumer_secret";
595592
public static final String REVOKED_TOKEN_TYPE = "type";
596-
public static final String INTERNAL_REVOCATION_EVENT_TYPE = "type";
597-
public static final String INTERNAL_REVOCATION_TIME = "revocationTime";
598-
public static final String INTERNAL_REVOCATION_CONSUMER_KEY = "consumerKey";
599-
public static final String INTERNAL_REVOCATION_ENTITY_ID = "entityId";
600-
public static final String INTERNAL_REVOCATION_ENTITY_TYPE = "entityType";
601593
public static final String IDENTITY_REVOKE_ENDPOINT = "/oauth2/revoke";
602594
public static final String IDENTITY_TOKEN_ENDPOINT_CONTEXT = "/oauth2/token";
603595
public static final String GATEWAY_SIGNED_JWT_CACHE = "SignedJWTParseCache";
@@ -2841,6 +2833,8 @@ public static class NotificationEvent {
28412833
public static final String STREAM_ID = "streamId";
28422834
public static final String ENTITY_ID = "entityId";
28432835
public static final String ENTITY_TYPE = "entityType";
2836+
public static final String ENTITY_TYPE_CLIENT_ID = "CLIENT_ID";
2837+
public static final String ENTITY_TYPE_USER_ID = "USER_ID";
28442838
public static final String EVENT_TYPE = "eventType";
28452839
}
28462840

components/apimgt/org.wso2.carbon.apimgt.notification/src/main/java/org/wso2/carbon/apimgt/notification/AbstractKeyManagerEventHandler.java

+20-27
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.wso2.carbon.apimgt.impl.keymgt.KeyManagerEventHandler;
2828
import org.wso2.carbon.apimgt.impl.publishers.RevocationRequestPublisher;
2929
import org.wso2.carbon.apimgt.notification.event.ConsumerAppRevocationEvent;
30+
import org.wso2.carbon.apimgt.notification.event.Event;
3031
import org.wso2.carbon.apimgt.notification.event.SubjectEntityRevocationEvent;
3132
import org.wso2.carbon.apimgt.notification.event.TokenRevocationEvent;
3233

@@ -46,18 +47,14 @@ public AbstractKeyManagerEventHandler() {
4647

4748
public boolean handleTokenRevocationEvent(TokenRevocationEvent tokenRevocationEvent) throws APIManagementException {
4849

49-
Properties properties = new Properties();
50-
properties.setProperty(APIConstants.NotificationEvent.EVENT_ID, tokenRevocationEvent.getEventId());
50+
Properties properties = getRevocationEventProperties(tokenRevocationEvent);
51+
properties.setProperty(APIConstants.NotificationEvent.EXPIRY_TIME,
52+
Long.toString(tokenRevocationEvent.getExpiryTime()));
5153
properties.put(APIConstants.NotificationEvent.CONSUMER_KEY, tokenRevocationEvent.getConsumerKey());
5254
if (StringUtils.isBlank(tokenRevocationEvent.getTokenType())) {
5355
tokenRevocationEvent.setTokenType(APIConstants.NotificationEvent.APPLICATION_TOKEN_TYPE_OAUTH2);
5456
}
5557
properties.put(APIConstants.NotificationEvent.TOKEN_TYPE, tokenRevocationEvent.getTokenType());
56-
properties.put(APIConstants.NotificationEvent.TENANT_ID, tokenRevocationEvent.getTenantId());
57-
properties.put(APIConstants.NotificationEvent.TENANT_DOMAIN, tokenRevocationEvent.getTenantDomain());
58-
properties.put(APIConstants.NotificationEvent.STREAM_ID, APIConstants.TOKEN_REVOCATION_STREAM_ID);
59-
properties.setProperty(APIConstants.NotificationEvent.EXPIRY_TIME,
60-
Long.toString(tokenRevocationEvent.getExpiryTime()));
6158
ApiMgtDAO.getInstance().addRevokedJWTSignature(tokenRevocationEvent.getEventId(),
6259
tokenRevocationEvent.getAccessToken(), tokenRevocationEvent.getTokenType(),
6360
tokenRevocationEvent.getExpiryTime(), tokenRevocationEvent.getTenantId());
@@ -67,9 +64,7 @@ public boolean handleTokenRevocationEvent(TokenRevocationEvent tokenRevocationEv
6764
String orgId = application.getOrganization();
6865
properties.put(APIConstants.NotificationEvent.ORG_ID, orgId);
6966
}
70-
7167
revocationRequestPublisher.publishRevocationEvents(tokenRevocationEvent.getAccessToken(), properties);
72-
7368
// Cleanup expired revoked tokens from db.
7469
Runnable expiredJWTCleaner = new ExpiredJWTCleaner();
7570
Thread cleanupThread = new Thread(expiredJWTCleaner);
@@ -80,20 +75,13 @@ public boolean handleTokenRevocationEvent(TokenRevocationEvent tokenRevocationEv
8075
public boolean handleConsumerAppRevocationEvent(ConsumerAppRevocationEvent consumerKeyEvent)
8176
throws APIManagementException {
8277

83-
// rule persistence
8478
ApiMgtDAO.getInstance().addRevokedConsumerKey(consumerKeyEvent.getConsumerKey(),
8579
consumerKeyEvent.getRevocationTime(), consumerKeyEvent.getTenantDomain());
86-
8780
// set properties
88-
Properties properties = new Properties();
89-
properties.setProperty(APIConstants.NotificationEvent.EVENT_ID, consumerKeyEvent.getEventId());
81+
Properties properties = getRevocationEventProperties(consumerKeyEvent);
9082
properties.setProperty(APIConstants.NotificationEvent.CONSUMER_KEY, consumerKeyEvent.getConsumerKey());
9183
properties.setProperty(APIConstants.NotificationEvent.REVOCATION_TIME,
9284
Long.toString(consumerKeyEvent.getRevocationTime()));
93-
properties.setProperty(APIConstants.NotificationEvent.ORGANIZATION, consumerKeyEvent.getTenantDomain());
94-
properties.setProperty(APIConstants.NotificationEvent.EVENT_TYPE, consumerKeyEvent.getType());
95-
properties.setProperty(APIConstants.NotificationEvent.STREAM_ID,
96-
APIConstants.APP_REVOCATION_EVENT_STREAM_ID);
9785

9886
// publish event
9987
revocationRequestPublisher.publishRevocationEvents(consumerKeyEvent.getConsumerKey(), properties);
@@ -102,24 +90,29 @@ public boolean handleConsumerAppRevocationEvent(ConsumerAppRevocationEvent consu
10290

10391
public void handleSubjectEntityRevocationEvent(SubjectEntityRevocationEvent userEvent)
10492
throws APIManagementException {
105-
// persistence
106-
ApiMgtDAO.getInstance().addRevokedSubjectEntity(userEvent.getEntityId(),
107-
userEvent.getEntityType(), userEvent.getRevocationTime(),
108-
userEvent.getTenantDomain());
10993

94+
ApiMgtDAO.getInstance().addRevokedSubjectEntity(userEvent.getEntityId(), userEvent.getEntityType(),
95+
userEvent.getRevocationTime(), userEvent.getTenantDomain());
11096
// set properties
111-
Properties properties = new Properties();
112-
properties.setProperty(APIConstants.NotificationEvent.EVENT_ID, userEvent.getEventId());
97+
Properties properties = getRevocationEventProperties(userEvent);
11398
properties.setProperty(APIConstants.NotificationEvent.ENTITY_ID, userEvent.getEntityId());
11499
properties.setProperty(APIConstants.NotificationEvent.ENTITY_TYPE, userEvent.getEntityType());
115100
properties.setProperty(APIConstants.NotificationEvent.REVOCATION_TIME,
116101
Long.toString(userEvent.getRevocationTime()));
117-
properties.setProperty(APIConstants.NotificationEvent.ORGANIZATION, userEvent.getTenantDomain());
118-
properties.setProperty(APIConstants.NotificationEvent.EVENT_TYPE, userEvent.getType());
119-
properties.setProperty(APIConstants.NotificationEvent.STREAM_ID,
120-
APIConstants.SUBJECT_ENTITY_REVOCATION_STREAM_ID);
121102

122103
// publish event
123104
revocationRequestPublisher.publishRevocationEvents(userEvent.getEntityId(), properties);
124105
}
106+
107+
private Properties getRevocationEventProperties(Event event) {
108+
109+
Properties properties = new Properties();
110+
properties.setProperty(APIConstants.NotificationEvent.EVENT_ID, event.getEventId());
111+
properties.put(APIConstants.NotificationEvent.TENANT_ID, event.getTenantId());
112+
properties.setProperty(APIConstants.NotificationEvent.TENANT_DOMAIN, event.getTenantDomain());
113+
properties.setProperty(APIConstants.NotificationEvent.EVENT_TYPE, event.getType());
114+
properties.setProperty(APIConstants.NotificationEvent.STREAM_ID,
115+
APIConstants.TOKEN_REVOCATION_STREAM_ID);
116+
return properties;
117+
}
125118
}

components/apimgt/org.wso2.carbon.apimgt.notification/src/main/java/org/wso2/carbon/apimgt/notification/DefaultKeyManagerEventHandlerImpl.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ public boolean handleEvent(String event, Map<String, List<String>> headers) thro
3939

4040
if (StringUtils.isNotEmpty(event)
4141
&& event.contains(APIConstants.NotificationEvent.CONSUMER_APP_REVOCATION_EVENT)) {
42-
handleInternalTokenRevocationByConsumerAppEvent(event);
42+
handleConsumerAppRevocationEvent(event);
4343
} else if (StringUtils.isNotEmpty(event)
4444
&& event.contains(APIConstants.NotificationEvent.SUBJECT_ENTITY_REVOCATION_EVENT)) {
45-
handleInternalTokenRevocationBySubjectEntityEvent(event);
45+
handleSubjectEntityRevocationEvent(event);
4646
} else if (StringUtils.isNotEmpty(event)
4747
&& event.contains(APIConstants.NotificationEvent.TOKEN_REVOCATION_EVENT)) {
4848
handleTokenRevocationEvent(event);
@@ -63,14 +63,14 @@ private boolean handleTokenRevocationEvent(String event) throws APIManagementExc
6363
return true;
6464
}
6565

66-
private boolean handleInternalTokenRevocationByConsumerAppEvent(String event) throws APIManagementException {
66+
private boolean handleConsumerAppRevocationEvent(String event) throws APIManagementException {
6767

6868
ConsumerAppRevocationEvent tokenRevocationEvent = new Gson().fromJson(event, ConsumerAppRevocationEvent.class);
6969
handleConsumerAppRevocationEvent(tokenRevocationEvent);
7070
return true;
7171
}
7272

73-
private boolean handleInternalTokenRevocationBySubjectEntityEvent(String event) throws APIManagementException {
73+
private boolean handleSubjectEntityRevocationEvent(String event) throws APIManagementException {
7474

7575
SubjectEntityRevocationEvent tokenRevocationEvent =
7676
new Gson().fromJson(event, SubjectEntityRevocationEvent.class);

0 commit comments

Comments
 (0)