Skip to content

Commit

Permalink
[ENG-5145] converge with gravyvalet backend (#2234)
Browse files Browse the repository at this point in the history
-   Ticket: [ENG-5145]
-   Feature flag: n/a

## Purpose
- converge with [gravyvalet backend](CenterForOpenScience/gravyvalet#64)

## Summary of Changes
- `addons_service` adapter: include auth cookies with requests
- consistent `displayName` attr on external services, authorized accounts, and configured addons
- add `thruAccount` relation to addon-operation-invocations (to allow the account owner to e.g. choose an authorized root folder without having configured an addon yet)
- some renames for consistency
- skip unused `credentials` members (allow/default to `{}`)
  • Loading branch information
aaxelb authored Jun 12, 2024
1 parent a8c5be9 commit 9fea8b2
Show file tree
Hide file tree
Showing 39 changed files with 211 additions and 220 deletions.
6 changes: 6 additions & 0 deletions app/adapters/addon-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,10 @@ export const addonServiceAPIUrl = `${addonServiceUrl}${addonServiceNamespace}/`;
export default class AddonServiceAdapter extends JSONAPIAdapter {
host = addonServiceUrl.replace(/\/$/, ''); // Remove trailing slash to avoid // in URLs
namespace = addonServiceNamespace;

ajaxOptions(url: string, type: string, options?: any): object {
const _ajaxopts: any = super.ajaxOptions(url, type, options);
_ajaxopts.credentials = 'include';
return _ajaxopts;
}
}
8 changes: 4 additions & 4 deletions app/guid-node/addons/index/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
{{#if manager.selectedProvider}}
{{#let manager.selectedProvider as |provider|}}
<div
data-test-addon={{provider.provider.name}}
data-analytics-scope='Addon - {{provider.provider.name}}'
data-test-addon={{provider.provider.displayName}}
data-analytics-scope='Addon - {{provider.provider.displayName}}'
>
{{#if (eq manager.pageMode 'terms')}}
<AddonsService::TermsOfService
Expand Down Expand Up @@ -206,7 +206,7 @@
as |dialog|
>
<dialog.heading>
{{t 'addons.list.disconnect'}} {{provider.provider.name}}
{{t 'addons.list.disconnect'}} {{provider.provider.displayName}}
</dialog.heading>
<dialog.main>
{{t 'addons.list.confirm-remove-connected-location'}}
Expand Down Expand Up @@ -363,4 +363,4 @@
</AriaTabs>
{{/if}}
</AddonsService::Manager>
</div>
</div>
13 changes: 8 additions & 5 deletions app/models/addon-operation-invocation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@ import Model, { AsyncBelongsTo, attr, belongsTo } from '@ember-data/model';

import UserReferenceModel from 'ember-osf-web/models/user-reference';
import ConfiguredAddonModel from 'ember-osf-web/models/configured-addon';
import AuthorizedAccountModel from 'ember-osf-web/models/authorized-account';
import { ConnectedOperationNames } from 'ember-osf-web/models/configured-storage-addon';

export enum InvocationStatus {
// TODO: are these right?
Success = 'SUCCESS',
Failure = 'FAILURE',
Pending = 'PENDING',
STARTING = 'STARTING',
GOING = 'GOING',
SUCCESS = 'SUCCESS',
ERROR = 'ERROR',
}
export enum ItemType {
Folder = 'FOLDER',
File = 'FILE',
}

export type OperationName = 'get_root_items' | 'get_child_items';
export interface OperationResult{
items: Item[];
cursor?: string; // TODO: name??
Expand All @@ -40,6 +40,9 @@ export default class AddonOperationInvocationModel extends Model {

@belongsTo('configured-addon', { inverse: null, polymorphic: true })
thruAddon?: AsyncBelongsTo<ConfiguredAddonModel> | ConfiguredAddonModel;

@belongsTo('authorized-account', { inverse: null, polymorphic: true })
thruAccount?: AsyncBelongsTo<AuthorizedAccountModel> | AuthorizedAccountModel;
}

declare module 'ember-data/types/registries/model' {
Expand Down
16 changes: 8 additions & 8 deletions app/models/authorized-account.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import Model, { attr } from '@ember-data/model';

export interface AddonCredentialFields {
url: string;
username: string;
password: string;
token: string;
accessKey: string;
secretKey: string;
repo: string;
url?: string;
username?: string;
password?: string;
token?: string;
accessKey?: string;
secretKey?: string;
repo?: string;
}

export default class AuthorizedAccountModel extends Model {
@attr('fixstring') displayName!: string;
@attr('fixstringarray') scopes!: string[];
@attr('fixstringarray') authorizedCapabilities!: string[];
@attr('object') credentials?: AddonCredentialFields; // write-only
@attr('boolean') initiateOauth!: boolean; // write-only
@attr('fixstring') readonly authUrl!: string; // Only returned when POSTing to /authorized-xyz-accounts
Expand Down
2 changes: 1 addition & 1 deletion app/models/authorized-citation-account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import UserReferenceModel from './user-reference';

export default class AuthorizedCitationAccountModel extends AuthorizedAccountModel {
@belongsTo('user-reference', { inverse: 'authorizedCitationAccounts' })
configuringUser!: AsyncBelongsTo<UserReferenceModel> & UserReferenceModel;
accountOwner!: AsyncBelongsTo<UserReferenceModel> & UserReferenceModel;

@belongsTo('external-citation-service')
citationService!: AsyncBelongsTo<ExternalCitationServiceModel> & ExternalCitationServiceModel;
Expand Down
2 changes: 1 addition & 1 deletion app/models/authorized-computing-account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import UserReferenceModel from './user-reference';

export default class AuthorizedComputingAccount extends AuthorizedAccountModel {
@belongsTo('user-reference', { inverse: 'authorizedComputingAccounts' })
configuringUser!: AsyncBelongsTo<UserReferenceModel> & UserReferenceModel;
accountOwner!: AsyncBelongsTo<UserReferenceModel> & UserReferenceModel;

@belongsTo('external-computing-service')
computingService!: AsyncBelongsTo<ExternalComputingService> & ExternalComputingService;
Expand Down
4 changes: 2 additions & 2 deletions app/models/authorized-storage-account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ export default class AuthorizedStorageAccountModel extends AuthorizedAccountMode
@attr('fixstring') apiBaseUrl!: string; // Only applicable when ExternalStorageService.configurableApiRoot === true

@belongsTo('user-reference', { inverse: 'authorizedStorageAccounts' })
configuringUser!: AsyncBelongsTo<UserReferenceModel> & UserReferenceModel;
readonly accountOwner!: AsyncBelongsTo<UserReferenceModel> & UserReferenceModel;

@belongsTo('external-storage-service')
storageProvider!: AsyncBelongsTo<ExternalStorageServiceModel> & ExternalStorageServiceModel;
externalStorageService!: AsyncBelongsTo<ExternalStorageServiceModel> & ExternalStorageServiceModel;
}

declare module 'ember-data/types/registries/model' {
Expand Down
1 change: 0 additions & 1 deletion app/models/configured-addon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import ResourceReferenceModel from './resource-reference';
import UserReferenceModel from './user-reference';

export default class ConfiguredAddonModel extends Model {
@attr('string') name!: string;
@attr('string') displayName!: string;
@attr('fixstring') externalUserId!: string;
@attr('fixstring') externalUserDisplayName!: string;
Expand Down
12 changes: 6 additions & 6 deletions app/models/configured-storage-addon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ export enum ConnectedOperationNames {
DownloadAsZip = 'download_as_zip',
CopyInto = 'copy_into',
HasRevisions = 'has_revisions',
GetRootItems = 'get_root_items',
GetChildItems = 'get_child_items',
ListRootItems = 'list_root_items',
ListChildItems = 'list_child_items',
}

export default class ConfiguredStorageAddonModel extends ConfiguredAddonModel {
Expand All @@ -29,7 +29,7 @@ export default class ConfiguredStorageAddonModel extends ConfiguredAddonModel {
@attr('fixstring') rootFolder!: string;

@belongsTo('external-storage-service', { inverse: null })
storageProvider!: AsyncBelongsTo<ExternalStorageServiceModel> & ExternalStorageServiceModel;
externalStorageService!: AsyncBelongsTo<ExternalStorageServiceModel> & ExternalStorageServiceModel;

@belongsTo('authorized-storage-account')
baseAccount!: AsyncBelongsTo<AuthorizedStorageAccountModel> & AuthorizedStorageAccountModel;
Expand All @@ -39,10 +39,10 @@ export default class ConfiguredStorageAddonModel extends ConfiguredAddonModel {
async getFolderItems(this: ConfiguredStorageAddonModel, folderId?: string) {
const newInvocation = this.store.createRecord('addon-operation-invocation', {

operationName: folderId ? ConnectedOperationNames.GetChildItems : ConnectedOperationNames.GetRootItems,
operationName: folderId ? ConnectedOperationNames.ListChildItems : ConnectedOperationNames.ListRootItems,
operationKwargs: {
folderId,
type: ItemType.Folder,
itemId: folderId,
itemType: ItemType.Folder,
},
thruAddon: this,
byUser: await this.accountOwner,
Expand Down
2 changes: 1 addition & 1 deletion app/models/external-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export enum TermsOfServiceCapabilities {
}

export default class ExternalServiceModel extends Model {
@attr('fixstring') name!: string;
@attr('fixstring') displayName!: string;
@attr('string') iconUrl!: string;
@attr('string') credentialsFormat!: CredentialsFormat;
@attr('array') termsOfService!: TermsOfServiceCapabilities[];
Expand Down
10 changes: 6 additions & 4 deletions app/models/user-reference.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import Model, { AsyncHasMany, hasMany } from '@ember-data/model';
import Model, { AsyncHasMany, attr, hasMany } from '@ember-data/model';

import AuthorizedStorageAccountModel from './authorized-storage-account';
import AuthorizedCitationAccount from './authorized-citation-account';
import AuthorizedComputingAccount from './authorized-computing-account';
import ResourceReferenceModel from './resource-reference';

export default class UserReferenceModel extends Model {
@hasMany('authorized-storage-account', { inverse: 'configuringUser' })
@attr('fixstring') userUri!: string;

@hasMany('authorized-storage-account', { inverse: 'accountOwner' })
authorizedStorageAccounts!: AsyncHasMany<AuthorizedStorageAccountModel> & AuthorizedStorageAccountModel[];

@hasMany('authorized-citation-account', { inverse: 'configuringUser' })
@hasMany('authorized-citation-account', { inverse: 'accountOwner' })
authorizedCitationAccounts!: AsyncHasMany<AuthorizedCitationAccount> &
AuthorizedCitationAccount[];

@hasMany('authorized-computing-account', { inverse: 'configuringUser' })
@hasMany('authorized-computing-account', { inverse: 'accountOwner' })
authorizedComputingAccounts!: AsyncHasMany<AuthorizedComputingAccount>
& AuthorizedComputingAccount[];

Expand Down
46 changes: 22 additions & 24 deletions app/packages/addons-service/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ export default class Provider {
provider: AllProviderTypes;
private providerMap?: ProviderTypeMapper;

get name() {
return this.provider.name;
get displayName() {
return this.provider.displayName;
}

get id() {
Expand Down Expand Up @@ -146,37 +146,35 @@ export default class Provider {
@task
@waitFor
async getUserReference() {
const userReference = this.store.peekRecord('user-reference', this.currentUser.user?.id);
if (userReference) {
this.userReference = userReference;
} else {
this.userReference = await this.store.findRecord('user-reference', this.currentUser.user?.id);
}
const { user } = this.currentUser;
const userReferences = await this.store.query('user-reference', {
filter: {user_uri: user?.links.iri?.toString()},
});
this.userReference = userReferences.firstObject;
}


@task
@waitFor
async getResourceReference() {
if (this.node) {
const serviceNode = this.store.peekRecord('resource-reference', this.node.id);
if (serviceNode) {
this.serviceNode = serviceNode;
} else {
this.serviceNode = await this.store.findRecord('resource-reference', this.node.id);
}
const resourceRefs = await this.store.query('resource-reference', {
filter: {resource_uri: this.node.links.iri?.toString()},
});
this.serviceNode = resourceRefs.firstObject;
}
}

getProviderConfiguredAddons() {
this.configuredAddons = this.allConfiguredAddons?.filter(addon => addon.name === this.name);
this.configuredAddons = this.allConfiguredAddons?.filter(addon => addon.displayName === this.displayName);
}

@task
@waitFor
async getAuthorizedStorageAccounts() {
const authorizedStorageAccounts = await this.userReference.authorizedStorageAccounts;
this.authorizedAccounts = authorizedStorageAccounts
.filterBy('storageProvider.id', this.provider.id).toArray();
.filterBy('externalStorageService.id', this.provider.id).toArray();
}

@task
Expand All @@ -198,7 +196,7 @@ export default class Provider {
@task
@waitFor
async getAuthorizedAccounts() {
this.providerMap?.getAuthorizedAccounts.perform();
await this.providerMap?.getAuthorizedAccounts.perform();
}

async userAddonAccounts() {
Expand All @@ -216,9 +214,8 @@ export default class Provider {
initiateOauth: initiateOauth || false,
apiBaseUrl: (this.provider as ExternalStorageServiceModel).configurableApiRoot ? credentials.url : '',
externalUserId: this.currentUser.user?.id,
scopes: [],
storageProvider: this.provider,
configuringUser: this.userReference,
authorizedCapabilities: ['ACCESS', 'UPDATE'],
externalStorageService: this.provider,
displayName: accountName,
});
await newAccount.save();
Expand All @@ -236,7 +233,7 @@ export default class Provider {
externalUserId: this.currentUser.user?.id,
scopes: [],
citationService: this.provider,
configuringUser: this.userReference,
accountOwner: this.userReference,
displayName: accountName,
});
await newAccount.save();
Expand All @@ -254,7 +251,7 @@ export default class Provider {
externalUserId: this.currentUser.user?.id,
scopes: [],
computingService: this.provider,
configuringUser: this.userReference,
accountOwner: this.userReference,
displayName: accountName,
});
await newAccount.save();
Expand Down Expand Up @@ -283,10 +280,11 @@ export default class Provider {
private async createConfiguredStorageAddon(account: AuthorizedStorageAccountModel) {
const configuredStorageAddon = this.store.createRecord('configured-storage-addon', {
rootFolder: '',
storageProvider: this.provider,
externalStorageService: this.provider,
accountOwner: this.userReference,
authorizedResource: this.serviceNode,
authorizedResourceUri: this.node!.links.iri,
baseAccount: account,
connectedCapabilities: ['ACCESS', 'UPDATE'],
});
await configuredStorageAddon.save();
}
Expand Down
12 changes: 6 additions & 6 deletions app/settings/addons/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<LoadingIndicator @dark={{true}} />
{{else}}
{{#if manager.selectedProvider}}
<div data-analytics-scope='{{manager.selectedProvider.name}}'>
<div data-analytics-scope='{{manager.selectedProvider.displayName}}'>
<Button
data-test-cancel-setup
data-analytics-name='Cancel Setup'
Expand All @@ -21,7 +21,7 @@
{{#if (eq manager.pageMode 'terms')}}
<div data-analytics-scope='Terms'>
<h3>
{{t 'addons.terms.heading' providerName=manager.selectedProvider.provider.name}}
{{t 'addons.terms.heading' providerName=manager.selectedProvider.provider.displayName}}
</h3>
<AddonsService::TermsOfService
@provider={{manager.selectedProvider.provider}}
Expand Down Expand Up @@ -112,13 +112,13 @@
<ul local-class='addons-card-wrapper'>
{{#each manager.filteredAddonProviders as |provider|}}
<li
data-test-provider={{provider.name}}
data-test-provider={{provider.displayName}}
local-class='provider-list-item'
>
{{provider.name}}
{{provider.displayName}}
<span>
<Button
data-analytics-name='Connect Addon Button {{provider.name}}'
data-analytics-name='Connect Addon Button {{provider.displayName}}'
@type='create'
{{on 'click' (fn manager.connectNewProviderAccount provider)}}
>
Expand Down Expand Up @@ -170,4 +170,4 @@
{{/if}}
{{/if}}
</AddonsService::UserAddonsManager>
</div>
</div>
2 changes: 1 addition & 1 deletion app/utils/get-href.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ import { Link } from 'jsonapi-typescript';
import { RelatedLink } from 'osf-api';

export default function getHref(link: Link | RelatedLink) {
return typeof link === 'string' ? link : link.href;
return (typeof link === 'string' ? link : link.href).toString();
}
2 changes: 1 addition & 1 deletion config/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ const {
OSF_MFR_URL: mfrUrl = 'http://localhost:4200',
OSF_FILE_URL: waterbutlerUrl = 'http://localhost:7777/',
// TODO: where shold this actually go?
ADDON_SERVICE_URL: addonServiceUrl = 'http://localhost:7979/',
ADDON_SERVICE_URL: addonServiceUrl = 'http://localhost:8004/',
OSF_HELP_URL: helpUrl = 'http://localhost:4200/help',
OSF_AUTHENTICATOR: osfAuthenticator = 'osf-cookie',
PLAUDIT_WIDGET_URL: plauditWidgetUrl = 'https://osf-review.plaudit.pub/embed/endorsements.js',
Expand Down
Loading

0 comments on commit 9fea8b2

Please sign in to comment.