Skip to content

Commit 9301c4a

Browse files
committed
Session docs on readme
1 parent 159e2bd commit 9301c4a

File tree

6 files changed

+129
-20
lines changed

6 files changed

+129
-20
lines changed

README.md

Lines changed: 88 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -500,13 +500,16 @@ In Lime, the **client can receive and process commands requests** from other nod
500500

501501
### Session
502502

503+
> The session establishment flow is automatically handled by the library.
504+
> This section is for informative purposes only.
505+
503506
The session envelope is used for the negotiation, authentication and establishment of the communication channel between
504507
the client and a server.
505-
It helps select the transport options, like compression and encryption (TLS), authentication credentials, and session
506-
metadata, like its `id` and local/remote node addresses.
508+
It helps the parties to select the transport options, like compression and encryption (TLS), authentication credentials,
509+
and session metadata, like its `id` and local/remote node addresses.
507510

508-
For instance, the first envelope sent in every like session is the **new session** envelope, which the client sends to
509-
the server after the transport connection is established:
511+
The first envelope sent in every Lime session is the **new session** envelope, which the client sends to the server
512+
after the transport connection is established:
510513

511514
```json
512515
{
@@ -531,11 +534,88 @@ encryption by default).
531534

532535
Note that this envelope haves a `id` defined, which is the **session id**.
533536
The next session envelopes sent by the client should use this same id, until the end of the session.
537+
During the session establishment, only session envelopes are allowed.
538+
539+
The server can skip the `negotiating` state and jump directly to the `authenticating` or even to the `established`
540+
state. The session state progression can occur in the following order:
534541

535-
The session state progression can occur in the following order:
536-
1. new (client started)
542+
1. new (started by the client)
537543
2. negotiating (optional)
538544
3. authenticating (optional)
539545
4. established
540-
5. finishing (optional, client started)
541-
6. finished OR failed
546+
5. finishing (optional, started by the client)
547+
6. finished OR failed (final)
548+
549+
In Go, the session negotiation, authentication, and establishment process is **automatically handled** by the
550+
`lime.Client` and `lime.Server` types.
551+
You just need to make sure that the server and client are configured accordingly the desired behavior.
552+
553+
For instance, if you want to ensure that the TCP transport connections are using the TLS encryption, you will need to
554+
configure the server similarly to this:
555+
556+
```go
557+
server := lime.NewServerBuilder().
558+
// Enable the TLS encryption option for all sessions
559+
EncryptionOptions(lime.SessionEncryptionTLS).
560+
// Set up the TCP listener providing a certificate
561+
ListenTCP(addr, &lime.TCPConfig{
562+
TLSConfig: &tls.Config{
563+
GetCertificate: func(info *tls.ClientHelloInfo) (*tls.Certificate, error) {
564+
cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem")
565+
if err != nil {
566+
return nil, err
567+
}
568+
return &cert, nil
569+
},
570+
}}).
571+
// TODO: Setup other server options
572+
Build()
573+
```
574+
575+
And in the client side, you should set up the TLS encryption option and the TCP config:
576+
577+
```go
578+
client := lime.NewClientBuilder().
579+
Encryption(lime.SessionEncryptionTLS).
580+
UseTCP(addr, &lime.TCPConfig{
581+
TLSConfig: &tls.Config{ServerName: "localhost"},
582+
}).
583+
// TODO: Setup other client options
584+
Build()
585+
```
586+
587+
You may also want to configure the server and client authentication mechanisms.
588+
The Lime Go library supports the following schemes:
589+
- Guest (no authentication)
590+
- Plain (password)
591+
- Key
592+
- Transport (mutual TLS on TCP)
593+
- External (token emitted by an issuer)
594+
595+
To enable the use of plain authentication, in the server you should use the `EnablePlainAuthentication` method passing
596+
the authentication handler function, like in the example below:
597+
598+
```go
599+
server := lime.NewServerBuilder().
600+
EnablePlainAuthentication(
601+
func(ctx context.Context, i lime.Identity, pwd string) (*lime.AuthenticationResult, error) {
602+
// TODO: implement checkCredentials to validate the user/password in your secret store
603+
if checkCredentials(i.Name, pwd) {
604+
return &lime.AuthenticationResult{Role: lime.DomainRoleMember}, nil
605+
}
606+
return &lime.AuthenticationResult{Role: lime.DomainRoleUnknown}, nil
607+
}).
608+
// TODO: Setup other server options
609+
Build()
610+
```
611+
612+
On the client side, you can use the `PlainAuthentication` method to set the password that should be used:
613+
614+
```go
615+
client := lime.NewClientBuilder().
616+
// Sets the identity name and password
617+
Name("john").
618+
PlainAuthentication("mysecretpassword").
619+
// TODO: Setup other client options
620+
Build()
621+
```

examples/client/main.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,13 @@ func main() {
2121
}
2222

2323
client := lime.NewClientBuilder().
24+
Encryption(lime.SessionEncryptionTLS).
2425
UseTCP(addr, &lime.TCPConfig{
2526
TLSConfig: &tls.Config{ServerName: "localhost", InsecureSkipVerify: true},
2627
TraceWriter: lime.NewStdoutTraceWriter(),
2728
}).
29+
Name("john").
30+
PlainAuthentication("mysecretpassword").
2831
MessagesHandlerFunc(
2932
func(ctx context.Context, msg *lime.Message, s lime.Sender) error {
3033
fmt.Printf("Message received - ID: %v - From: %v - Type: %v - Content: %v\n", msg.ID, msg.From, msg.Type, msg.Content)

examples/server/credentials.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package main
2+
3+
import "golang.org/x/crypto/bcrypt"
4+
5+
var fakeSecretStore = map[string]string{
6+
"john": hashPassword("mysecretpassword"),
7+
"mary": hashPassword("mary1234"),
8+
}
9+
10+
func checkCredentials(name string, password string) bool {
11+
if hash, ok := fakeSecretStore[name]; ok {
12+
return checkPasswordHash(password, hash)
13+
}
14+
return false
15+
}
16+
17+
func hashPassword(password string) string {
18+
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14)
19+
if err != nil {
20+
panic(err)
21+
}
22+
return string(bytes)
23+
}
24+
25+
func checkPasswordHash(password, hash string) bool {
26+
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
27+
return err == nil
28+
}

examples/server/main.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ func main() {
4545
fmt.Printf("RequestCommand received - ID: %v\n", cmd.ID)
4646
return nil
4747
}).
48+
EncryptionOptions(lime.SessionEncryptionTLS).
4849
ListenTCP(
4950
addr,
5051
&lime.TCPConfig{
@@ -56,6 +57,12 @@ func main() {
5657
TraceWriter: lime.NewStdoutTraceWriter(),
5758
}).
5859
EnableGuestAuthentication().
60+
EnablePlainAuthentication(func(ctx context.Context, identity lime.Identity, password string) (*lime.AuthenticationResult, error) {
61+
if checkCredentials(identity.Name, password) {
62+
return &lime.AuthenticationResult{Role: lime.DomainRoleMember}, nil
63+
}
64+
return &lime.AuthenticationResult{Role: lime.DomainRoleUnknown}, nil
65+
}).
5966
Build()
6067

6168
go func() {

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ require (
88
github.com/stretchr/testify v1.7.0
99
go.uber.org/atomic v1.9.0 // indirect
1010
go.uber.org/goleak v1.1.12
11-
go.uber.org/multierr v1.8.0 // indirect
11+
go.uber.org/multierr v1.8.0
12+
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
1213
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
1314
)

go.sum

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
1-
github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo=
2-
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
3-
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
41
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
52
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
63
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
7-
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
8-
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
94
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
105
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
116
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
@@ -19,8 +14,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
1914
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
2015
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
2116
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
22-
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
23-
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
2417
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
2518
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
2619
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
@@ -32,6 +25,7 @@ go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ
3225
go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8=
3326
go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
3427
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
28+
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
3529
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
3630
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
3731
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
@@ -62,13 +56,9 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
6256
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
6357
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
6458
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
65-
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
6659
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
6760
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
6861
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
69-
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
70-
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
71-
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
7262
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
7363
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
7464
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

0 commit comments

Comments
 (0)