-
Notifications
You must be signed in to change notification settings - Fork 12
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
Feature/refresh #273
Feature/refresh #273
Conversation
src/server/auth/arboristClient.js
Outdated
Object.keys(result).forEach((key) => { | ||
// logic: you have access to a project if you have the following access: | ||
// method 'create' (or '*' - all methods) to service 'guppy' (or '*' - all services) | ||
// on the project resource. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is too broad, and it sort of binds the two roles of data submitter and Guppy admin togather. The restarting of Guppy should be an "admin-level" feature. I think we'd better to have a dedicated "guppy_admin" policy for this feature, which could be service == guppy, method == *
, or service == guppy, method == admin_access
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see 713fc1f
src/server/auth/arboristClient.js
Outdated
@@ -65,6 +65,64 @@ class ArboristClient { | |||
}, | |||
); | |||
} | |||
|
|||
listAuthorizedCreateResources(jwt) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of this function is duplicating listAuthorizedResources(jwt)
, except for the part that check's the user for certain service + methods.
We don't need to duplicate those codes, we should be extracting the part of making request to arborist and checking for user's access in the returned auth mapping into two separated functions, and just reuse them. In this way, we can avoid sending duplicated requests to arborist
See how the fetch for user's auth mapping and check for user's access can be separated in another service
https://github.com/uc-cdis/data-portal/blob/master/src/actions.js#L513
https://github.com/uc-cdis/data-portal/blob/master/src/authMappingUtils.js#L53
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok getAuthMapping function has been created and used twice, once for the reader permissions checking, and again for the guppy admin permissions checking. See 713fc1f
src/server/auth/utils.js
Outdated
throw new CodedError(data.error.code, data.error.message); | ||
} | ||
const resources = data.resources ? _.uniq(data.resources) : []; | ||
return resources; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to execute all those expensive array manipulations for this feature, if your goal is to determine whether am user is Guppy admin or not. This function can simply returns a boolean based on the return value from listAuthorizedCreateResources()
Of couse variable and function names should be updated to relflect this change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok boolean is returned now when checking for refresh permissions
src/server/server.js
Outdated
} | ||
await server.stop() | ||
await initializeAndStartServer(); | ||
} else if (config.allowRefresh === false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this check should happens first, before checking for user's token
src/server/server.js
Outdated
throw noPermsUser; | ||
} | ||
await server.stop() | ||
await initializeAndStartServer(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This solution is generally ok, but it only works if there is only 1 guppy pod/container/server in the system.
In the cases of how Gen3 is usually deployed, which is on a k8s cluster with a load balancer / reverse proxy in front of pods, and also if there are replicas of guppy pods. This solution will only triggers 1 guppy pod to restart each time, which will causes a discrepancy in the states of pods
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mfshao thanks for all the feedback. In the case of replica guppy pods, is there a link you could provide for how requests from the clients are distributed to the guppy replicas? In other words, is there a nginx or helm configuration that fans out the requests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mfshao Alternatively, as a brainstorm: guppy could checking mappings on a configurable interval and initiate a restart if the version changed. For example, for index gen3.aced.io_file_0
$ curl localhost:9200/gen3.aced.io_file_0 | jq '.["gen3.aced.io_file_0"].settings.index.version.created '
>>> "7170399"
On startup, guppy could cache this value for each index, and then monitor the index for changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This branch need a rebase with the current master
src/server/auth/utils.js
Outdated
], | ||
}; | ||
} else { | ||
data = await arboristClient.listAuthMapping(jwt); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this canRefresh()
will only be called within initialize()
, you don't have to make another call to arborist to get user's ath mapping again because you have already done it in getAccessibleResourcesFromArboristasync()
consider to put the auth mapping in a vairable and use it here instead of making another call
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has been implemented in recent commits
src/server/auth/utils.js
Outdated
const resources = data.resources ? _.uniq(data.resources) : []; | ||
return resources; | ||
}; | ||
|
||
export const canRefresh = async (jwt) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
export const canRefresh = async (jwt) => { | |
export const checkIfUserCanRefreshServer = async (jwt) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
canRefresh => checkIfUserCanRefreshServer has been implemented
src/server/server.js
Outdated
const disabledRefresh = new CodedError(404, '[Refresh] guppy _refresh functionality is not enabled'); | ||
throw disabledRefresh; | ||
} | ||
else if (config.allowRefresh) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this can be just an else
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
implemented
* chore(deps): bump braces from 3.0.2 to 3.0.3 Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3. - [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md) - [Commits](micromatch/braces@3.0.2...3.0.3) --- updated-dependencies: - dependency-name: braces dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> * trigger gh action * trigger travis --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Mingfei Shao <mshao1@uchicago.edu>
Bumps [ws](https://github.com/websockets/ws) from 6.2.2 to 6.2.3. - [Release notes](https://github.com/websockets/ws/releases) - [Commits](websockets/ws@6.2.2...6.2.3) --- updated-dependencies: - dependency-name: ws dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Mingfei Shao <2475897+mfshao@users.noreply.github.com>
* fix apply hide number resolver to as text agg results * update dockerfile
Param order was wrong on changed line, put err first. Refer to: https://expressjs.com/en/guide/error-handling.html
…dis#280) The following vulnerabilities are fixed with an upgrade: - https://snyk.io/vuln/SNYK-JS-SEND-7926862 Co-authored-by: snyk-bot <snyk-bot@snyk.io>
…e to use newer dependencies (uc-cdis#285) * PPS-1564 PPS-1567 PPS-1585: update body-parser and package lock file to use newer dependencies * PPS-1564 PPS-1567 PPS-1585: add file so nvm can set node version
Fix a dead link
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we are getting close to it, still a few small issues to fix, and we will run our CI over this to make sure there is no regression
I think after fixing these issues and passing CI we could approve
src/server/server.js
Outdated
} | ||
}, | ||
); | ||
// eslint-disable-next-line no-unused-vars |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you don't need this for the next line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
}); | ||
}; | ||
// download endpoint for fetching data directly from es | ||
app.post('/download', downloadRouter, (err, req, res, next) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
put // eslint-disable-next-line no-unused-vars
above this to satisfy the linter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
src/server/server.js
Outdated
}; | ||
// download endpoint for fetching data directly from es | ||
app.post('/download', downloadRouter, (err, req, res, next) => { | ||
// eslint-disable-line no-unused-vars |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you don't need this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
} | ||
}); | ||
|
||
app.post('/_refresh', refreshRouter, (err, req, res, next) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
put // eslint-disable-next-line no-unused-vars
above this to satisfy the linter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
src/server/server.js
Outdated
const app = express(); | ||
app.use(cors()); | ||
app.use(helmet()); | ||
app.use(bodyParser.json({ limit: '50mb' })); | ||
|
||
const refreshRouter = async (req, res, next) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refreshRouter
should be placed after initializeAndStartServer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
src/server/config.js
Outdated
} | ||
|
||
const config = { | ||
allowRefresh: inputConfig.allowRefresh || false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
allowRefresh
is duplicated in this config
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
|
||
export const checkIfUserCanRefreshServer = async (data) => { | ||
if (config.internalLocalTest) { | ||
data = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider fix the failed es-lint check here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CI is passing in this PR #292
code-wsie lgtm
This statement in the PR description and release notes is not accurate |
yeah you are right, I can update the PR description, and release note |
Link to JIRA ticket if there is one:
New Features
_refresh
. Guppy must be configured to accept this request via theallowRefresh
variable in the guppy config. If this variable is not set, the feature is not available.admin_access
or*
method permissions for serviceguppy
on resource path/guppy_admin
are able to make the _refresh request.Breaking Changes
None
Bug Fixes
None
Improvements
None
Dependency updates
None
Deployment changes
"allowRefresh": {{ .Values.allowRefresh }}
togen3-helm/helm/guppy/templates/guppy_config.yaml
and then in your values.yaml file, specify allowRefresh as the boolean true value.