Added trivial implementation of ACL patterns
This commit is contained in:
@@ -299,7 +299,7 @@ class ProtocolProcessor implements EventHandler<ValueEvent> {
|
||||
boolean retain = msg.isRetainFlag();
|
||||
//check if the topic can be wrote
|
||||
String user = (String) session.getAttribute(NettyChannel.ATTR_KEY_USERNAME);
|
||||
if (m_authorizator.canWrite(topic, user)) {
|
||||
if (m_authorizator.canWrite(topic, user, clientID)) {
|
||||
processPublish(clientID, topic, qos, message, retain, msg.getMessageID());
|
||||
} else {
|
||||
LOG.debug("topic {} doesn't have write credentials", topic);
|
||||
@@ -439,7 +439,7 @@ class ProtocolProcessor implements EventHandler<ValueEvent> {
|
||||
LOG.debug("Session for clientId {} is {}", clientId, session);
|
||||
|
||||
String user = (String) session.getAttribute(NettyChannel.ATTR_KEY_USERNAME);
|
||||
if (!m_authorizator.canRead(topic, user)) {
|
||||
if (!m_authorizator.canRead(topic, user, clientId)) {
|
||||
LOG.debug("topic {} doesn't have read credentials", topic);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public class Authorization {
|
||||
* */
|
||||
enum Permission {
|
||||
READ, WRITE, READWRITE
|
||||
};
|
||||
}
|
||||
|
||||
Authorization(String topic) {
|
||||
this(topic, Permission.READWRITE);
|
||||
|
||||
+43
-22
@@ -42,6 +42,7 @@ class AuthorizationsCollector implements IAuthorizator {
|
||||
private List<Authorization> m_patternAuthorizations = new ArrayList();
|
||||
private Map<String, List<Authorization>> m_userAuthorizations = new HashMap();
|
||||
private boolean m_parsingUsersSpecificSection = false;
|
||||
private boolean m_parsingPatternSpecificSection = false;
|
||||
private String m_currentUser = "";
|
||||
|
||||
static final AuthorizationsCollector emptyImmutableCollector() {
|
||||
@@ -65,6 +66,8 @@ class AuthorizationsCollector implements IAuthorizator {
|
||||
}
|
||||
List<Authorization> userAuths = m_userAuthorizations.get(m_currentUser);
|
||||
userAuths.add(acl);
|
||||
} else if (m_parsingPatternSpecificSection) {
|
||||
m_patternAuthorizations.add(acl);
|
||||
} else {
|
||||
m_globalAuthorizations.add(acl);
|
||||
}
|
||||
@@ -75,43 +78,50 @@ class AuthorizationsCollector implements IAuthorizator {
|
||||
String keyword = tokens[0].toLowerCase();
|
||||
switch (keyword) {
|
||||
case "topic":
|
||||
if (tokens.length > 2) {
|
||||
//if the tokenized lines has 3 token the second must be the permission
|
||||
try {
|
||||
Authorization.Permission permission = Authorization.Permission.valueOf(tokens[1].toUpperCase());
|
||||
//bring topic with all original spacing
|
||||
String topic = line.substring(line.indexOf(tokens[2]));
|
||||
|
||||
return new Authorization(topic, permission);
|
||||
} catch (IllegalArgumentException iaex) {
|
||||
throw new ParseException("invalid permission token", 1);
|
||||
}
|
||||
}
|
||||
String topic = tokens[1];
|
||||
return new Authorization(topic);
|
||||
return createAuthorization(line, tokens);
|
||||
case "user":
|
||||
m_parsingUsersSpecificSection = true;
|
||||
m_currentUser = tokens[1];
|
||||
m_parsingPatternSpecificSection = false;
|
||||
return null;
|
||||
case "pattern":
|
||||
//TODO implement the part for patter matching
|
||||
return null;
|
||||
m_parsingUsersSpecificSection = false;
|
||||
m_currentUser = "";
|
||||
m_parsingPatternSpecificSection = true;
|
||||
return createAuthorization(line, tokens);
|
||||
default:
|
||||
throw new ParseException(String.format("invalid line definition found %s", line), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canWrite(String topic, String user) {
|
||||
return canDoOperation(topic, WRITE, user);
|
||||
private Authorization createAuthorization(String line, String[] tokens) throws ParseException {
|
||||
if (tokens.length > 2) {
|
||||
//if the tokenized lines has 3 token the second must be the permission
|
||||
try {
|
||||
Authorization.Permission permission = Authorization.Permission.valueOf(tokens[1].toUpperCase());
|
||||
//bring topic with all original spacing
|
||||
String topic = line.substring(line.indexOf(tokens[2]));
|
||||
|
||||
return new Authorization(topic, permission);
|
||||
} catch (IllegalArgumentException iaex) {
|
||||
throw new ParseException("invalid permission token", 1);
|
||||
}
|
||||
}
|
||||
String topic = tokens[1];
|
||||
return new Authorization(topic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRead(String topic, String user) {
|
||||
return canDoOperation(topic, READ, user);
|
||||
public boolean canWrite(String topic, String user, String client) {
|
||||
return canDoOperation(topic, WRITE, user, client);
|
||||
}
|
||||
|
||||
private boolean canDoOperation(String topic, Authorization.Permission permission, String username) {
|
||||
@Override
|
||||
public boolean canRead(String topic, String user, String client) {
|
||||
return canDoOperation(topic, READ, user, client);
|
||||
}
|
||||
|
||||
private boolean canDoOperation(String topic, Authorization.Permission permission, String username, String client) {
|
||||
for (Authorization auth : m_globalAuthorizations) {
|
||||
if (auth.permission == permission || auth.permission == READWRITE) {
|
||||
if (SubscriptionsStore.matchTopics(topic, auth.topic)) {
|
||||
@@ -120,6 +130,17 @@ class AuthorizationsCollector implements IAuthorizator {
|
||||
}
|
||||
}
|
||||
|
||||
if (client != null && !client.isEmpty()) {
|
||||
for (Authorization auth : m_patternAuthorizations) {
|
||||
String substitutedTopic = auth.topic.replace("%c", client);
|
||||
if (auth.permission == permission || auth.permission == READWRITE) {
|
||||
if (SubscriptionsStore.matchTopics(topic, substitutedTopic)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (username != null && !username.isEmpty()) {
|
||||
if (m_userAuthorizations.containsKey(username)) {
|
||||
for (Authorization auth : m_userAuthorizations.get(username)) {
|
||||
|
||||
+2
-2
@@ -20,12 +20,12 @@ package org.eclipse.moquette.spi.impl.security;
|
||||
*/
|
||||
public class DenyAllAuthorizator implements IAuthorizator {
|
||||
@Override
|
||||
public boolean canWrite(String topic, String user) {
|
||||
public boolean canWrite(String topic, String user, String client) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRead(String topic, String user) {
|
||||
public boolean canRead(String topic, String user, String client) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ public interface IAuthorizator {
|
||||
/**
|
||||
* Ask the implementation of the authorizator if the topic can be used in a publish.
|
||||
* */
|
||||
boolean canWrite(String topic, String user);
|
||||
boolean canWrite(String topic, String user, String client);
|
||||
|
||||
boolean canRead(String topic, String user);
|
||||
boolean canRead(String topic, String user, String client);
|
||||
}
|
||||
|
||||
+2
-2
@@ -20,12 +20,12 @@ package org.eclipse.moquette.spi.impl.security;
|
||||
*/
|
||||
public class PermitAllAuthorizator implements IAuthorizator {
|
||||
@Override
|
||||
public boolean canWrite(String topic, String user) {
|
||||
public boolean canWrite(String topic, String user, String client) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRead(String topic, String user) {
|
||||
public boolean canRead(String topic, String user, String client) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user