mirror of
https://github.com/netbirdio/netbird.git
synced 2025-04-15 15:08:31 +02:00
Get Device Authorization Flow information from management (#308)
We will configure the device authorization flow information and a client will retrieve it and initiate a device authorization gran flow
This commit is contained in:
parent
fec3132585
commit
7e5449fb55
@ -14,4 +14,5 @@ type Client interface {
|
|||||||
GetServerPublicKey() (*wgtypes.Key, error)
|
GetServerPublicKey() (*wgtypes.Key, error)
|
||||||
Register(serverKey wgtypes.Key, setupKey string, jwtToken string, info *system.Info) (*proto.LoginResponse, error)
|
Register(serverKey wgtypes.Key, setupKey string, jwtToken string, info *system.Info) (*proto.LoginResponse, error)
|
||||||
Login(serverKey wgtypes.Key) (*proto.LoginResponse, error)
|
Login(serverKey wgtypes.Key) (*proto.LoginResponse, error)
|
||||||
|
GetDeviceAuthorizationFlow(serverKey wgtypes.Key) (*proto.DeviceAuthorizationFlow, error)
|
||||||
}
|
}
|
||||||
|
@ -25,25 +25,17 @@ import (
|
|||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
var tested *GrpcClient
|
|
||||||
var serverAddr string
|
|
||||||
var mgmtMockServer *mock_server.ManagementServiceServerMock
|
|
||||||
var serverKey wgtypes.Key
|
|
||||||
|
|
||||||
const ValidKey = "A2C8E62B-38F5-4553-B31E-DD66C696CEBB"
|
const ValidKey = "A2C8E62B-38F5-4553-B31E-DD66C696CEBB"
|
||||||
|
|
||||||
func Test_Start(t *testing.T) {
|
func startManagement(t *testing.T) (*grpc.Server, net.Listener) {
|
||||||
|
|
||||||
level, _ := log.ParseLevel("debug")
|
level, _ := log.ParseLevel("debug")
|
||||||
log.SetLevel(level)
|
log.SetLevel(level)
|
||||||
|
|
||||||
testKey, err := wgtypes.GenerateKey()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
testDir := t.TempDir()
|
testDir := t.TempDir()
|
||||||
ctx := context.Background()
|
|
||||||
config := &mgmt.Config{}
|
config := &mgmt.Config{}
|
||||||
_, err = util.ReadJson("../server/testdata/management.json", config)
|
_, err := util.ReadJson("../server/testdata/management.json", config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -52,15 +44,7 @@ func Test_Start(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
_, listener := startManagement(config, t)
|
|
||||||
serverAddr = listener.Addr().String()
|
|
||||||
tested, err = NewClient(ctx, serverAddr, testKey, false)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func startManagement(config *mgmt.Config, t *testing.T) (*grpc.Server, net.Listener) {
|
|
||||||
lis, err := net.Listen("tcp", ":0")
|
lis, err := net.Listen("tcp", ":0")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -89,7 +73,7 @@ func startManagement(config *mgmt.Config, t *testing.T) (*grpc.Server, net.Liste
|
|||||||
return s, lis
|
return s, lis
|
||||||
}
|
}
|
||||||
|
|
||||||
func startMockManagement(t *testing.T) (*grpc.Server, net.Listener) {
|
func startMockManagement(t *testing.T) (*grpc.Server, net.Listener, *mock_server.ManagementServiceServerMock, wgtypes.Key) {
|
||||||
lis, err := net.Listen("tcp", ":0")
|
lis, err := net.Listen("tcp", ":0")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -97,12 +81,12 @@ func startMockManagement(t *testing.T) (*grpc.Server, net.Listener) {
|
|||||||
|
|
||||||
s := grpc.NewServer()
|
s := grpc.NewServer()
|
||||||
|
|
||||||
serverKey, err = wgtypes.GenerateKey()
|
serverKey, err := wgtypes.GenerateKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
mgmtMockServer = &mock_server.ManagementServiceServerMock{
|
mgmtMockServer := &mock_server.ManagementServiceServerMock{
|
||||||
GetServerKeyFunc: func(context.Context, *proto.Empty) (*proto.ServerKeyResponse, error) {
|
GetServerKeyFunc: func(context.Context, *proto.Empty) (*proto.ServerKeyResponse, error) {
|
||||||
response := &proto.ServerKeyResponse{
|
response := &proto.ServerKeyResponse{
|
||||||
Key: serverKey.PublicKey().String(),
|
Key: serverKey.PublicKey().String(),
|
||||||
@ -119,27 +103,59 @@ func startMockManagement(t *testing.T) (*grpc.Server, net.Listener) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return s, lis
|
return s, lis, mgmtMockServer, serverKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func closeManagementSilently(s *grpc.Server, listener net.Listener) {
|
||||||
|
s.GracefulStop()
|
||||||
|
err := listener.Close()
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("error while closing management listener %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClient_GetServerPublicKey(t *testing.T) {
|
func TestClient_GetServerPublicKey(t *testing.T) {
|
||||||
|
testKey, err := wgtypes.GenerateKey()
|
||||||
key, err := tested.GetServerPublicKey()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
ctx := context.Background()
|
||||||
|
s, listener := startManagement(t)
|
||||||
|
defer closeManagementSilently(s, listener)
|
||||||
|
|
||||||
|
client, err := NewClient(ctx, listener.Addr().String(), testKey, false)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
key, err := client.GetServerPublicKey()
|
||||||
|
if err != nil {
|
||||||
|
t.Error("couldn't retrieve management public key")
|
||||||
|
}
|
||||||
if key == nil {
|
if key == nil {
|
||||||
t.Error("expecting non nil server key got nil")
|
t.Error("got an empty management public key")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClient_LoginUnregistered_ShouldThrow_401(t *testing.T) {
|
func TestClient_LoginUnregistered_ShouldThrow_401(t *testing.T) {
|
||||||
key, err := tested.GetServerPublicKey()
|
testKey, err := wgtypes.GenerateKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
_, err = tested.Login(*key)
|
ctx := context.Background()
|
||||||
|
s, listener := startManagement(t)
|
||||||
|
defer closeManagementSilently(s, listener)
|
||||||
|
|
||||||
|
client, err := NewClient(ctx, listener.Addr().String(), testKey, false)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
key, err := client.GetServerPublicKey()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
_, err = client.Login(*key)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("expecting err on unregistered login, got nil")
|
t.Error("expecting err on unregistered login, got nil")
|
||||||
}
|
}
|
||||||
@ -149,12 +165,25 @@ func TestClient_LoginUnregistered_ShouldThrow_401(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestClient_LoginRegistered(t *testing.T) {
|
func TestClient_LoginRegistered(t *testing.T) {
|
||||||
key, err := tested.GetServerPublicKey()
|
testKey, err := wgtypes.GenerateKey()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
ctx := context.Background()
|
||||||
|
s, listener := startManagement(t)
|
||||||
|
defer closeManagementSilently(s, listener)
|
||||||
|
|
||||||
|
client, err := NewClient(ctx, listener.Addr().String(), testKey, false)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
key, err := client.GetServerPublicKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
info := system.GetInfo()
|
info := system.GetInfo()
|
||||||
resp, err := tested.Register(*key, ValidKey, "", info)
|
resp, err := client.Register(*key, ValidKey, "", info)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@ -165,13 +194,26 @@ func TestClient_LoginRegistered(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestClient_Sync(t *testing.T) {
|
func TestClient_Sync(t *testing.T) {
|
||||||
serverKey, err := tested.GetServerPublicKey()
|
testKey, err := wgtypes.GenerateKey()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
ctx := context.Background()
|
||||||
|
s, listener := startManagement(t)
|
||||||
|
defer closeManagementSilently(s, listener)
|
||||||
|
|
||||||
|
client, err := NewClient(ctx, listener.Addr().String(), testKey, false)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
serverKey, err := client.GetServerPublicKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
info := system.GetInfo()
|
info := system.GetInfo()
|
||||||
_, err = tested.Register(*serverKey, ValidKey, "", info)
|
_, err = client.Register(*serverKey, ValidKey, "", info)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@ -181,7 +223,7 @@ func TestClient_Sync(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
remoteClient, err := NewClient(context.TODO(), serverAddr, remoteKey, false)
|
remoteClient, err := NewClient(context.TODO(), listener.Addr().String(), remoteKey, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -195,7 +237,7 @@ func TestClient_Sync(t *testing.T) {
|
|||||||
ch := make(chan *mgmtProto.SyncResponse, 1)
|
ch := make(chan *mgmtProto.SyncResponse, 1)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
err = tested.Sync(func(msg *mgmtProto.SyncResponse) error {
|
err = client.Sync(func(msg *mgmtProto.SyncResponse) error {
|
||||||
ch <- msg
|
ch <- msg
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@ -227,7 +269,8 @@ func TestClient_Sync(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_SystemMetaDataFromClient(t *testing.T) {
|
func Test_SystemMetaDataFromClient(t *testing.T) {
|
||||||
_, lis := startMockManagement(t)
|
s, lis, mgmtMockServer, serverKey := startMockManagement(t)
|
||||||
|
defer s.GracefulStop()
|
||||||
|
|
||||||
testKey, err := wgtypes.GenerateKey()
|
testKey, err := wgtypes.GenerateKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -304,3 +347,49 @@ func Test_SystemMetaDataFromClient(t *testing.T) {
|
|||||||
assert.Equal(t, ValidKey, actualValidKey)
|
assert.Equal(t, ValidKey, actualValidKey)
|
||||||
assert.Equal(t, expectedMeta, actualMeta)
|
assert.Equal(t, expectedMeta, actualMeta)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_GetDeviceAuthorizationFlow(t *testing.T) {
|
||||||
|
s, lis, mgmtMockServer, serverKey := startMockManagement(t)
|
||||||
|
defer s.GracefulStop()
|
||||||
|
|
||||||
|
testKey, err := wgtypes.GenerateKey()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
serverAddr := lis.Addr().String()
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
client, err := NewClient(ctx, serverAddr, testKey, false)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("error while creating testClient: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedFlowInfo := &proto.DeviceAuthorizationFlow{
|
||||||
|
Provider: 0,
|
||||||
|
ProviderConfig: &proto.ProviderConfig{ClientID: "client"},
|
||||||
|
}
|
||||||
|
|
||||||
|
mgmtMockServer.GetDeviceAuthorizationFlowFunc =
|
||||||
|
func(ctx context.Context, req *mgmtProto.EncryptedMessage) (*proto.EncryptedMessage, error) {
|
||||||
|
|
||||||
|
encryptedResp, err := encryption.EncryptMessage(serverKey, client.key, expectedFlowInfo)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &mgmtProto.EncryptedMessage{
|
||||||
|
WgPubKey: serverKey.PublicKey().String(),
|
||||||
|
Body: encryptedResp,
|
||||||
|
Version: 0,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
flowInfo, err := client.GetDeviceAuthorizationFlow(serverKey)
|
||||||
|
if err != nil {
|
||||||
|
t.Error("error while retrieving device auth flow information")
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Equal(t, expectedFlowInfo.Provider, flowInfo.Provider, "provider should match")
|
||||||
|
assert.Equal(t, expectedFlowInfo.ProviderConfig.ClientID, flowInfo.ProviderConfig.ClientID, "provider configured client ID should match")
|
||||||
|
}
|
||||||
|
@ -245,3 +245,37 @@ func (c *GrpcClient) Register(serverKey wgtypes.Key, setupKey string, jwtToken s
|
|||||||
func (c *GrpcClient) Login(serverKey wgtypes.Key) (*proto.LoginResponse, error) {
|
func (c *GrpcClient) Login(serverKey wgtypes.Key) (*proto.LoginResponse, error) {
|
||||||
return c.login(serverKey, &proto.LoginRequest{})
|
return c.login(serverKey, &proto.LoginRequest{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDeviceAuthorizationFlow returns a device authorization flow information.
|
||||||
|
// It also takes care of encrypting and decrypting messages.
|
||||||
|
func (c *GrpcClient) GetDeviceAuthorizationFlow(serverKey wgtypes.Key) (*proto.DeviceAuthorizationFlow, error) {
|
||||||
|
if !c.ready() {
|
||||||
|
return nil, fmt.Errorf("no connection to management in order to get device authorization flow")
|
||||||
|
}
|
||||||
|
mgmCtx, cancel := context.WithTimeout(c.ctx, time.Second*2)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
message := &proto.DeviceAuthorizationFlowRequest{}
|
||||||
|
encryptedMSG, err := encryption.EncryptMessage(serverKey, c.key, message)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := c.realClient.GetDeviceAuthorizationFlow(mgmCtx, &proto.EncryptedMessage{
|
||||||
|
WgPubKey: c.key.PublicKey().String(),
|
||||||
|
Body: encryptedMSG},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
flowInfoResp := &proto.DeviceAuthorizationFlow{}
|
||||||
|
err = encryption.DecryptMessage(serverKey, c.key, resp.Body, flowInfoResp)
|
||||||
|
if err != nil {
|
||||||
|
errWithMSG := fmt.Errorf("failed to decrypt device authorization flow message: %s", err)
|
||||||
|
log.Error(errWithMSG)
|
||||||
|
return nil, errWithMSG
|
||||||
|
}
|
||||||
|
|
||||||
|
return flowInfoResp, nil
|
||||||
|
}
|
||||||
|
@ -12,6 +12,7 @@ type MockClient struct {
|
|||||||
GetServerPublicKeyFunc func() (*wgtypes.Key, error)
|
GetServerPublicKeyFunc func() (*wgtypes.Key, error)
|
||||||
RegisterFunc func(serverKey wgtypes.Key, setupKey string, jwtToken string, info *system.Info) (*proto.LoginResponse, error)
|
RegisterFunc func(serverKey wgtypes.Key, setupKey string, jwtToken string, info *system.Info) (*proto.LoginResponse, error)
|
||||||
LoginFunc func(serverKey wgtypes.Key) (*proto.LoginResponse, error)
|
LoginFunc func(serverKey wgtypes.Key) (*proto.LoginResponse, error)
|
||||||
|
GetDeviceAuthorizationFlowFunc func(serverKey wgtypes.Key) (*proto.DeviceAuthorizationFlow, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MockClient) Close() error {
|
func (m *MockClient) Close() error {
|
||||||
@ -48,3 +49,10 @@ func (m *MockClient) Login(serverKey wgtypes.Key) (*proto.LoginResponse, error)
|
|||||||
}
|
}
|
||||||
return m.LoginFunc(serverKey)
|
return m.LoginFunc(serverKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *MockClient) GetDeviceAuthorizationFlow(serverKey wgtypes.Key) (*proto.DeviceAuthorizationFlow, error) {
|
||||||
|
if m.GetDeviceAuthorizationFlowFunc == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return m.GetDeviceAuthorizationFlowFunc(serverKey)
|
||||||
|
}
|
||||||
|
@ -76,6 +76,49 @@ func (HostConfig_Protocol) EnumDescriptor() ([]byte, []int) {
|
|||||||
return file_management_proto_rawDescGZIP(), []int{9, 0}
|
return file_management_proto_rawDescGZIP(), []int{9, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DeviceAuthorizationFlowProvider int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
DeviceAuthorizationFlow_HOSTED DeviceAuthorizationFlowProvider = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
// Enum value maps for DeviceAuthorizationFlowProvider.
|
||||||
|
var (
|
||||||
|
DeviceAuthorizationFlowProvider_name = map[int32]string{
|
||||||
|
0: "HOSTED",
|
||||||
|
}
|
||||||
|
DeviceAuthorizationFlowProvider_value = map[string]int32{
|
||||||
|
"HOSTED": 0,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (x DeviceAuthorizationFlowProvider) Enum() *DeviceAuthorizationFlowProvider {
|
||||||
|
p := new(DeviceAuthorizationFlowProvider)
|
||||||
|
*p = x
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x DeviceAuthorizationFlowProvider) String() string {
|
||||||
|
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (DeviceAuthorizationFlowProvider) Descriptor() protoreflect.EnumDescriptor {
|
||||||
|
return file_management_proto_enumTypes[1].Descriptor()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (DeviceAuthorizationFlowProvider) Type() protoreflect.EnumType {
|
||||||
|
return &file_management_proto_enumTypes[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x DeviceAuthorizationFlowProvider) Number() protoreflect.EnumNumber {
|
||||||
|
return protoreflect.EnumNumber(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use DeviceAuthorizationFlowProvider.Descriptor instead.
|
||||||
|
func (DeviceAuthorizationFlowProvider) EnumDescriptor() ([]byte, []int) {
|
||||||
|
return file_management_proto_rawDescGZIP(), []int{15, 0}
|
||||||
|
}
|
||||||
|
|
||||||
type EncryptedMessage struct {
|
type EncryptedMessage struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
@ -973,6 +1016,180 @@ func (x *RemotePeerConfig) GetAllowedIps() []string {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeviceAuthorizationFlowRequest empty struct for future expansion
|
||||||
|
type DeviceAuthorizationFlowRequest struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DeviceAuthorizationFlowRequest) Reset() {
|
||||||
|
*x = DeviceAuthorizationFlowRequest{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_management_proto_msgTypes[14]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DeviceAuthorizationFlowRequest) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DeviceAuthorizationFlowRequest) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *DeviceAuthorizationFlowRequest) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_management_proto_msgTypes[14]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use DeviceAuthorizationFlowRequest.ProtoReflect.Descriptor instead.
|
||||||
|
func (*DeviceAuthorizationFlowRequest) Descriptor() ([]byte, []int) {
|
||||||
|
return file_management_proto_rawDescGZIP(), []int{14}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeviceAuthorizationFlow represents Device Authorization Flow information
|
||||||
|
// that can be used by the client to login initiate a Oauth 2.0 device authorization grant flow
|
||||||
|
// see https://datatracker.ietf.org/doc/html/rfc8628
|
||||||
|
type DeviceAuthorizationFlow struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
// An IDP provider , (eg. Auth0)
|
||||||
|
Provider DeviceAuthorizationFlowProvider `protobuf:"varint,1,opt,name=Provider,proto3,enum=management.DeviceAuthorizationFlowProvider" json:"Provider,omitempty"`
|
||||||
|
ProviderConfig *ProviderConfig `protobuf:"bytes,2,opt,name=ProviderConfig,proto3" json:"ProviderConfig,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DeviceAuthorizationFlow) Reset() {
|
||||||
|
*x = DeviceAuthorizationFlow{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_management_proto_msgTypes[15]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DeviceAuthorizationFlow) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DeviceAuthorizationFlow) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *DeviceAuthorizationFlow) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_management_proto_msgTypes[15]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use DeviceAuthorizationFlow.ProtoReflect.Descriptor instead.
|
||||||
|
func (*DeviceAuthorizationFlow) Descriptor() ([]byte, []int) {
|
||||||
|
return file_management_proto_rawDescGZIP(), []int{15}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DeviceAuthorizationFlow) GetProvider() DeviceAuthorizationFlowProvider {
|
||||||
|
if x != nil {
|
||||||
|
return x.Provider
|
||||||
|
}
|
||||||
|
return DeviceAuthorizationFlow_HOSTED
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DeviceAuthorizationFlow) GetProviderConfig() *ProviderConfig {
|
||||||
|
if x != nil {
|
||||||
|
return x.ProviderConfig
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProviderConfig has all attributes needed to initiate a device authorization flow
|
||||||
|
type ProviderConfig struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
// An IDP application client id
|
||||||
|
ClientID string `protobuf:"bytes,1,opt,name=ClientID,proto3" json:"ClientID,omitempty"`
|
||||||
|
// An IDP application client secret
|
||||||
|
ClientSecret string `protobuf:"bytes,2,opt,name=ClientSecret,proto3" json:"ClientSecret,omitempty"`
|
||||||
|
// An IDP API domain
|
||||||
|
Domain string `protobuf:"bytes,3,opt,name=Domain,proto3" json:"Domain,omitempty"`
|
||||||
|
// An Audience for validation
|
||||||
|
Audience string `protobuf:"bytes,4,opt,name=Audience,proto3" json:"Audience,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ProviderConfig) Reset() {
|
||||||
|
*x = ProviderConfig{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_management_proto_msgTypes[16]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ProviderConfig) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ProviderConfig) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *ProviderConfig) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_management_proto_msgTypes[16]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use ProviderConfig.ProtoReflect.Descriptor instead.
|
||||||
|
func (*ProviderConfig) Descriptor() ([]byte, []int) {
|
||||||
|
return file_management_proto_rawDescGZIP(), []int{16}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ProviderConfig) GetClientID() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.ClientID
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ProviderConfig) GetClientSecret() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.ClientSecret
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ProviderConfig) GetDomain() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Domain
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ProviderConfig) GetAudience() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Audience
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
var File_management_proto protoreflect.FileDescriptor
|
var File_management_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
var file_management_proto_rawDesc = []byte{
|
var file_management_proto_rawDesc = []byte{
|
||||||
@ -1094,26 +1311,54 @@ var file_management_proto_rawDesc = []byte{
|
|||||||
0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x67,
|
0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x77, 0x67,
|
||||||
0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65,
|
0x50, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65,
|
||||||
0x64, 0x49, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x6c, 0x6c, 0x6f,
|
0x64, 0x49, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x6c, 0x6c, 0x6f,
|
||||||
0x77, 0x65, 0x64, 0x49, 0x70, 0x73, 0x32, 0x9b, 0x02, 0x0a, 0x11, 0x4d, 0x61, 0x6e, 0x61, 0x67,
|
0x77, 0x65, 0x64, 0x49, 0x70, 0x73, 0x22, 0x20, 0x0a, 0x1e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
|
||||||
0x65, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x45, 0x0a, 0x05,
|
0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6c, 0x6f,
|
||||||
0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65,
|
0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xbf, 0x01, 0x0a, 0x17, 0x44, 0x65, 0x76,
|
||||||
0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73,
|
0x69, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||||
0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
|
0x46, 0x6c, 0x6f, 0x77, 0x12, 0x48, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
|
||||||
0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
|
0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
|
||||||
0x65, 0x22, 0x00, 0x12, 0x46, 0x0a, 0x04, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x1c, 0x2e, 0x6d, 0x61,
|
0x65, 0x6e, 0x74, 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
|
||||||
|
0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6c, 0x6f, 0x77, 0x2e, 0x70, 0x72, 0x6f, 0x76,
|
||||||
|
0x69, 0x64, 0x65, 0x72, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x42,
|
||||||
|
0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||||
|
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
|
||||||
|
0x65, 0x6e, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66,
|
||||||
|
0x69, 0x67, 0x52, 0x0e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66,
|
||||||
|
0x69, 0x67, 0x22, 0x16, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x0a,
|
||||||
|
0x0a, 0x06, 0x48, 0x4f, 0x53, 0x54, 0x45, 0x44, 0x10, 0x00, 0x22, 0x84, 0x01, 0x0a, 0x0e, 0x50,
|
||||||
|
0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a,
|
||||||
|
0x08, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||||
|
0x08, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x44, 0x12, 0x22, 0x0a, 0x0c, 0x43, 0x6c, 0x69,
|
||||||
|
0x65, 0x6e, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||||
|
0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x16, 0x0a,
|
||||||
|
0x06, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x44,
|
||||||
|
0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x41, 0x75, 0x64, 0x69, 0x65, 0x6e, 0x63,
|
||||||
|
0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x41, 0x75, 0x64, 0x69, 0x65, 0x6e, 0x63,
|
||||||
|
0x65, 0x32, 0xf7, 0x02, 0x0a, 0x11, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74,
|
||||||
|
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x45, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e,
|
||||||
|
0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e,
|
||||||
|
0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c,
|
||||||
|
0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72,
|
||||||
|
0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x12, 0x46,
|
||||||
|
0x0a, 0x04, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
|
||||||
|
0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73,
|
||||||
|
0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e,
|
||||||
|
0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61,
|
||||||
|
0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x42, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72,
|
||||||
|
0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d,
|
||||||
|
0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1d, 0x2e, 0x6d, 0x61, 0x6e, 0x61,
|
||||||
|
0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79,
|
||||||
|
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x33, 0x0a, 0x09, 0x69, 0x73,
|
||||||
|
0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x12, 0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65,
|
||||||
|
0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x6d, 0x61, 0x6e,
|
||||||
|
0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12,
|
||||||
|
0x5a, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x41, 0x75, 0x74, 0x68,
|
||||||
|
0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6c, 0x6f, 0x77, 0x12, 0x1c, 0x2e,
|
||||||
|
0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79,
|
||||||
|
0x70, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61,
|
||||||
0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74,
|
0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74,
|
||||||
0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x1c, 0x2e, 0x6d, 0x61, 0x6e, 0x61,
|
0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x42, 0x08, 0x5a, 0x06, 0x2f,
|
||||||
0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64,
|
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x42, 0x0a, 0x0c, 0x47,
|
|
||||||
0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x11, 0x2e, 0x6d, 0x61,
|
|
||||||
0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1d,
|
|
||||||
0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x72, 0x76,
|
|
||||||
0x65, 0x72, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
|
|
||||||
0x33, 0x0a, 0x09, 0x69, 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x12, 0x11, 0x2e, 0x6d,
|
|
||||||
0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a,
|
|
||||||
0x11, 0x2e, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6d, 0x70,
|
|
||||||
0x74, 0x79, 0x22, 0x00, 0x42, 0x08, 0x5a, 0x06, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06,
|
|
||||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -1128,55 +1373,63 @@ func file_management_proto_rawDescGZIP() []byte {
|
|||||||
return file_management_proto_rawDescData
|
return file_management_proto_rawDescData
|
||||||
}
|
}
|
||||||
|
|
||||||
var file_management_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
var file_management_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
|
||||||
var file_management_proto_msgTypes = make([]protoimpl.MessageInfo, 14)
|
var file_management_proto_msgTypes = make([]protoimpl.MessageInfo, 17)
|
||||||
var file_management_proto_goTypes = []interface{}{
|
var file_management_proto_goTypes = []interface{}{
|
||||||
(HostConfig_Protocol)(0), // 0: management.HostConfig.Protocol
|
(HostConfig_Protocol)(0), // 0: management.HostConfig.Protocol
|
||||||
(*EncryptedMessage)(nil), // 1: management.EncryptedMessage
|
(DeviceAuthorizationFlowProvider)(0), // 1: management.DeviceAuthorizationFlow.provider
|
||||||
(*SyncRequest)(nil), // 2: management.SyncRequest
|
(*EncryptedMessage)(nil), // 2: management.EncryptedMessage
|
||||||
(*SyncResponse)(nil), // 3: management.SyncResponse
|
(*SyncRequest)(nil), // 3: management.SyncRequest
|
||||||
(*LoginRequest)(nil), // 4: management.LoginRequest
|
(*SyncResponse)(nil), // 4: management.SyncResponse
|
||||||
(*PeerSystemMeta)(nil), // 5: management.PeerSystemMeta
|
(*LoginRequest)(nil), // 5: management.LoginRequest
|
||||||
(*LoginResponse)(nil), // 6: management.LoginResponse
|
(*PeerSystemMeta)(nil), // 6: management.PeerSystemMeta
|
||||||
(*ServerKeyResponse)(nil), // 7: management.ServerKeyResponse
|
(*LoginResponse)(nil), // 7: management.LoginResponse
|
||||||
(*Empty)(nil), // 8: management.Empty
|
(*ServerKeyResponse)(nil), // 8: management.ServerKeyResponse
|
||||||
(*WiretrusteeConfig)(nil), // 9: management.WiretrusteeConfig
|
(*Empty)(nil), // 9: management.Empty
|
||||||
(*HostConfig)(nil), // 10: management.HostConfig
|
(*WiretrusteeConfig)(nil), // 10: management.WiretrusteeConfig
|
||||||
(*ProtectedHostConfig)(nil), // 11: management.ProtectedHostConfig
|
(*HostConfig)(nil), // 11: management.HostConfig
|
||||||
(*PeerConfig)(nil), // 12: management.PeerConfig
|
(*ProtectedHostConfig)(nil), // 12: management.ProtectedHostConfig
|
||||||
(*NetworkMap)(nil), // 13: management.NetworkMap
|
(*PeerConfig)(nil), // 13: management.PeerConfig
|
||||||
(*RemotePeerConfig)(nil), // 14: management.RemotePeerConfig
|
(*NetworkMap)(nil), // 14: management.NetworkMap
|
||||||
(*timestamppb.Timestamp)(nil), // 15: google.protobuf.Timestamp
|
(*RemotePeerConfig)(nil), // 15: management.RemotePeerConfig
|
||||||
|
(*DeviceAuthorizationFlowRequest)(nil), // 16: management.DeviceAuthorizationFlowRequest
|
||||||
|
(*DeviceAuthorizationFlow)(nil), // 17: management.DeviceAuthorizationFlow
|
||||||
|
(*ProviderConfig)(nil), // 18: management.ProviderConfig
|
||||||
|
(*timestamppb.Timestamp)(nil), // 19: google.protobuf.Timestamp
|
||||||
}
|
}
|
||||||
var file_management_proto_depIdxs = []int32{
|
var file_management_proto_depIdxs = []int32{
|
||||||
9, // 0: management.SyncResponse.wiretrusteeConfig:type_name -> management.WiretrusteeConfig
|
10, // 0: management.SyncResponse.wiretrusteeConfig:type_name -> management.WiretrusteeConfig
|
||||||
12, // 1: management.SyncResponse.peerConfig:type_name -> management.PeerConfig
|
13, // 1: management.SyncResponse.peerConfig:type_name -> management.PeerConfig
|
||||||
14, // 2: management.SyncResponse.remotePeers:type_name -> management.RemotePeerConfig
|
15, // 2: management.SyncResponse.remotePeers:type_name -> management.RemotePeerConfig
|
||||||
13, // 3: management.SyncResponse.NetworkMap:type_name -> management.NetworkMap
|
14, // 3: management.SyncResponse.NetworkMap:type_name -> management.NetworkMap
|
||||||
5, // 4: management.LoginRequest.meta:type_name -> management.PeerSystemMeta
|
6, // 4: management.LoginRequest.meta:type_name -> management.PeerSystemMeta
|
||||||
9, // 5: management.LoginResponse.wiretrusteeConfig:type_name -> management.WiretrusteeConfig
|
10, // 5: management.LoginResponse.wiretrusteeConfig:type_name -> management.WiretrusteeConfig
|
||||||
12, // 6: management.LoginResponse.peerConfig:type_name -> management.PeerConfig
|
13, // 6: management.LoginResponse.peerConfig:type_name -> management.PeerConfig
|
||||||
15, // 7: management.ServerKeyResponse.expiresAt:type_name -> google.protobuf.Timestamp
|
19, // 7: management.ServerKeyResponse.expiresAt:type_name -> google.protobuf.Timestamp
|
||||||
10, // 8: management.WiretrusteeConfig.stuns:type_name -> management.HostConfig
|
11, // 8: management.WiretrusteeConfig.stuns:type_name -> management.HostConfig
|
||||||
11, // 9: management.WiretrusteeConfig.turns:type_name -> management.ProtectedHostConfig
|
12, // 9: management.WiretrusteeConfig.turns:type_name -> management.ProtectedHostConfig
|
||||||
10, // 10: management.WiretrusteeConfig.signal:type_name -> management.HostConfig
|
11, // 10: management.WiretrusteeConfig.signal:type_name -> management.HostConfig
|
||||||
0, // 11: management.HostConfig.protocol:type_name -> management.HostConfig.Protocol
|
0, // 11: management.HostConfig.protocol:type_name -> management.HostConfig.Protocol
|
||||||
10, // 12: management.ProtectedHostConfig.hostConfig:type_name -> management.HostConfig
|
11, // 12: management.ProtectedHostConfig.hostConfig:type_name -> management.HostConfig
|
||||||
12, // 13: management.NetworkMap.peerConfig:type_name -> management.PeerConfig
|
13, // 13: management.NetworkMap.peerConfig:type_name -> management.PeerConfig
|
||||||
14, // 14: management.NetworkMap.remotePeers:type_name -> management.RemotePeerConfig
|
15, // 14: management.NetworkMap.remotePeers:type_name -> management.RemotePeerConfig
|
||||||
1, // 15: management.ManagementService.Login:input_type -> management.EncryptedMessage
|
1, // 15: management.DeviceAuthorizationFlow.Provider:type_name -> management.DeviceAuthorizationFlow.provider
|
||||||
1, // 16: management.ManagementService.Sync:input_type -> management.EncryptedMessage
|
18, // 16: management.DeviceAuthorizationFlow.ProviderConfig:type_name -> management.ProviderConfig
|
||||||
8, // 17: management.ManagementService.GetServerKey:input_type -> management.Empty
|
2, // 17: management.ManagementService.Login:input_type -> management.EncryptedMessage
|
||||||
8, // 18: management.ManagementService.isHealthy:input_type -> management.Empty
|
2, // 18: management.ManagementService.Sync:input_type -> management.EncryptedMessage
|
||||||
1, // 19: management.ManagementService.Login:output_type -> management.EncryptedMessage
|
9, // 19: management.ManagementService.GetServerKey:input_type -> management.Empty
|
||||||
1, // 20: management.ManagementService.Sync:output_type -> management.EncryptedMessage
|
9, // 20: management.ManagementService.isHealthy:input_type -> management.Empty
|
||||||
7, // 21: management.ManagementService.GetServerKey:output_type -> management.ServerKeyResponse
|
2, // 21: management.ManagementService.GetDeviceAuthorizationFlow:input_type -> management.EncryptedMessage
|
||||||
8, // 22: management.ManagementService.isHealthy:output_type -> management.Empty
|
2, // 22: management.ManagementService.Login:output_type -> management.EncryptedMessage
|
||||||
19, // [19:23] is the sub-list for method output_type
|
2, // 23: management.ManagementService.Sync:output_type -> management.EncryptedMessage
|
||||||
15, // [15:19] is the sub-list for method input_type
|
8, // 24: management.ManagementService.GetServerKey:output_type -> management.ServerKeyResponse
|
||||||
15, // [15:15] is the sub-list for extension type_name
|
9, // 25: management.ManagementService.isHealthy:output_type -> management.Empty
|
||||||
15, // [15:15] is the sub-list for extension extendee
|
2, // 26: management.ManagementService.GetDeviceAuthorizationFlow:output_type -> management.EncryptedMessage
|
||||||
0, // [0:15] is the sub-list for field type_name
|
22, // [22:27] is the sub-list for method output_type
|
||||||
|
17, // [17:22] is the sub-list for method input_type
|
||||||
|
17, // [17:17] is the sub-list for extension type_name
|
||||||
|
17, // [17:17] is the sub-list for extension extendee
|
||||||
|
0, // [0:17] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_management_proto_init() }
|
func init() { file_management_proto_init() }
|
||||||
@ -1353,14 +1606,50 @@ func file_management_proto_init() {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
file_management_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*DeviceAuthorizationFlowRequest); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_management_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*DeviceAuthorizationFlow); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_management_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*ProviderConfig); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
type x struct{}
|
type x struct{}
|
||||||
out := protoimpl.TypeBuilder{
|
out := protoimpl.TypeBuilder{
|
||||||
File: protoimpl.DescBuilder{
|
File: protoimpl.DescBuilder{
|
||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: file_management_proto_rawDesc,
|
RawDescriptor: file_management_proto_rawDesc,
|
||||||
NumEnums: 1,
|
NumEnums: 2,
|
||||||
NumMessages: 14,
|
NumMessages: 17,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 1,
|
NumServices: 1,
|
||||||
},
|
},
|
||||||
|
@ -24,6 +24,13 @@ service ManagementService {
|
|||||||
|
|
||||||
// health check endpoint
|
// health check endpoint
|
||||||
rpc isHealthy(Empty) returns (Empty) {}
|
rpc isHealthy(Empty) returns (Empty) {}
|
||||||
|
|
||||||
|
// Exposes a device authorization flow information
|
||||||
|
// This is used for initiating a Oauth 2 device authorization grant flow
|
||||||
|
// which will be used by our clients to Login.
|
||||||
|
// EncryptedMessage of the request has a body of DeviceAuthorizationFlowRequest.
|
||||||
|
// EncryptedMessage of the response has a body of DeviceAuthorizationFlow.
|
||||||
|
rpc GetDeviceAuthorizationFlow(EncryptedMessage) returns (EncryptedMessage) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
message EncryptedMessage {
|
message EncryptedMessage {
|
||||||
@ -165,3 +172,29 @@ message RemotePeerConfig {
|
|||||||
// Wireguard allowed IPs of a remote peer e.g. [10.30.30.1/32]
|
// Wireguard allowed IPs of a remote peer e.g. [10.30.30.1/32]
|
||||||
repeated string allowedIps = 2;
|
repeated string allowedIps = 2;
|
||||||
}
|
}
|
||||||
|
// DeviceAuthorizationFlowRequest empty struct for future expansion
|
||||||
|
message DeviceAuthorizationFlowRequest {}
|
||||||
|
// DeviceAuthorizationFlow represents Device Authorization Flow information
|
||||||
|
// that can be used by the client to login initiate a Oauth 2.0 device authorization grant flow
|
||||||
|
// see https://datatracker.ietf.org/doc/html/rfc8628
|
||||||
|
message DeviceAuthorizationFlow {
|
||||||
|
// An IDP provider , (eg. Auth0)
|
||||||
|
provider Provider = 1;
|
||||||
|
ProviderConfig ProviderConfig = 2;
|
||||||
|
|
||||||
|
enum provider {
|
||||||
|
HOSTED = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProviderConfig has all attributes needed to initiate a device authorization flow
|
||||||
|
message ProviderConfig {
|
||||||
|
// An IDP application client id
|
||||||
|
string ClientID = 1;
|
||||||
|
// An IDP application client secret
|
||||||
|
string ClientSecret = 2;
|
||||||
|
// An IDP API domain
|
||||||
|
string Domain =3;
|
||||||
|
// An Audience for validation
|
||||||
|
string Audience = 4;
|
||||||
|
}
|
@ -31,6 +31,10 @@ type ManagementServiceClient interface {
|
|||||||
GetServerKey(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ServerKeyResponse, error)
|
GetServerKey(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ServerKeyResponse, error)
|
||||||
// health check endpoint
|
// health check endpoint
|
||||||
IsHealthy(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error)
|
IsHealthy(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error)
|
||||||
|
// Exposes a device authorization flow information
|
||||||
|
// This is used for initiating a Oauth 2 device authorization grant flow
|
||||||
|
// which will be used by our clients to Login
|
||||||
|
GetDeviceAuthorizationFlow(ctx context.Context, in *EncryptedMessage, opts ...grpc.CallOption) (*EncryptedMessage, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type managementServiceClient struct {
|
type managementServiceClient struct {
|
||||||
@ -100,6 +104,15 @@ func (c *managementServiceClient) IsHealthy(ctx context.Context, in *Empty, opts
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *managementServiceClient) GetDeviceAuthorizationFlow(ctx context.Context, in *EncryptedMessage, opts ...grpc.CallOption) (*EncryptedMessage, error) {
|
||||||
|
out := new(EncryptedMessage)
|
||||||
|
err := c.cc.Invoke(ctx, "/management.ManagementService/GetDeviceAuthorizationFlow", in, out, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ManagementServiceServer is the server API for ManagementService service.
|
// ManagementServiceServer is the server API for ManagementService service.
|
||||||
// All implementations must embed UnimplementedManagementServiceServer
|
// All implementations must embed UnimplementedManagementServiceServer
|
||||||
// for forward compatibility
|
// for forward compatibility
|
||||||
@ -117,6 +130,10 @@ type ManagementServiceServer interface {
|
|||||||
GetServerKey(context.Context, *Empty) (*ServerKeyResponse, error)
|
GetServerKey(context.Context, *Empty) (*ServerKeyResponse, error)
|
||||||
// health check endpoint
|
// health check endpoint
|
||||||
IsHealthy(context.Context, *Empty) (*Empty, error)
|
IsHealthy(context.Context, *Empty) (*Empty, error)
|
||||||
|
// Exposes a device authorization flow information
|
||||||
|
// This is used for initiating a Oauth 2 device authorization grant flow
|
||||||
|
// which will be used by our clients to Login
|
||||||
|
GetDeviceAuthorizationFlow(context.Context, *EncryptedMessage) (*EncryptedMessage, error)
|
||||||
mustEmbedUnimplementedManagementServiceServer()
|
mustEmbedUnimplementedManagementServiceServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,6 +153,9 @@ func (UnimplementedManagementServiceServer) GetServerKey(context.Context, *Empty
|
|||||||
func (UnimplementedManagementServiceServer) IsHealthy(context.Context, *Empty) (*Empty, error) {
|
func (UnimplementedManagementServiceServer) IsHealthy(context.Context, *Empty) (*Empty, error) {
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method IsHealthy not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method IsHealthy not implemented")
|
||||||
}
|
}
|
||||||
|
func (UnimplementedManagementServiceServer) GetDeviceAuthorizationFlow(context.Context, *EncryptedMessage) (*EncryptedMessage, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method GetDeviceAuthorizationFlow not implemented")
|
||||||
|
}
|
||||||
func (UnimplementedManagementServiceServer) mustEmbedUnimplementedManagementServiceServer() {}
|
func (UnimplementedManagementServiceServer) mustEmbedUnimplementedManagementServiceServer() {}
|
||||||
|
|
||||||
// UnsafeManagementServiceServer may be embedded to opt out of forward compatibility for this service.
|
// UnsafeManagementServiceServer may be embedded to opt out of forward compatibility for this service.
|
||||||
@ -224,6 +244,24 @@ func _ManagementService_IsHealthy_Handler(srv interface{}, ctx context.Context,
|
|||||||
return interceptor(ctx, in, info, handler)
|
return interceptor(ctx, in, info, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _ManagementService_GetDeviceAuthorizationFlow_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(EncryptedMessage)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(ManagementServiceServer).GetDeviceAuthorizationFlow(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: "/management.ManagementService/GetDeviceAuthorizationFlow",
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(ManagementServiceServer).GetDeviceAuthorizationFlow(ctx, req.(*EncryptedMessage))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
// ManagementService_ServiceDesc is the grpc.ServiceDesc for ManagementService service.
|
// ManagementService_ServiceDesc is the grpc.ServiceDesc for ManagementService service.
|
||||||
// It's only intended for direct use with grpc.RegisterService,
|
// It's only intended for direct use with grpc.RegisterService,
|
||||||
// and not to be introspected or modified (even as a copy)
|
// and not to be introspected or modified (even as a copy)
|
||||||
@ -243,6 +281,10 @@ var ManagementService_ServiceDesc = grpc.ServiceDesc{
|
|||||||
MethodName: "isHealthy",
|
MethodName: "isHealthy",
|
||||||
Handler: _ManagementService_IsHealthy_Handler,
|
Handler: _ManagementService_IsHealthy_Handler,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MethodName: "GetDeviceAuthorizationFlow",
|
||||||
|
Handler: _ManagementService_GetDeviceAuthorizationFlow_Handler,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Streams: []grpc.StreamDesc{
|
Streams: []grpc.StreamDesc{
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Protocol string
|
type Protocol string
|
||||||
|
type Provider string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
UDP Protocol = "udp"
|
UDP Protocol = "udp"
|
||||||
@ -14,6 +15,7 @@ const (
|
|||||||
TCP Protocol = "tcp"
|
TCP Protocol = "tcp"
|
||||||
HTTP Protocol = "http"
|
HTTP Protocol = "http"
|
||||||
HTTPS Protocol = "https"
|
HTTPS Protocol = "https"
|
||||||
|
AUTH0 Provider = "auth0"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config of the Management service
|
// Config of the Management service
|
||||||
@ -27,6 +29,8 @@ type Config struct {
|
|||||||
HttpConfig *HttpServerConfig
|
HttpConfig *HttpServerConfig
|
||||||
|
|
||||||
IdpManagerConfig *idp.Config
|
IdpManagerConfig *idp.Config
|
||||||
|
|
||||||
|
DeviceAuthorizationFlow *DeviceAuthorizationFlow
|
||||||
}
|
}
|
||||||
|
|
||||||
// TURNConfig is a config of the TURNCredentialsManager
|
// TURNConfig is a config of the TURNCredentialsManager
|
||||||
@ -62,6 +66,26 @@ type Host struct {
|
|||||||
Password string
|
Password string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeviceAuthorizationFlow represents Device Authorization Flow information
|
||||||
|
// that can be used by the client to login initiate a Oauth 2.0 device authorization grant flow
|
||||||
|
// see https://datatracker.ietf.org/doc/html/rfc8628
|
||||||
|
type DeviceAuthorizationFlow struct {
|
||||||
|
Provider string
|
||||||
|
ProviderConfig ProviderConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProviderConfig has all attributes needed to initiate a device authorization flow
|
||||||
|
type ProviderConfig struct {
|
||||||
|
// ClientID An IDP application client id
|
||||||
|
ClientID string
|
||||||
|
// ClientSecret An IDP application client secret
|
||||||
|
ClientSecret string
|
||||||
|
// Domain An IDP API domain
|
||||||
|
Domain string
|
||||||
|
// Audience An Audience for to authorization validation
|
||||||
|
Audience string
|
||||||
|
}
|
||||||
|
|
||||||
// validateURL validates input http url
|
// validateURL validates input http url
|
||||||
func validateURL(httpURL string) bool {
|
func validateURL(httpURL string) bool {
|
||||||
_, err := url.ParseRequestURI(httpURL)
|
_, err := url.ParseRequestURI(httpURL)
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/netbirdio/netbird/management/server/http/middleware"
|
"github.com/netbirdio/netbird/management/server/http/middleware"
|
||||||
"github.com/netbirdio/netbird/management/server/jwtclaims"
|
"github.com/netbirdio/netbird/management/server/jwtclaims"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/golang/protobuf/ptypes/timestamp"
|
"github.com/golang/protobuf/ptypes/timestamp"
|
||||||
@ -47,6 +48,8 @@ func NewServer(config *Config, accountManager AccountManager, peersUpdateManager
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "unable to create new jwt middleware, err: %v", err)
|
return nil, status.Errorf(codes.Internal, "unable to create new jwt middleware, err: %v", err)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
log.Debug("unable to use http config to create new jwt middleware")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Server{
|
return &Server{
|
||||||
@ -425,3 +428,52 @@ func (s *Server) sendInitialSync(peerKey wgtypes.Key, peer *Peer, srv proto.Mana
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDeviceAuthorizationFlow returns a device authorization flow information
|
||||||
|
// This is used for initiating an Oauth 2 device authorization grant flow
|
||||||
|
// which will be used by our clients to Login
|
||||||
|
func (s *Server) GetDeviceAuthorizationFlow(ctx context.Context, req *proto.EncryptedMessage) (*proto.EncryptedMessage, error) {
|
||||||
|
|
||||||
|
peerKey, err := wgtypes.ParseKey(req.GetWgPubKey())
|
||||||
|
if err != nil {
|
||||||
|
errMSG := fmt.Sprintf("error while parsing peer's Wireguard public key %s on GetDeviceAuthorizationFlow request.", req.WgPubKey)
|
||||||
|
log.Warn(errMSG)
|
||||||
|
return nil, status.Error(codes.InvalidArgument, errMSG)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = encryption.DecryptMessage(peerKey, s.wgKey, req.Body, &proto.DeviceAuthorizationFlowRequest{})
|
||||||
|
if err != nil {
|
||||||
|
errMSG := fmt.Sprintf("error while decrypting peer's message with Wireguard public key %s.", req.WgPubKey)
|
||||||
|
log.Warn(errMSG)
|
||||||
|
return nil, status.Error(codes.InvalidArgument, errMSG)
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.config.DeviceAuthorizationFlow == nil {
|
||||||
|
return nil, status.Error(codes.NotFound, "no device authorization flow information available")
|
||||||
|
}
|
||||||
|
|
||||||
|
provider, ok := proto.DeviceAuthorizationFlowProvider_value[strings.ToUpper(s.config.DeviceAuthorizationFlow.Provider)]
|
||||||
|
if !ok {
|
||||||
|
return nil, status.Errorf(codes.InvalidArgument, "no provider found in the protocol for %s", s.config.DeviceAuthorizationFlow.Provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
flowInfoResp := &proto.DeviceAuthorizationFlow{
|
||||||
|
Provider: proto.DeviceAuthorizationFlowProvider(provider),
|
||||||
|
ProviderConfig: &proto.ProviderConfig{
|
||||||
|
ClientID: s.config.DeviceAuthorizationFlow.ProviderConfig.ClientID,
|
||||||
|
ClientSecret: s.config.DeviceAuthorizationFlow.ProviderConfig.ClientSecret,
|
||||||
|
Domain: s.config.DeviceAuthorizationFlow.ProviderConfig.Domain,
|
||||||
|
Audience: s.config.DeviceAuthorizationFlow.ProviderConfig.Audience,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
encryptedResp, err := encryption.EncryptMessage(peerKey, s.wgKey, flowInfoResp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, status.Error(codes.Internal, "failed to encrypt no device authorization flow information")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &proto.EncryptedMessage{
|
||||||
|
WgPubKey: s.wgKey.PublicKey().String(),
|
||||||
|
Body: encryptedResp,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"github.com/netbirdio/netbird/encryption"
|
"github.com/netbirdio/netbird/encryption"
|
||||||
mgmtProto "github.com/netbirdio/netbird/management/proto"
|
mgmtProto "github.com/netbirdio/netbird/management/proto"
|
||||||
"github.com/netbirdio/netbird/util"
|
"github.com/netbirdio/netbird/util"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/stretchr/testify/require"
|
||||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
@ -85,7 +85,7 @@ func Test_SyncProtocol(t *testing.T) {
|
|||||||
os.Remove(filepath.Join(dir, "store.json")) //nolint
|
os.Remove(filepath.Join(dir, "store.json")) //nolint
|
||||||
}()
|
}()
|
||||||
mport := 33091
|
mport := 33091
|
||||||
mgmtServer, err := startManagement(mport, &Config{
|
mgmtServer, err := startManagement(t, mport, &Config{
|
||||||
Stuns: []*Host{{
|
Stuns: []*Host{{
|
||||||
Proto: "udp",
|
Proto: "udp",
|
||||||
URI: "stun:stun.wiretrustee.com:3468",
|
URI: "stun:stun.wiretrustee.com:3468",
|
||||||
@ -301,7 +301,102 @@ func loginPeerWithValidSetupKey(key wgtypes.Key, client mgmtProto.ManagementServ
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func startManagement(port int, config *Config) (*grpc.Server, error) {
|
func TestServer_GetDeviceAuthorizationFlow(t *testing.T) {
|
||||||
|
|
||||||
|
testingServerKey, err := wgtypes.GeneratePrivateKey()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unable to generate server wg key for testing GetDeviceAuthorizationFlow, error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
testingClientKey, err := wgtypes.GeneratePrivateKey()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unable to generate client wg key for testing GetDeviceAuthorizationFlow, error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
inputFlow *DeviceAuthorizationFlow
|
||||||
|
expectedFlow *mgmtProto.DeviceAuthorizationFlow
|
||||||
|
expectedErrFunc require.ErrorAssertionFunc
|
||||||
|
expectedErrMSG string
|
||||||
|
expectedComparisonFunc require.ComparisonAssertionFunc
|
||||||
|
expectedComparisonMSG string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Testing No Device Flow Config",
|
||||||
|
inputFlow: nil,
|
||||||
|
expectedErrFunc: require.Error,
|
||||||
|
expectedErrMSG: "should return error",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Testing Invalid Device Flow Provider Config",
|
||||||
|
inputFlow: &DeviceAuthorizationFlow{
|
||||||
|
Provider: "NoNe",
|
||||||
|
ProviderConfig: ProviderConfig{
|
||||||
|
ClientID: "test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedErrFunc: require.Error,
|
||||||
|
expectedErrMSG: "should return error",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Testing Full Device Flow Config",
|
||||||
|
inputFlow: &DeviceAuthorizationFlow{
|
||||||
|
Provider: "hosted",
|
||||||
|
ProviderConfig: ProviderConfig{
|
||||||
|
ClientID: "test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedFlow: &mgmtProto.DeviceAuthorizationFlow{
|
||||||
|
Provider: 0,
|
||||||
|
ProviderConfig: &mgmtProto.ProviderConfig{
|
||||||
|
ClientID: "test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedErrFunc: require.NoError,
|
||||||
|
expectedErrMSG: "should not return error",
|
||||||
|
expectedComparisonFunc: require.Equal,
|
||||||
|
expectedComparisonMSG: "should match",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
|
|
||||||
|
mgmtServer := &Server{
|
||||||
|
wgKey: testingServerKey,
|
||||||
|
config: &Config{
|
||||||
|
DeviceAuthorizationFlow: testCase.inputFlow,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
message := &mgmtProto.DeviceAuthorizationFlowRequest{}
|
||||||
|
|
||||||
|
encryptedMSG, err := encryption.EncryptMessage(testingClientKey.PublicKey(), mgmtServer.wgKey, message)
|
||||||
|
require.NoError(t, err, "should be able to encrypt message")
|
||||||
|
|
||||||
|
resp, err := mgmtServer.GetDeviceAuthorizationFlow(
|
||||||
|
context.TODO(),
|
||||||
|
&mgmtProto.EncryptedMessage{
|
||||||
|
WgPubKey: testingClientKey.PublicKey().String(),
|
||||||
|
Body: encryptedMSG,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
testCase.expectedErrFunc(t, err, testCase.expectedErrMSG)
|
||||||
|
if testCase.expectedComparisonFunc != nil {
|
||||||
|
flowInfoResp := &mgmtProto.DeviceAuthorizationFlow{}
|
||||||
|
|
||||||
|
err = encryption.DecryptMessage(mgmtServer.wgKey.PublicKey(), testingClientKey, resp.Body, flowInfoResp)
|
||||||
|
require.NoError(t, err, "should be able to decrypt")
|
||||||
|
|
||||||
|
testCase.expectedComparisonFunc(t, testCase.expectedFlow.Provider, flowInfoResp.Provider, testCase.expectedComparisonMSG)
|
||||||
|
testCase.expectedComparisonFunc(t, testCase.expectedFlow.ProviderConfig.ClientID, flowInfoResp.ProviderConfig.ClientID, testCase.expectedComparisonMSG)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startManagement(t *testing.T, port int, config *Config) (*grpc.Server, error) {
|
||||||
|
|
||||||
lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", port))
|
lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", port))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -320,9 +415,10 @@ func startManagement(port int, config *Config) (*grpc.Server, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
mgmtProto.RegisterManagementServiceServer(s, mgmtServer)
|
mgmtProto.RegisterManagementServiceServer(s, mgmtServer)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
if err = s.Serve(lis); err != nil {
|
if err = s.Serve(lis); err != nil {
|
||||||
log.Fatalf("failed to serve: %v", err)
|
t.Errorf("failed to serve: %v", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ type ManagementServiceServerMock struct {
|
|||||||
SyncFunc func(*proto.EncryptedMessage, proto.ManagementService_SyncServer)
|
SyncFunc func(*proto.EncryptedMessage, proto.ManagementService_SyncServer)
|
||||||
GetServerKeyFunc func(context.Context, *proto.Empty) (*proto.ServerKeyResponse, error)
|
GetServerKeyFunc func(context.Context, *proto.Empty) (*proto.ServerKeyResponse, error)
|
||||||
IsHealthyFunc func(context.Context, *proto.Empty) (*proto.Empty, error)
|
IsHealthyFunc func(context.Context, *proto.Empty) (*proto.Empty, error)
|
||||||
|
GetDeviceAuthorizationFlowFunc func(ctx context.Context, req *proto.EncryptedMessage) (*proto.EncryptedMessage, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m ManagementServiceServerMock) Login(ctx context.Context, req *proto.EncryptedMessage) (*proto.EncryptedMessage, error) {
|
func (m ManagementServiceServerMock) Login(ctx context.Context, req *proto.EncryptedMessage) (*proto.EncryptedMessage, error) {
|
||||||
@ -44,3 +45,10 @@ func (m ManagementServiceServerMock) IsHealthy(ctx context.Context, empty *proto
|
|||||||
}
|
}
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method IsHealthy not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method IsHealthy not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m ManagementServiceServerMock) GetDeviceAuthorizationFlow(ctx context.Context, req *proto.EncryptedMessage) (*proto.EncryptedMessage, error) {
|
||||||
|
if m.GetDeviceAuthorizationFlowFunc != nil {
|
||||||
|
return m.GetDeviceAuthorizationFlowFunc(ctx, req)
|
||||||
|
}
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method GetDeviceAuthorizationFlow not implemented")
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user