Skip to content

Commit

Permalink
Enhance Client Initialization and Authentication Configuration (#137)
Browse files Browse the repository at this point in the history
This commit enhances the initialization process for clients, introducing a configuration options for client-application via API. The addition of a Reset function allows the application to transition to an uninitialized state, providing users the flexibility to choose between X509 and PreSharedKey device authentication methods. This update empowers remote clients connected to plgd-hub, allowing seamless configuration of device authentication to meet specific requirements.

Changes Introduced:
Client Initialization:

Enables configuration of client application during the initialization process via UI
Introduces a Reset function to transition the application to an uninitialized state.
Authentication Methods:

Provides support for both X509 and PreSharedKey device authentication methods from UI
Code Reusability and Maintainability:

Implements changes to the Devices pages by leveraging code from the shared UI repository (shared-ui).
Enhances code reusability and maintainability across projects.

---------

Co-authored-by: Patrik Matiaško <patrik.matiasko@gmail.com>
  • Loading branch information
jkralik and PatrikMatiasko authored Dec 7, 2023
1 parent 1036fb6 commit ffdc0f8
Show file tree
Hide file tree
Showing 121 changed files with 24,012 additions and 35,272 deletions.
16 changes: 10 additions & 6 deletions pb/get_configuration.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pb/get_configuration.proto
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ message GetConfigurationResponse {
enum DeviceAuthenticationMode {
PRE_SHARED_KEY = 0;
X509 = 1;
UNINITIALIZED = 2;
};
string version = 1; // deprecated, use build_info.version
string build_date = 2; // deprecated, use build_info.build_date
Expand Down
90 changes: 50 additions & 40 deletions pb/initialize.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pb/initialize.proto
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ message InitializePreSharedKey {
string subject_id = 1;
// Associated secret to the client application ID. Only first 16bytes is used.
string key = 2;
// If true, the client application will be save subject_id and key to the persistent storage.
bool save = 3;
}

message InitializeX509 {
Expand Down
7 changes: 6 additions & 1 deletion pb/service.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -939,7 +939,8 @@
"type": "string",
"enum": [
"PRE_SHARED_KEY",
"X509"
"X509",
"UNINITIALIZED"
],
"default": "PRE_SHARED_KEY"
},
Expand Down Expand Up @@ -1324,6 +1325,10 @@
"key": {
"type": "string",
"description": "Associated secret to the client application ID. Only first 16bytes is used."
},
"save": {
"type": "boolean",
"description": "If true, the client application will be save subject_id and key to the persistent storage."
}
}
},
Expand Down
8 changes: 5 additions & 3 deletions service/config/device/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,9 @@ func (c *PreSharedKeyConfig) Validate() error {
type Authentication string

const (
AuthenticationPreSharedKey Authentication = "preSharedKey"
AuthenticationX509 Authentication = "x509"
AuthenticationPreSharedKey Authentication = "preSharedKey"
AuthenticationX509 Authentication = "x509"
AuthenticationUninitialized Authentication = "uninitialized"
)

type TLSConfig struct {
Expand All @@ -207,6 +208,7 @@ type TLSConfig struct {
func (c *TLSConfig) Validate() error {
switch c.Authentication {
case AuthenticationX509:
case AuthenticationUninitialized:
case AuthenticationPreSharedKey:
if err := c.PreSharedKey.Validate(); err != nil {
return fmt.Errorf("preSharedKey.%w", err)
Expand Down Expand Up @@ -276,7 +278,7 @@ var defaultConfig = Config{
SZXStr: "1024",
},
TLS: TLSConfig{
Authentication: AuthenticationPreSharedKey,
Authentication: AuthenticationUninitialized,
PreSharedKey: PreSharedKeyConfig{
SubjectIDStr: "",
Key: "",
Expand Down
11 changes: 6 additions & 5 deletions service/device/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ import (
udpClient "github.com/plgd-dev/go-coap/v3/udp/client"
udpServer "github.com/plgd-dev/go-coap/v3/udp/server"
"github.com/plgd-dev/hub/v2/pkg/log"
"go.opentelemetry.io/otel/trace"
)

type AuthenticationClient interface {
Expand All @@ -63,7 +62,6 @@ type AuthenticationClient interface {
type Service struct {
getConfig func() configDevice.Config
logger log.Logger
tracerProvider trace.TracerProvider
udp4server *udpServer.Server
udp6server *udpServer.Server
udp4Listener *coapNet.UDPConn
Expand All @@ -79,14 +77,16 @@ func errClosingConnection(debugf func(fmt string, a ...any), scheme schema.Schem
}

// New creates new GRPC service
func New(ctx context.Context, serviceName string, getConfig func() configDevice.Config, logger log.Logger, tracerProvider trace.TracerProvider) (*Service, error) {
func New(ctx context.Context, getConfig func() configDevice.Config, logger log.Logger) (*Service, error) {
config := getConfig()
var authenticationClient AuthenticationClient
switch config.COAP.TLS.Authentication {
case configDevice.AuthenticationPreSharedKey:
authenticationClient = newAuthenticationPreSharedKey(getConfig)
case configDevice.AuthenticationX509:
authenticationClient = newAuthenticationX509(config)
case configDevice.AuthenticationUninitialized:
return nil, fmt.Errorf("device is not initialized")
}

opts := []udpServer.Option{
Expand Down Expand Up @@ -124,7 +124,6 @@ func New(ctx context.Context, serviceName string, getConfig func() configDevice.
return &Service{
getConfig: getConfig,
logger: logger,
tracerProvider: tracerProvider,
udp4server: udp4server,
udp6server: udp6server,
udp4Listener: udp4Listener,
Expand Down Expand Up @@ -368,8 +367,10 @@ func (s *Service) GetDeviceAuthenticationMode() pb.GetConfigurationResponse_Devi
return pb.GetConfigurationResponse_X509
case configDevice.AuthenticationPreSharedKey:
return pb.GetConfigurationResponse_PRE_SHARED_KEY
case configDevice.AuthenticationUninitialized:
return pb.GetConfigurationResponse_UNINITIALIZED
}
return pb.GetConfigurationResponse_PRE_SHARED_KEY
return pb.GetConfigurationResponse_UNINITIALIZED
}

func (s *Service) IsInitialized() bool {
Expand Down
45 changes: 30 additions & 15 deletions service/grpc/clearCache.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,47 @@ package grpc
import (
"context"
"fmt"
"time"

"github.com/google/uuid"
"github.com/hashicorp/go-multierror"
"github.com/plgd-dev/client-application/pb"
)

func (s *ClientApplicationServer) ClearCache(ctx context.Context, _ *pb.ClearCacheRequest) (*pb.ClearCacheResponse, error) {
var errors []error
s.devices.Range(func(key uuid.UUID, dev *device) bool {
s.devices.Delete(key)
err := dev.Close(ctx)
func closeDevice(dev *device) error {
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second))
defer cancel()
return dev.Close(ctx)
}

func closeDevices(devices map[uuid.UUID]*device) error {
var errors *multierror.Error
for key, dev := range devices {
err := closeDevice(dev)
if err != nil {
errors = append(errors, fmt.Errorf("cannot close device %v connections: %w", key, err))
errors = multierror.Append(errors, fmt.Errorf("cannot close device %v connections: %w", key, err))
}
return true
})
var err error
switch len(errors) {
}
if errors == nil {
return nil
}
switch errors.Len() {
case 0:
return nil
case 1:
err = errors[0]
return errors.Errors[0]
default:
err = fmt.Errorf("%v", errors)
}
if err != nil {
s.logger.Warnf("cannot properly clear cache: %w", err)
return errors
}
}

func (s *ClientApplicationServer) ClearCache(ctx context.Context, _ *pb.ClearCacheRequest) (*pb.ClearCacheResponse, error) {
devices := s.devices.LoadAndDeleteAll()
go func(devices map[uuid.UUID]*device) {
err := closeDevices(devices)
if err != nil {
s.logger.Warnf("cannot properly clear cache: %w", err)
}
}(devices)
return &pb.ClearCacheResponse{}, nil
}
2 changes: 1 addition & 1 deletion service/grpc/createResource.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (s *ClientApplicationServer) CreateResource(ctx context.Context, req *pb.Cr
if err != nil {
return nil, err
}
link, err := dev.getResourceLinkAndCheckAccess(ctx, req.GetResourceId())
link, err := dev.getResourceLinkAndCheckAccess(ctx, req.GetResourceId(), "")
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion service/grpc/deleteResource.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (s *ClientApplicationServer) DeleteResource(ctx context.Context, req *pb.De
if err != nil {
return nil, err
}
link, err := dev.getResourceLinkAndCheckAccess(ctx, req.GetResourceId())
link, err := dev.getResourceLinkAndCheckAccess(ctx, req.GetResourceId(), "")
if err != nil {
return nil, err
}
Expand Down
Loading

0 comments on commit ffdc0f8

Please sign in to comment.