You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ma...@apache.org on 2020/04/14 21:39:24 UTC
[airavata-django-portal] branch develop updated: AIRAVATA-3320:
AIRAVATA-3320 Check user has READ access to all GRP tokens
This is an automated email from the ASF dual-hosted git repository.
machristie pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/airavata-django-portal.git
The following commit(s) were added to refs/heads/develop by this push:
new 675d550 AIRAVATA-3320: AIRAVATA-3320 Check user has READ access to all GRP tokens
new f2b3350 Merge branch 'AIRAVATA-3320-disallow-editing-grp-when-user-doesn-t-have-at-lea' into develop
675d550 is described below
commit 675d550ea97f306bda5273318c32de4923f7e196
Author: Marcus Christie <ma...@apache.org>
AuthorDate: Tue Apr 14 17:37:32 2020 -0400
AIRAVATA-3320: AIRAVATA-3320 Check user has READ access to all GRP tokens
---
.../ComputePreference.vue | 75 ++++++++++++++--------
.../credentials/SSHCredentialSelector.vue | 49 +++++++++++---
.../gatewayprofile/StoragePreferenceEditor.vue | 2 +-
django_airavata/apps/api/serializers.py | 14 +++-
4 files changed, 100 insertions(+), 40 deletions(-)
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/ComputePreference.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/ComputePreference.vue
index 794a552..12f9923 100644
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/ComputePreference.vue
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/admin/group_resource_preferences/ComputePreference.vue
@@ -7,10 +7,9 @@
v-if="localGroupResourceProfile"
class="group-resource-profile-name text-muted text-uppercase"
>
- <i
- class="fa fa-server"
- aria-hidden="true"
- ></i> {{ localGroupResourceProfile.groupResourceProfileName }}</div>
+ <i class="fa fa-server" aria-hidden="true"></i>
+ {{ localGroupResourceProfile.groupResourceProfileName }}
+ </div>
{{ computeResource.hostName }}
</h1>
</div>
@@ -22,7 +21,9 @@
<b-form-group
label="Login Username"
label-for="login-username"
- :invalid-feedback="validationFeedback.loginUserName.invalidFeedback"
+ :invalid-feedback="
+ validationFeedback.loginUserName.invalidFeedback
+ "
:state="validationFeedback.loginUserName.state"
>
<b-form-input
@@ -42,16 +43,26 @@
<ssh-credential-selector
v-model="data.resourceSpecificCredentialStoreToken"
v-if="localGroupResourceProfile"
- :null-option-default-credential-token="localGroupResourceProfile.defaultCredentialStoreToken"
- :null-option-disabled="!localGroupResourceProfile.defaultCredentialStoreToken"
+ :null-option-default-credential-token="
+ localGroupResourceProfile.defaultCredentialStoreToken
+ "
+ :null-option-disabled="
+ !localGroupResourceProfile.defaultCredentialStoreToken
+ "
>
<template
slot="null-option-label"
slot-scope="nullOptionLabelScope"
>
<span v-if="nullOptionLabelScope.defaultCredentialSummary">
- Use the default SSH credential for {{ localGroupResourceProfile.groupResourceProfileName }} ({{
- nullOptionLabelScope.defaultCredentialSummary.description }})
+ Use the default SSH credential for
+ {{ localGroupResourceProfile.groupResourceProfileName }} ({{
+ nullOptionLabelScope.defaultCredentialSummary.username
+ }}
+ -
+ {{
+ nullOptionLabelScope.defaultCredentialSummary.description
+ }})
</span>
<span v-else>
Select a SSH credential
@@ -73,7 +84,9 @@
<b-form-group
label="Scratch Location"
label-for="scratch-location"
- :invalid-feedback="validationFeedback.scratchLocation.invalidFeedback"
+ :invalid-feedback="
+ validationFeedback.scratchLocation.invalidFeedback
+ "
:state="validationFeedback.scratchLocation.state"
>
<b-form-input
@@ -104,15 +117,27 @@
:key="batchQueue.queueName"
>
<b-form-checkbox
- :checked="localComputeResourcePolicy.allowedBatchQueues.includes(batchQueue.queueName)"
+ :checked="
+ localComputeResourcePolicy.allowedBatchQueues.includes(
+ batchQueue.queueName
+ )
+ "
@input="batchQueueChecked(batchQueue, $event)"
>
{{ batchQueue.queueName }}
</b-form-checkbox>
<batch-queue-resource-policy
- v-if="localComputeResourcePolicy.allowedBatchQueues.includes(batchQueue.queueName)"
+ v-if="
+ localComputeResourcePolicy.allowedBatchQueues.includes(
+ batchQueue.queueName
+ )
+ "
:batch-queue="batchQueue"
- :value="localBatchQueueResourcePolicies.find(pol => pol.queuename === batchQueue.queueName)"
+ :value="
+ localBatchQueueResourcePolicies.find(
+ pol => pol.queuename === batchQueue.queueName
+ )
+ "
@input="updatedBatchQueueResourcePolicy(batchQueue, $event)"
@valid="recordValidBatchQueueResourcePolicy(batchQueue)"
@invalid="recordInvalidBatchQueueResourcePolicy(batchQueue)"
@@ -125,21 +150,15 @@
</div>
<div class="row">
<div class="col d-flex justify-content-end">
- <b-button
- variant="primary"
- @click="save"
- :disabled="!valid"
- >Save</b-button>
- <b-button
- class="ml-2"
- variant="danger"
- @click="remove"
- >Delete</b-button>
- <b-button
- class="ml-2"
- variant="secondary"
- @click="cancel"
- >Cancel</b-button>
+ <b-button variant="primary" @click="save" :disabled="!valid"
+ >Save</b-button
+ >
+ <b-button class="ml-2" variant="danger" @click="remove"
+ >Delete</b-button
+ >
+ <b-button class="ml-2" variant="secondary" @click="cancel"
+ >Cancel</b-button
+ >
</div>
</div>
</div>
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/credentials/SSHCredentialSelector.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/credentials/SSHCredentialSelector.vue
index f4b9ca0..2042e23 100644
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/credentials/SSHCredentialSelector.vue
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/credentials/SSHCredentialSelector.vue
@@ -1,11 +1,25 @@
<template>
<div>
<b-input-group>
- <b-form-select v-model="data" :options="credentialStoreTokenOptions" :disabled="readonly">
- <option v-if="nullOption" slot="first" :value="null" :disabled="nullOptionDisabled">
- <slot name="null-option-label" :defaultCredentialSummary="defaultCredentialSummary">
+ <b-form-select
+ v-model="data"
+ :options="credentialStoreTokenOptions"
+ :disabled="readonly"
+ >
+ <option
+ v-if="nullOption"
+ slot="first"
+ :value="null"
+ :disabled="nullOptionDisabled"
+ >
+ <slot
+ name="null-option-label"
+ :defaultCredentialSummary="defaultCredentialSummary"
+ >
<span v-if="defaultCredentialSummary">
- Use the default SSH credential ({{ defaultCredentialSummary.description }})
+ Use the default SSH credential ({{
+ createCredentialDescription(defaultCredentialSummary)
+ }})
</span>
<span v-else>
Unset the default SSH credential
@@ -16,12 +30,19 @@
<b-input-group-append>
<clipboard-copy-button variant="secondary" :text="copySSHPublicKeyText">
</clipboard-copy-button>
- <b-button v-if="!readonly" variant="secondary" @click="showNewSSHCredentialModal">
+ <b-button
+ v-if="!readonly"
+ variant="secondary"
+ @click="showNewSSHCredentialModal"
+ >
<i class="fa fa-plus"></i>
</b-button>
</b-input-group-append>
</b-input-group>
- <new-ssh-credential-modal ref="newSSHCredentialModal" @new="createSSHCredential" />
+ <new-ssh-credential-modal
+ ref="newSSHCredentialModal"
+ @new="createSSHCredential"
+ />
</div>
</template>
@@ -69,7 +90,7 @@ export default {
? this.credentials.map(summary => {
return {
value: summary.token,
- text: summary.description ? summary.description : `No description (${summary.token})`
+ text: this.createCredentialDescription(summary)
};
})
: [];
@@ -94,8 +115,8 @@ export default {
return this.selectedCredential
? this.selectedCredential.publicKey.trim()
: this.defaultCredentialSummary
- ? this.defaultCredentialSummary.publicKey.trim()
- : null;
+ ? this.defaultCredentialSummary.publicKey.trim()
+ : null;
}
},
methods: {
@@ -107,6 +128,15 @@ export default {
this.credentials.push(cred);
this.data = cred.token;
});
+ },
+ createCredentialDescription(summary) {
+ return (
+ summary.username +
+ " - " +
+ (summary.description
+ ? summary.description
+ : `No description (${summary.token})`)
+ );
}
},
created() {
@@ -118,4 +148,3 @@ export default {
}
};
</script>
-
diff --git a/django_airavata/apps/admin/static/django_airavata_admin/src/components/gatewayprofile/StoragePreferenceEditor.vue b/django_airavata/apps/admin/static/django_airavata_admin/src/components/gatewayprofile/StoragePreferenceEditor.vue
index 53edfad..f3a79ae 100644
--- a/django_airavata/apps/admin/static/django_airavata_admin/src/components/gatewayprofile/StoragePreferenceEditor.vue
+++ b/django_airavata/apps/admin/static/django_airavata_admin/src/components/gatewayprofile/StoragePreferenceEditor.vue
@@ -11,7 +11,7 @@
:null-option-default-credential-token="defaultCredentialStoreToken" :null-option-disabled="!defaultCredentialStoreToken">
<template slot="null-option-label" slot-scope="nullOptionLabelScope">
<span v-if="nullOptionLabelScope.defaultCredentialSummary">
- Use the gateway's default SSH credential ({{ nullOptionLabelScope.defaultCredentialSummary.description }})
+ Use the gateway's default SSH credential ({{nullOptionLabelScope.defaultCredentialSummary.username}} - {{ nullOptionLabelScope.defaultCredentialSummary.description }})
</span>
<span v-else>
Select a SSH credential
diff --git a/django_airavata/apps/api/serializers.py b/django_airavata/apps/api/serializers.py
index 58b1470..05af856 100644
--- a/django_airavata/apps/api/serializers.py
+++ b/django_airavata/apps/api/serializers.py
@@ -625,9 +625,21 @@ class GroupResourceProfileSerializer(
def get_userHasWriteAccess(self, groupResourceProfile):
request = self.context['request']
- return request.airavata_client.userHasAccess(
+ write_access = request.airavata_client.userHasAccess(
request.authz_token, groupResourceProfile.groupResourceProfileId,
ResourcePermissionType.WRITE)
+ if not write_access:
+ return False
+ # Check that user has READ access to all tokens in this
+ # GroupResourceProfile
+ tokens = set([groupResourceProfile.defaultCredentialStoreToken] +
+ [cp.resourceSpecificCredentialStoreToken
+ for cp in groupResourceProfile.computePreferences])
+
+ def check_token(token):
+ return token is None or request.airavata_client.userHasAccess(
+ request.authz_token, token, ResourcePermissionType.READ)
+ return all(map(check_token, tokens))
class UserPermissionSerializer(serializers.Serializer):