Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add authentication plugin to embedded components #3298

Merged
merged 5 commits into from
Nov 17, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/core/util/io/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
FileLocation,
LocalPathLocation,
BlobLocation,
isAppRootModel,
isRootModelWithInternetAccounts,
isUriLocation,
AuthNeededError,
UriLocation,
Expand Down Expand Up @@ -109,7 +109,7 @@ function getInternetAccount(
): BaseInternetAccountModel | undefined {
const { rootModel } = pluginManager
// If there is an appRootModel, use it to find the internetAccount
if (rootModel && isAppRootModel(rootModel)) {
if (rootModel && isRootModelWithInternetAccounts(rootModel)) {
return rootModel.findAppropriateInternetAccount(location)
}
// If there is no appRootModel, but there is pre-auth, create a temporary
Expand Down
18 changes: 18 additions & 0 deletions packages/core/util/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,24 @@ export function isAppRootModel(thing: unknown): thing is AppRootModel {
)
}

export interface RootModelWithInternetAccounts extends AbstractRootModel {
internetAccounts: BaseInternetAccountModel[]
findAppropriateInternetAccount(
location: UriLocation,
): BaseInternetAccountModel | undefined
}

export function isRootModelWithInternetAccounts(
thing: unknown,
): thing is RootModelWithInternetAccounts {
return (
typeof thing === 'object' &&
thing !== null &&
'internetAccounts' in thing &&
'findAppropriateInternetAccount' in thing
)
}

/** a root model that manages global menus */
export interface AbstractMenuManager {
appendMenu(menuName: string): void
Expand Down
34 changes: 15 additions & 19 deletions products/jbrowse-desktop/src/rootModel.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import {
addDisposer,
cast,
resolveIdentifier,
getSnapshot,
types,
SnapshotIn,
Instance,
IAnyModelType,
} from 'mobx-state-tree'
import { autorun } from 'mobx'
import makeWorkerInstance from './makeWorkerInstance'
Expand Down Expand Up @@ -129,27 +127,25 @@ export default function rootModelFactory(pluginManager: PluginManager) {
this.setSession(snapshot)
}
},
initializeInternetAccount(id: string, initialSnapshot = {}) {
const schema = pluginManager.pluggableConfigSchemaType(
'internet account',
) as IAnyModelType
const configuration = resolveIdentifier(schema, self, id)

const accountType = pluginManager.getInternetAccountType(
configuration.type,
initializeInternetAccount(
internetAccountConfig: AnyConfigurationModel,
initialSnapshot = {},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason for changing it to take a config instead of id?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the only place this is called, the calling code already has a handle the config. By passing it directly, we avoid having to call resolveIdentifier with the ID.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will note that things like onAction listeners cannot handle full configuration objects, and this is one reason why e.g. showTrack take a trackId even if they have a full conf object to supply generally. Internet account would probably rarely be attached to a onAction listener but it's just a data point for the use of ids in the api

) {
const internetAccountType = pluginManager.getInternetAccountType(
internetAccountConfig.type,
)
if (!accountType) {
throw new Error(`unknown internet account type ${configuration.type}`)
if (!internetAccountType) {
throw new Error(
`unknown internet account type ${internetAccountConfig.type}`,
)
}

const internetAccount = accountType.stateModel.create({
const length = self.internetAccounts.push({
...initialSnapshot,
type: configuration.type,
configuration,
type: internetAccountConfig.type,
configuration: internetAccountConfig,
})

self.internetAccounts.push(internetAccount)
return internetAccount
return self.internetAccounts[length - 1]
},
createEphemeralInternetAccount(
internetAccountId: string,
Expand Down Expand Up @@ -579,7 +575,7 @@ export default function rootModelFactory(pluginManager: PluginManager) {
self,
autorun(() => {
self.jbrowse.internetAccounts.forEach(account => {
self.initializeInternetAccount(account.internetAccountId)
self.initializeInternetAccount(account)
})
}),
)
Expand Down
1 change: 1 addition & 0 deletions products/jbrowse-react-circular-genome-view/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"@emotion/react": "^11.9.0",
"@emotion/styled": "^11.8.1",
"@jbrowse/core": "^2.1.7",
"@jbrowse/plugin-authentication": "^2.1.7",
"@jbrowse/plugin-circular-view": "^2.1.7",
"@jbrowse/plugin-config": "^2.1.7",
"@jbrowse/plugin-data-management": "^2.1.7",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Authentication from '@jbrowse/plugin-authentication'
import Config from '@jbrowse/plugin-config'
import DataManagement from '@jbrowse/plugin-data-management'
import CircularGenomeView from '@jbrowse/plugin-circular-view'
Expand All @@ -6,6 +7,7 @@ import Variants from '@jbrowse/plugin-variants'
import Wiggle from '@jbrowse/plugin-wiggle'

const corePlugins = [
Authentication,
Config,
DataManagement,
CircularGenomeView,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ export default function createConfigModel(
}),
assembly: assemblyConfigSchemasType,
tracks: types.array(pluginManager.pluggableConfigSchemaType('track')),
internetAccounts: types.array(
pluginManager.pluggableConfigSchemaType('internet account'),
),
connections: types.array(
pluginManager.pluggableConfigSchemaType('connection'),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { PluginConstructor } from '@jbrowse/core/Plugin'
import PluginManager from '@jbrowse/core/PluginManager'
import RpcManager from '@jbrowse/core/rpc/RpcManager'
import TextSearchManager from '@jbrowse/core/TextSearch/TextSearchManager'
import { UriLocation } from '@jbrowse/core/util'
import { cast, getSnapshot, Instance, SnapshotIn, types } from 'mobx-state-tree'
import corePlugins from '../corePlugins'
import createConfigModel from './createConfigModel'
Expand All @@ -26,6 +27,9 @@ export default function createModel(runtimePlugins: PluginConstructor[]) {
config: createConfigModel(pluginManager, assemblyConfigSchema),
session: Session,
assemblyManager: assemblyManagerType,
internetAccounts: types.array(
pluginManager.pluggableMstType('internet account', 'stateModel'),
),
})
.volatile(() => ({
error: undefined as Error | undefined,
Expand All @@ -44,6 +48,34 @@ export default function createModel(runtimePlugins: PluginConstructor[]) {
setError(errorMessage: Error | undefined) {
self.error = errorMessage
},
addInternetAccount(
internetAccount: SnapshotIn<typeof self.internetAccounts[0]>,
) {
self.internetAccounts.push(internetAccount)
},
findAppropriateInternetAccount(location: UriLocation) {
// find the existing account selected from menu
const selectedId = location.internetAccountId
if (selectedId) {
const selectedAccount = self.internetAccounts.find(account => {
return account.internetAccountId === selectedId
})
if (selectedAccount) {
return selectedAccount
}
}

// if no existing account or not found, try to find working account
for (const account of self.internetAccounts) {
const handleResult = account.handlesLocation(location)
if (handleResult) {
return account
}
}

// no available internet accounts
return null
},
}))
.views(self => ({
get jbrowse() {
Expand Down
16 changes: 16 additions & 0 deletions products/jbrowse-react-circular-genome-view/src/createViewState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ type SessionSnapshot = SnapshotIn<ReturnType<typeof createSessionModel>>
type ConfigSnapshot = SnapshotIn<ReturnType<typeof createConfigModel>>
type Assembly = ConfigSnapshot['assembly']
type Tracks = ConfigSnapshot['tracks']
type InternetAccounts = ConfigSnapshot['internetAccounts']
type AggregateTextSearchAdapters = ConfigSnapshot['aggregateTextSearchAdapters']

interface ViewStateOptions {
assembly: Assembly
tracks: Tracks
internetAccounts?: InternetAccounts
aggregateTextSearchAdapters?: AggregateTextSearchAdapters
configuration?: Record<string, unknown>
plugins?: PluginConstructor[]
Expand All @@ -26,6 +28,7 @@ export default function createViewState(opts: ViewStateOptions) {
const {
assembly,
tracks,
internetAccounts,
configuration,
aggregateTextSearchAdapters,
plugins,
Expand All @@ -47,13 +50,26 @@ export default function createViewState(opts: ViewStateOptions) {
configuration,
assembly,
tracks,
internetAccounts,
aggregateTextSearchAdapters,
defaultSession,
},
assemblyManager: {},
session: defaultSession,
}
const stateTree = model.create(stateSnapshot, { pluginManager })
stateTree.config.internetAccounts.forEach(account => {
const internetAccountType = pluginManager.getInternetAccountType(
account.type,
)
if (!internetAccountType) {
throw new Error(`unknown internet account type ${account.type}`)
}
stateTree.addInternetAccount({
type: account.type,
configuration: account,
})
})
pluginManager.setRootModel(stateTree)
pluginManager.configure()
autorun(reaction => {
Expand Down
1 change: 1 addition & 0 deletions products/jbrowse-react-linear-genome-view/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"@emotion/styled": "^11.8.1",
"@jbrowse/core": "^2.1.7",
"@jbrowse/plugin-alignments": "^2.1.7",
"@jbrowse/plugin-authentication": "^2.1.7",
"@jbrowse/plugin-bed": "^2.1.7",
"@jbrowse/plugin-circular-view": "^2.1.7",
"@jbrowse/plugin-config": "^2.1.7",
Expand Down
2 changes: 2 additions & 0 deletions products/jbrowse-react-linear-genome-view/src/corePlugins.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Alignments from '@jbrowse/plugin-alignments'
import Authentication from '@jbrowse/plugin-authentication'
import BED from '@jbrowse/plugin-bed'
import Config from '@jbrowse/plugin-config'
import DataManagement from '@jbrowse/plugin-data-management'
Expand All @@ -14,6 +15,7 @@ import Trix from '@jbrowse/plugin-trix'
const corePlugins = [
SVG,
Alignments,
Authentication,
BED,
Config,
DataManagement,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ export default function createConfigModel(
}),
assembly: assemblyConfigSchemasType,
tracks: types.array(pluginManager.pluggableConfigSchemaType('track')),
internetAccounts: types.array(
pluginManager.pluggableConfigSchemaType('internet account'),
),
connections: types.array(
pluginManager.pluggableConfigSchemaType('connection'),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { PluginConstructor } from '@jbrowse/core/Plugin'
import PluginManager from '@jbrowse/core/PluginManager'
import RpcManager from '@jbrowse/core/rpc/RpcManager'
import TextSearchManager from '@jbrowse/core/TextSearch/TextSearchManager'
import { UriLocation } from '@jbrowse/core/util'
import { cast, getSnapshot, Instance, SnapshotIn, types } from 'mobx-state-tree'
import corePlugins from '../corePlugins'
import createConfigModel from './createConfigModel'
Expand All @@ -29,6 +30,9 @@ export default function createModel(
session: Session,
assemblyManager: types.optional(AssemblyManager, {}),
disableAddTracks: types.optional(types.boolean, false),
internetAccounts: types.array(
pluginManager.pluggableMstType('internet account', 'stateModel'),
),
})
.volatile(self => ({
error: undefined as Error | undefined,
Expand All @@ -55,6 +59,34 @@ export default function createModel(
setError(errorMessage: Error | undefined) {
self.error = errorMessage
},
addInternetAccount(
internetAccount: SnapshotIn<typeof self.internetAccounts[0]>,
) {
self.internetAccounts.push(internetAccount)
},
findAppropriateInternetAccount(location: UriLocation) {
// find the existing account selected from menu
const selectedId = location.internetAccountId
if (selectedId) {
const selectedAccount = self.internetAccounts.find(account => {
return account.internetAccountId === selectedId
})
if (selectedAccount) {
return selectedAccount
}
}

// if no existing account or not found, try to find working account
for (const account of self.internetAccounts) {
const handleResult = account.handlesLocation(location)
if (handleResult) {
return account
}
}

// no available internet accounts
return null
},
}))

.views(self => ({
Expand Down
16 changes: 16 additions & 0 deletions products/jbrowse-react-linear-genome-view/src/createViewState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type SessionSnapshot = SnapshotIn<ReturnType<typeof createSessionModel>>
type ConfigSnapshot = SnapshotIn<ReturnType<typeof createConfigModel>>
type Assembly = ConfigSnapshot['assembly']
type Tracks = ConfigSnapshot['tracks']
type InternetAccounts = ConfigSnapshot['internetAccounts']
type AggregateTextSearchAdapters = ConfigSnapshot['aggregateTextSearchAdapters']

interface Location {
Expand All @@ -22,6 +23,7 @@ interface Location {
interface ViewStateOptions {
assembly: Assembly
tracks: Tracks
internetAccounts?: InternetAccounts
aggregateTextSearchAdapters?: AggregateTextSearchAdapters
configuration?: Record<string, unknown>
plugins?: PluginConstructor[]
Expand All @@ -36,6 +38,7 @@ export default function createViewState(opts: ViewStateOptions) {
const {
assembly,
tracks,
internetAccounts,
configuration,
aggregateTextSearchAdapters,
plugins,
Expand Down Expand Up @@ -64,13 +67,26 @@ export default function createViewState(opts: ViewStateOptions) {
configuration,
assembly,
tracks,
internetAccounts,
aggregateTextSearchAdapters,
},
disableAddTracks,
session: defaultSession,
},
{ pluginManager },
)
stateTree.config.internetAccounts.forEach(account => {
const internetAccountType = pluginManager.getInternetAccountType(
account.type,
)
if (!internetAccountType) {
throw new Error(`unknown internet account type ${account.type}`)
}
stateTree.addInternetAccount({
type: account.type,
configuration: account,
})
})
pluginManager.setRootModel(stateTree)
pluginManager.configure()
if (location) {
Expand Down
Loading