mirror of
https://github.com/fhmq/hmq.git
synced 2026-04-24 10:38:34 +00:00
149 lines
3.0 KiB
Go
149 lines
3.0 KiB
Go
package acl
|
|
|
|
import "strings"
|
|
|
|
func checkTopicAuth(ACLInfo *ACLConfig, typ int, ip, username, clientid, topic string) bool {
|
|
for _, info := range ACLInfo.Info {
|
|
ctyp := info.Typ
|
|
switch ctyp {
|
|
case CLIENTID:
|
|
if match, auth := info.checkWithClientID(typ, clientid, topic); match {
|
|
return auth
|
|
}
|
|
case USERNAME:
|
|
if match, auth := info.checkWithUsername(typ, username, topic); match {
|
|
return auth
|
|
}
|
|
case IP:
|
|
if match, auth := info.checkWithIP(typ, ip, topic); match {
|
|
return auth
|
|
}
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (a *AuthInfo) checkWithClientID(typ int, clientid, topic string) (bool, bool) {
|
|
auth := false
|
|
match := false
|
|
if a.Val == "*" || a.Val == clientid {
|
|
for _, tp := range a.Topics {
|
|
des := strings.Replace(tp, "%c", clientid, -1)
|
|
if typ == PUB {
|
|
if pubTopicMatch(topic, des) {
|
|
match = true
|
|
auth = a.checkAuth(PUB)
|
|
}
|
|
} else if typ == SUB {
|
|
if subTopicMatch(topic, des) {
|
|
match = true
|
|
auth = a.checkAuth(SUB)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return match, auth
|
|
}
|
|
|
|
func (a *AuthInfo) checkWithUsername(typ int, username, topic string) (bool, bool) {
|
|
auth := false
|
|
match := false
|
|
if a.Val == "*" || a.Val == username {
|
|
for _, tp := range a.Topics {
|
|
des := strings.Replace(tp, "%u", username, -1)
|
|
if typ == PUB {
|
|
if pubTopicMatch(topic, des) {
|
|
match = true
|
|
auth = a.checkAuth(PUB)
|
|
}
|
|
} else if typ == SUB {
|
|
if subTopicMatch(topic, des) {
|
|
match = true
|
|
auth = a.checkAuth(SUB)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return match, auth
|
|
}
|
|
|
|
func (a *AuthInfo) checkWithIP(typ int, ip, topic string) (bool, bool) {
|
|
auth := false
|
|
match := false
|
|
if a.Val == "*" || a.Val == ip {
|
|
for _, tp := range a.Topics {
|
|
des := tp
|
|
if typ == PUB {
|
|
if pubTopicMatch(topic, des) {
|
|
auth = a.checkAuth(PUB)
|
|
match = true
|
|
}
|
|
} else if typ == SUB {
|
|
if subTopicMatch(topic, des) {
|
|
auth = a.checkAuth(SUB)
|
|
match = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return match, auth
|
|
}
|
|
|
|
func (a *AuthInfo) checkAuth(typ int) bool {
|
|
auth := false
|
|
if typ == PUB {
|
|
if a.Auth == ALLOW && (a.PubSub == PUB || a.PubSub == PUBSUB) {
|
|
auth = true
|
|
} else if a.Auth == DENY && a.PubSub == SUB {
|
|
auth = true
|
|
}
|
|
} else if typ == SUB {
|
|
if a.Auth == ALLOW && (a.PubSub == SUB || a.PubSub == PUBSUB) {
|
|
auth = true
|
|
} else if a.Auth == DENY && a.PubSub == PUB {
|
|
auth = true
|
|
}
|
|
}
|
|
return auth
|
|
}
|
|
|
|
func pubTopicMatch(pub, des string) bool {
|
|
dest, _ := SubscribeTopicSpilt(des)
|
|
topic, _ := PublishTopicSpilt(pub)
|
|
for i, t := range dest {
|
|
if i > len(topic)-1 {
|
|
return false
|
|
}
|
|
if t == "#" {
|
|
return true
|
|
}
|
|
if t == "+" || t == topic[i] {
|
|
continue
|
|
}
|
|
if t != topic[i] {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func subTopicMatch(pub, des string) bool {
|
|
dest, _ := SubscribeTopicSpilt(des)
|
|
topic, _ := SubscribeTopicSpilt(pub)
|
|
for i, t := range dest {
|
|
if i > len(topic)-1 {
|
|
return false
|
|
}
|
|
if t == "#" {
|
|
return true
|
|
}
|
|
if t == "+" || "+" == topic[i] || t == topic[i] {
|
|
continue
|
|
}
|
|
if t != topic[i] {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|