-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #12 from muzzammilshahid/router-config
Add command to init basic config and start router
- Loading branch information
Showing
6 changed files
with
289 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
|
||
"golang.org/x/exp/slices" | ||
|
||
"github.com/xconnio/wampproto-go/auth" | ||
) | ||
|
||
type Authenticator struct { | ||
authenticator Authenticators | ||
} | ||
|
||
func NewAuthenticator(authenticators Authenticators) *Authenticator { | ||
return &Authenticator{authenticator: authenticators} | ||
} | ||
|
||
func (a *Authenticator) Methods() []auth.Method { | ||
return []auth.Method{auth.MethodAnonymous, auth.MethodTicket, auth.MethodCRA, auth.MethodCryptoSign} | ||
} | ||
|
||
func (a *Authenticator) Authenticate(request auth.Request) (auth.Response, error) { | ||
switch request.AuthMethod() { | ||
case auth.MethodAnonymous: | ||
for _, anonymous := range a.authenticator.Anonymous { | ||
if anonymous.Realm == request.Realm() { | ||
return auth.NewResponse(request.AuthID(), request.AuthRole(), 0) | ||
} | ||
} | ||
return nil, fmt.Errorf("invalid realm") | ||
|
||
case auth.MethodTicket: | ||
ticketRequest, ok := request.(*auth.TicketRequest) | ||
if !ok { | ||
return nil, fmt.Errorf("invalid request") | ||
} | ||
|
||
for _, ticket := range a.authenticator.Ticket { | ||
if ticket.Realm == ticketRequest.Realm() && ticket.Ticket == ticketRequest.Ticket() { | ||
return auth.NewResponse(ticketRequest.AuthID(), ticketRequest.AuthRole(), 0) | ||
} | ||
} | ||
return nil, fmt.Errorf("invalid ticket") | ||
|
||
case auth.MethodCRA: | ||
for _, wampcra := range a.authenticator.WAMPCRA { | ||
if wampcra.Realm == request.Realm() { | ||
return auth.NewCRAResponse(request.AuthID(), request.AuthRole(), wampcra.Secret, 0), nil | ||
} | ||
} | ||
return nil, fmt.Errorf("invalid realm") | ||
|
||
case auth.MethodCryptoSign: | ||
cryptosignRequest, ok := request.(*auth.RequestCryptoSign) | ||
if !ok { | ||
return nil, fmt.Errorf("invalid request") | ||
} | ||
|
||
for _, cryptosign := range a.authenticator.CryptoSign { | ||
if cryptosign.Realm == cryptosignRequest.Realm() && | ||
slices.Contains(cryptosign.AuthorizedKeys, cryptosignRequest.PublicKey()) { | ||
return auth.NewResponse(cryptosignRequest.AuthID(), cryptosignRequest.AuthRole(), 0) | ||
} | ||
} | ||
return nil, fmt.Errorf("unknown publickey") | ||
|
||
default: | ||
return nil, fmt.Errorf("unknown authentication method: %v", request.AuthMethod()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
version: '1' | ||
|
||
realms: | ||
- name: realm1 | ||
|
||
transports: | ||
- type: websocket | ||
port: 8080 | ||
serializers: | ||
- json | ||
- cbor | ||
- protobuf | ||
|
||
authenticators: | ||
cryptosign: | ||
- authid: john | ||
realm: realm1 | ||
role: anonymous | ||
authorized_keys: | ||
- 20e6ff0eb2552204fac19a15a61da586e437abd64a545bedce61a89b48184fcb | ||
|
||
wampcra: | ||
- authid: john | ||
realm: realm1 | ||
role: anonymous | ||
secret: hello | ||
|
||
ticket: | ||
- authid: john | ||
realm: realm1 | ||
role: anonymous | ||
ticket: hello | ||
|
||
anonymous: | ||
- authid: john | ||
realm: realm1 | ||
role: anonymous |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,121 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
_ "embed" // nolint:gci | ||
"fmt" | ||
"log" | ||
"os" | ||
|
||
"github.com/alecthomas/kingpin/v2" | ||
"golang.org/x/exp/slices" | ||
"gopkg.in/yaml.v3" | ||
|
||
"github.com/xconnio/wampproto-protobuf/go" | ||
"github.com/xconnio/xconn-go" | ||
) | ||
|
||
func main() { | ||
router := xconn.NewRouter() | ||
router.AddRealm("realm1") | ||
var ( | ||
//go:embed config.yaml.in | ||
sampleConfig []byte | ||
) | ||
|
||
server := xconn.NewServer(router, nil) | ||
const ( | ||
versionString = "0.1.0" | ||
|
||
serializer := &wampprotobuf.ProtobufSerializer{} | ||
protobufSpec := xconn.NewWSSerializerSpec("wamp.2.protobuf", serializer) | ||
ConfigDir = ".xconn" | ||
ConfigFile = ConfigDir + "/config.yaml" | ||
|
||
ProtobufSubProtocol = "wamp.2.protobuf" | ||
) | ||
|
||
type cmd struct { | ||
parsedCommand string | ||
|
||
init *kingpin.CmdClause | ||
|
||
start *kingpin.CmdClause | ||
} | ||
|
||
if err := server.RegisterSpec(protobufSpec); err != nil { | ||
log.Fatal(err) | ||
func parseCommand(args []string) (*cmd, error) { | ||
app := kingpin.New(args[0], "XConn") | ||
app.Version(versionString).VersionFlag.Short('v') | ||
|
||
c := &cmd{ | ||
init: app.Command("init", "Initialize sample router config."), | ||
start: app.Command("start", "Start the router."), | ||
} | ||
|
||
parsedCommand, err := app.Parse(args[1:]) | ||
if err != nil { | ||
return nil, err | ||
} | ||
c.parsedCommand = parsedCommand | ||
|
||
return c, nil | ||
} | ||
|
||
func Run(args []string) error { | ||
c, err := parseCommand(args) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
log.Fatal(server.Start("0.0.0.0", 8080)) | ||
switch c.parsedCommand { | ||
case c.init.FullCommand(): | ||
if err := os.MkdirAll(ConfigDir, os.ModePerm); err != nil { | ||
return err | ||
} | ||
|
||
if err = os.WriteFile(ConfigFile, sampleConfig, 0600); err != nil { | ||
return fmt.Errorf("unable to write config: %w", err) | ||
} | ||
|
||
case c.start.FullCommand(): | ||
data, err := os.ReadFile(ConfigFile) | ||
if err != nil { | ||
return fmt.Errorf("unable to read config file: %w", err) | ||
} | ||
|
||
var decoder = yaml.NewDecoder(bytes.NewBuffer(data)) | ||
decoder.KnownFields(true) | ||
|
||
var config Config | ||
if err := decoder.Decode(&config); err != nil { | ||
return fmt.Errorf("unable to decode config file: %w", err) | ||
} | ||
|
||
router := xconn.NewRouter() | ||
|
||
for _, realm := range config.Realms { | ||
router.AddRealm(realm.Name) | ||
} | ||
|
||
authenticator := NewAuthenticator(config.Authenticators) | ||
server := xconn.NewServer(router, authenticator) | ||
|
||
for _, transport := range config.Transports { | ||
if slices.Contains(transport.Serializers, "protobuf") { | ||
serializer := &wampprotobuf.ProtobufSerializer{} | ||
protobufSpec := xconn.NewWSSerializerSpec(ProtobufSubProtocol, serializer) | ||
|
||
if err := server.RegisterSpec(protobufSpec); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
if err := server.Start("0.0.0.0", transport.Port); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
} | ||
|
||
return nil | ||
} | ||
|
||
func main() { | ||
if err := Run(os.Args); err != nil { | ||
log.Fatalln(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package main | ||
|
||
type Config struct { | ||
Version string `yaml:"version"` | ||
Realms []Realm `yaml:"realms"` | ||
Transports []Transport `yaml:"transports"` | ||
Authenticators Authenticators `yaml:"authenticators"` | ||
} | ||
|
||
type Realm struct { | ||
Name string `yaml:"name"` | ||
} | ||
|
||
type Transport struct { | ||
Type string `yaml:"type"` | ||
Port int `yaml:"port"` | ||
Serializers []string `yaml:"serializers"` | ||
} | ||
|
||
type CryptoSign struct { | ||
AuthID string `yaml:"authid"` | ||
Realm string `yaml:"realm"` | ||
Role string `yaml:"role"` | ||
AuthorizedKeys []string `yaml:"authorized_keys"` | ||
} | ||
|
||
type WAMPCRA struct { | ||
AuthID string `yaml:"authid"` | ||
Realm string `yaml:"realm"` | ||
Role string `yaml:"role"` | ||
Secret string `yaml:"secret"` | ||
Salt string `yaml:"salt"` | ||
Iterations int `yaml:"iterations"` | ||
KeyLen int `yaml:"keylen"` | ||
} | ||
|
||
type Ticket struct { | ||
AuthID string `yaml:"authid"` | ||
Realm string `yaml:"realm"` | ||
Role string `yaml:"role"` | ||
Ticket string `yaml:"ticket"` | ||
} | ||
|
||
type Anonymous struct { | ||
AuthID string `yaml:"authid"` | ||
Realm string `yaml:"realm"` | ||
Role string `yaml:"role"` | ||
} | ||
|
||
type Authenticators struct { | ||
CryptoSign []CryptoSign `yaml:"cryptosign"` | ||
WAMPCRA []WAMPCRA `yaml:"wampcra"` | ||
Ticket []Ticket `yaml:"ticket"` | ||
Anonymous []Anonymous `yaml:"anonymous"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters