代码整理
This commit is contained in:
103
hooks/auth/auth.go
Normal file
103
hooks/auth/auth.go
Normal file
@@ -0,0 +1,103 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// SPDX-FileCopyrightText: 2022 mochi-mqtt, mochi-co
|
||||
// SPDX-FileContributor: mochi-co
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"testmqtt/mqtt"
|
||||
"testmqtt/packets"
|
||||
)
|
||||
|
||||
// Options contains the configuration/rules data for the auth ledger.
|
||||
type Options struct {
|
||||
Data []byte
|
||||
Ledger *Ledger
|
||||
}
|
||||
|
||||
// Hook is an authentication hook which implements an auth ledger.
|
||||
type Hook struct {
|
||||
mqtt.HookBase
|
||||
config *Options
|
||||
ledger *Ledger
|
||||
}
|
||||
|
||||
// ID returns the ID of the hook.
|
||||
func (h *Hook) ID() string {
|
||||
return "auth-ledger"
|
||||
}
|
||||
|
||||
// Provides indicates which hook methods this hook provides.
|
||||
func (h *Hook) Provides(b byte) bool {
|
||||
return bytes.Contains([]byte{
|
||||
mqtt.OnConnectAuthenticate,
|
||||
mqtt.OnACLCheck,
|
||||
}, []byte{b})
|
||||
}
|
||||
|
||||
// Init configures the hook with the auth ledger to be used for checking.
|
||||
func (h *Hook) Init(config any) error {
|
||||
if _, ok := config.(*Options); !ok && config != nil {
|
||||
return mqtt.ErrInvalidConfigType
|
||||
}
|
||||
|
||||
if config == nil {
|
||||
config = new(Options)
|
||||
}
|
||||
|
||||
h.config = config.(*Options)
|
||||
|
||||
var err error
|
||||
if h.config.Ledger != nil {
|
||||
h.ledger = h.config.Ledger
|
||||
} else if len(h.config.Data) > 0 {
|
||||
h.ledger = new(Ledger)
|
||||
err = h.ledger.Unmarshal(h.config.Data)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if h.ledger == nil {
|
||||
h.ledger = &Ledger{
|
||||
Auth: AuthRules{},
|
||||
ACL: ACLRules{},
|
||||
}
|
||||
}
|
||||
|
||||
h.Log.Info("loaded auth rules",
|
||||
"authentication", len(h.ledger.Auth),
|
||||
"acl", len(h.ledger.ACL))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// OnConnectAuthenticate returns true if the connecting client has rules which provide access
|
||||
// in the auth ledger.
|
||||
func (h *Hook) OnConnectAuthenticate(cl *mqtt.Client, pk packets.Packet) bool {
|
||||
if _, ok := h.ledger.AuthOk(cl, pk); ok {
|
||||
return true
|
||||
}
|
||||
|
||||
h.Log.Info("client failed authentication check",
|
||||
"username", string(pk.Connect.Username),
|
||||
"remote", cl.Net.Remote)
|
||||
return false
|
||||
}
|
||||
|
||||
// OnACLCheck returns true if the connecting client has matching read or write access to subscribe
|
||||
// or publish to a given topic.
|
||||
func (h *Hook) OnACLCheck(cl *mqtt.Client, topic string, write bool) bool {
|
||||
if _, ok := h.ledger.ACLOk(cl, topic, write); ok {
|
||||
return true
|
||||
}
|
||||
|
||||
h.Log.Debug("client failed allowed ACL check",
|
||||
"client", cl.ID,
|
||||
"username", string(cl.Properties.Username),
|
||||
"topic", topic)
|
||||
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user