Add hello version "2.0" that authenticates connections using a JWT.

This commit is contained in:
Joachim Bauch
2022-08-03 16:33:45 +02:00
parent 88e4c5f2c3
commit 156bc360ff
11 changed files with 693 additions and 64 deletions
+38 -4
View File
@@ -27,11 +27,16 @@ import (
"net/url"
"sort"
"strings"
"github.com/golang-jwt/jwt/v4"
)
const (
// Version that must be sent in a "hello" message.
HelloVersion = "1.0"
// Version 1.0 validates auth params against the Nextcloud instance.
HelloVersionV1 = "1.0"
// Version 2.0 validates auth params encoded as JWT.
HelloVersionV2 = "2.0"
)
// ClientMessage is a message that is sent from a client to the server.
@@ -325,6 +330,23 @@ func (p *ClientTypeInternalAuthParams) CheckValid() error {
return nil
}
type HelloV2AuthParams struct {
Token string `json:"token"`
}
func (p *HelloV2AuthParams) CheckValid() error {
if p.Token == "" {
return fmt.Errorf("token missing")
}
return nil
}
type HelloV2TokenClaims struct {
jwt.RegisteredClaims
UserData *json.RawMessage `json:"userdata,omitempty"`
}
type HelloClientMessageAuth struct {
// The client type that is connecting. Leave empty to use the default
// "HelloClientTypeClient"
@@ -336,6 +358,7 @@ type HelloClientMessageAuth struct {
parsedUrl *url.URL
internalParams ClientTypeInternalAuthParams
helloV2Params HelloV2AuthParams
}
// Type "hello"
@@ -352,8 +375,8 @@ type HelloClientMessage struct {
}
func (m *HelloClientMessage) CheckValid() error {
if m.Version != HelloVersion {
return fmt.Errorf("unsupported hello version: %s", m.Version)
if m.Version != HelloVersionV1 && m.Version != HelloVersionV2 {
return InvalidHelloVersion
}
if m.ResumeId == "" {
if m.Auth.Params == nil || len(*m.Auth.Params) == 0 {
@@ -375,6 +398,17 @@ func (m *HelloClientMessage) CheckValid() error {
m.Auth.parsedUrl = u
}
switch m.Version {
case HelloVersionV1:
// No additional validation necessary.
case HelloVersionV2:
if err := json.Unmarshal(*m.Auth.Params, &m.Auth.helloV2Params); err != nil {
return err
} else if err := m.Auth.helloV2Params.CheckValid(); err != nil {
return err
}
}
case HelloClientTypeInternal:
if err := json.Unmarshal(*m.Auth.Params, &m.Auth.internalParams); err != nil {
return err