Skip to content

Commit b636d72

Browse files
authored
RSDK-12351 - remove location secret connection code (#659)
1 parent 98b8e0e commit b636d72

File tree

3 files changed

+63
-89
lines changed

3 files changed

+63
-89
lines changed

src/app/viam-client.spec.ts

Lines changed: 29 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
// @vitest-environment happy-dom
22

33
import { beforeEach, describe, expect, it, vi } from 'vitest';
4-
import { Location, RobotPart, SharedSecret_State } from '../gen/app/v1/app_pb';
4+
import {
5+
GetRobotPartByNameAndLocationResponse,
6+
RobotPart,
7+
} from '../gen/app/v1/app_pb';
58
import { createRobotClient } from '../robot/dial';
69
import { AppClient } from './app-client';
710
import { BillingClient } from './billing-client';
@@ -156,98 +159,64 @@ describe('ViamClient', () => {
156159
).rejects.toThrowError('not provided and could not be obtained');
157160
});
158161

159-
it('gets location secret if credential is access token -- host', async () => {
162+
it('gets robot secret if credential is access token -- host', async () => {
160163
options = { credentials: testAccessToken };
161164
const client = await subject();
162165

163-
const location = new Location({
164-
auth: {
165-
secrets: [
166-
{
167-
id: '0',
168-
state: SharedSecret_State.DISABLED, // eslint-disable-line camelcase
169-
secret: 'disabled secret',
170-
},
171-
{
172-
id: '1',
173-
state: SharedSecret_State.UNSPECIFIED, // eslint-disable-line camelcase
174-
secret: 'unspecified secret',
175-
},
176-
{
177-
id: '2',
178-
state: SharedSecret_State.ENABLED, // eslint-disable-line camelcase
179-
secret: 'enabled secret',
180-
},
181-
],
182-
locationId: 'location',
183-
secret: 'secret',
184-
},
166+
const MAIN_PART = new RobotPart({
167+
mainPart: true,
168+
name: 'main-part',
169+
secret: 'fake-robot-secret',
185170
});
186-
const getLocationMock = vi.fn().mockImplementation(() => location);
187-
AppClient.prototype.getLocation = getLocationMock;
171+
const partByNameAndLocationResponse =
172+
new GetRobotPartByNameAndLocationResponse({
173+
part: MAIN_PART,
174+
});
175+
const getRobotPartByNameAndLocationMock = vi
176+
.fn()
177+
.mockImplementation(() => partByNameAndLocationResponse);
178+
AppClient.prototype.getRobotPartByNameAndLocation =
179+
getRobotPartByNameAndLocationMock;
188180

189181
await client.connectToMachine({
190182
host: 'main-part.location.viam.cloud',
191183
});
192-
expect(getLocationMock).toHaveBeenCalledWith('location');
184+
expect(getRobotPartByNameAndLocationMock).toHaveBeenCalledWith(
185+
'main-part',
186+
'location'
187+
);
193188
expect(createRobotClient).toHaveBeenCalledWith(
194189
expect.objectContaining({
195190
credentials: expect.objectContaining({
196-
type: 'robot-location-secret',
197-
payload: 'enabled secret',
191+
type: 'robot-secret',
192+
payload: 'fake-robot-secret',
198193
}),
199194
})
200195
);
201196
});
202197

203-
it('gets location secret if credential is access token -- id', async () => {
198+
it('gets robot secret if credential is access token -- id', async () => {
204199
options = { credentials: testAccessToken };
205200
const client = await subject();
206201

207202
const MAIN_PART = new RobotPart({
208203
mainPart: true,
209-
locationId: 'location-id',
210204
fqdn: 'main-part.fqdn',
205+
secret: 'fake-robot-secret',
211206
});
212207
const robotParts = [MAIN_PART];
213208
const getRobotPartsMock = vi.fn().mockImplementation(() => robotParts);
214209
AppClient.prototype.getRobotParts = getRobotPartsMock;
215210

216-
const location = new Location({
217-
auth: {
218-
secrets: [
219-
{
220-
id: '0',
221-
state: SharedSecret_State.DISABLED, // eslint-disable-line camelcase
222-
secret: 'disabled secret',
223-
},
224-
{
225-
id: '1',
226-
state: SharedSecret_State.UNSPECIFIED, // eslint-disable-line camelcase
227-
secret: 'unspecified secret',
228-
},
229-
{
230-
id: '2',
231-
state: SharedSecret_State.ENABLED, // eslint-disable-line camelcase
232-
secret: 'enabled secret',
233-
},
234-
],
235-
locationId: 'location',
236-
secret: 'secret',
237-
},
238-
});
239-
const getLocationMock = vi.fn().mockImplementation(() => location);
240-
AppClient.prototype.getLocation = getLocationMock;
241-
242211
await client.connectToMachine({
243212
id: 'machine-uuid',
244213
});
245-
expect(getLocationMock).toHaveBeenCalledWith('location-id');
214+
expect(getRobotPartsMock).toHaveBeenCalledWith('machine-uuid');
246215
expect(createRobotClient).toHaveBeenCalledWith(
247216
expect.objectContaining({
248217
credentials: expect.objectContaining({
249-
type: 'robot-location-secret',
250-
payload: 'enabled secret',
218+
type: 'robot-secret',
219+
payload: 'fake-robot-secret',
251220
}),
252221
})
253222
);

src/app/viam-client.ts

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import type { Transport } from '@connectrpc/connect';
2-
import { SharedSecret_State } from '../gen/app/v1/app_pb';
32
import { createRobotClient } from '../robot/dial';
43
import { AppClient } from './app-client';
54
import { BillingClient } from './billing-client';
@@ -54,6 +53,26 @@ export class ViamClient {
5453
this.billingClient = new BillingClient(this.transport);
5554
}
5655

56+
async getRobotSecretFromHost(host: string): Promise<string | undefined> {
57+
const firstHalf = host.split('.viam.');
58+
const locationSplit = firstHalf[0]?.split('.');
59+
if (locationSplit !== undefined) {
60+
const locationId = locationSplit.at(-1);
61+
if (locationId === undefined) {
62+
return undefined;
63+
}
64+
const name = host.split('.').at(0);
65+
if (name !== undefined) {
66+
const resp = await this.appClient.getRobotPartByNameAndLocation(
67+
name,
68+
locationId
69+
);
70+
return resp.part?.secret;
71+
}
72+
}
73+
return undefined;
74+
}
75+
5776
public async connectToMachine({
5877
host = undefined,
5978
id = undefined,
@@ -62,7 +81,7 @@ export class ViamClient {
6281
throw new Error('Either a machine address or ID must be provided');
6382
}
6483
let address = host;
65-
let locationId: string | undefined = undefined;
84+
let robotSecret: string | undefined = undefined;
6685

6786
// Get address if only ID was provided
6887
if (id !== undefined && host === undefined) {
@@ -74,7 +93,7 @@ export class ViamClient {
7493
);
7594
}
7695
address = mainPart.fqdn;
77-
locationId = mainPart.locationId;
96+
robotSecret = mainPart.secret;
7897
}
7998

8099
if (address === undefined || address === '') {
@@ -83,31 +102,20 @@ export class ViamClient {
83102
);
84103
}
85104

86-
// If credentials is AccessToken, then attempt to get the robot location secret
105+
// If credentials is AccessToken, then attempt to use the robot part secret
87106
let creds = this.credentials;
88107
if (!isCredential(creds)) {
89-
if (locationId === undefined) {
90-
// If we don't have a location, try to get it from the address
91-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
92-
const firstHalf = address.split('.viam.');
93-
const locationSplit = firstHalf[0]?.split('.');
94-
if (locationSplit !== undefined) {
95-
locationId = locationSplit.at(-1);
96-
}
97-
}
98-
if (locationId !== undefined) {
99-
// If we found the location, then attempt to get its secret
100-
const location = await this.appClient.getLocation(locationId);
101-
const secret = location?.auth?.secrets.find(
102-
// eslint-disable-next-line camelcase
103-
(sec) => sec.state === SharedSecret_State.ENABLED
104-
);
105-
creds = {
106-
type: 'robot-location-secret',
107-
payload: secret?.secret,
108-
authEntity: address,
109-
} as Credential;
108+
if (robotSecret === undefined) {
109+
robotSecret = await this.getRobotSecretFromHost(address);
110110
}
111+
creds =
112+
robotSecret === undefined
113+
? creds
114+
: ({
115+
type: 'robot-secret',
116+
payload: robotSecret,
117+
authEntity: address,
118+
} as Credential);
111119
}
112120

113121
return createRobotClient({

src/app/viam-transport.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@ export interface Credential {
1616
payload: string;
1717
}
1818

19-
export type CredentialType =
20-
| 'robot-location-secret'
21-
| 'api-key'
22-
| 'robot-secret';
19+
export type CredentialType = 'api-key' | 'robot-secret';
2320

2421
/** An access token used to access protected resources. */
2522
export interface AccessToken {

0 commit comments

Comments
 (0)