Skip to content

Commit

Permalink
πŸ”€ : merge pull request #477 from gaia-app/local-users
Browse files Browse the repository at this point in the history
✨ : local users mgmt
  • Loading branch information
cdubuisson authored Dec 30, 2020
2 parents 7844b6e + 0137d6e commit 02cbf3e
Show file tree
Hide file tree
Showing 29 changed files with 939 additions and 97 deletions.
6 changes: 0 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -208,13 +208,7 @@
</dependencies>

<dependencyManagement>
<!-- we need this as selenium needs guava 25, and docker-client embeds guava 20 -->
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>29.0-jre</version>
</dependency>
<dependency>
<groupId>org.springframework.vault</groupId>
<artifactId>spring-vault-dependencies</artifactId>
Expand Down
89 changes: 89 additions & 0 deletions src/main/client/app/pages/users/organizations.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<template>
<div>
<b-modal
id="new-organization-modal"
title="New Organization"
ok-title="Create"
auto-focus-button="ok"
@ok="createOrg"
@cancel="newOrganizationName = ''"
@close="newOrganizationName = ''"
>
<b-input
v-model="newOrganizationName"
autofocus
/>
</b-modal>

<b-button
v-b-modal.new-organization-modal
variant="primary"
>
<font-awesome-icon
icon="plus"
class="icon"
/>
Create new organization
</b-button>

<div class="block mt-3">
<b-table
:items="teams"
:fields="fields"
striped
fixed
outlined
>
<template v-slot:cell(edit)="row">
<b-button
variant="outline-danger"
class="ml-1"
@click="deleteOrg(row.item)"
>
<font-awesome-icon
:icon="['far', 'trash-alt']"
class="icon"
/>
</b-button>
</template>
</b-table>
</div>
</div>
</template>

<script>
import { createOrganization, deleteOrganization, getTeams } from '@/shared/api/teams-api';
import { displayNotification } from '@/shared/services/modal-service';
export default {
name: 'AppOrganizations',
data: () => ({
teams: [],
newOrganizationName: '',
fields: [
{ key: 'id', label: 'Name', sortable: true },
{ key: 'edit' },
],
}),
async created() {
await this.refresh();
},
methods: {
async refresh() {
this.teams = await getTeams();
},
async createOrg() {
await createOrganization({ id: this.newOrganizationName })
.then(() => displayNotification(this, { message: 'Organization created', variant: 'success' }))
.then(this.refresh)
.catch(({ error, message }) => displayNotification(this, { title: error, message, variant: 'danger' }));
},
async deleteOrg(organization) {
await deleteOrganization(organization.id)
.then(() => displayNotification(this, { message: 'Organization deleted', variant: 'success' }))
.then(this.refresh)
.catch(({ error, message }) => displayNotification(this, { title: error, message, variant: 'danger' }));
},
},
};
</script>
188 changes: 188 additions & 0 deletions src/main/client/app/pages/users/user-edit.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
<template>
<div>
<div class="block">
<div class="block_head">
<h2>User {{ user.username }}</h2>
</div>

<div class="block_content">
<b-form>
<b-form-group
v-if="user.new"
label="Username"
description="The username"
>
<b-form-input v-model="user.username" />
</b-form-group>

<b-form-group
label="Team"
description="The user team"
>
<vue-multiselect
v-model="user.team"
:options="teams"
track-by="id"
label="id"
:multiple="false"
placeholder="Select user team"
:show-labels="false"
/>
</b-form-group>
<b-form-group
label="Administrator"
:description="user.admin === true ? 'The user is an administrator' : 'The user is not an administrator'"
>
<b-form-checkbox
v-model="user.admin"
type="password"
switch
size="lg"
/>
</b-form-group>
</b-form>
</div>

<div class="block_content">
<b-button
variant="primary"
@click="saveUser"
>
<font-awesome-icon
icon="save"
class="icon"
/>
Save User
</b-button>

<b-button
v-if="! user.new"
variant="danger"
class="ml-3"
@click="deleteUser"
>
<font-awesome-icon
icon="user-minus"
class="icon"
/>
Delete User
</b-button>
</div>
</div>
<div class="block mt-2">
<div class="block_head">
<h2>Change user password</h2>
</div>

<div class="block_content">
<b-form v-if="! user.oauth2User">
<b-form-row
v-if="! user.oauth2User"
>
<b-form-group
label="Password"
description="Change the user password"
class="mr-2"
>
<b-form-input
v-model="user.password"
type="password"
:state="user.password && user.password === user.passwordConfirmation"
/>
</b-form-group>
<b-form-group
label="Confirm password"
description="Confirm the user password"
>
<b-form-input
v-model="user.passwordConfirmation"
type="password"
:state="user.password && user.password === user.passwordConfirmation"
/>
</b-form-group>
</b-form-row>
</b-form>

<b-alert
v-else
show
>
This user is an OAuth2 User. Its password cannot be changed.
</b-alert>
</div>

<div
v-if="! user.oauth2User"
class="block_content"
>
<b-button
variant="primary"
@click="changePassword"
>
<font-awesome-icon
icon="save"
class="icon"
/>
Change user password
</b-button>
</div>
</div>
</div>
</template>

<script>
import { getTeams } from '@/shared/api/teams-api';
import { changeUserPassword, deleteUser, updateUser } from '@/shared/api/users-api';
import { displayNotification } from '@/shared/services/modal-service';
export default {
name: 'AppUserEdition',
props: {
user: {
type: Object,
default: () => ({
new: true,
}),
},
username: {
type: String,
required: true,
},
},
data: () => ({
teams: [],
}),
async created() {
this.teams = await getTeams();
},
methods: {
async redirectToUsersPage() {
await this.$router.push({ name: 'users' });
},
async saveUser() {
await updateUser(this.user)
.then(() => displayNotification(this, { message: 'User updated', variant: 'success' }))
.then(this.redirectToUsersPage)
.catch(({ error, message }) => displayNotification(this, { title: error, message, variant: 'danger' }));
},
async changePassword() {
await changeUserPassword(this.username, this.user.password)
.then(() => displayNotification(this, { message: 'Password changed', variant: 'success' }))
.catch(({ error, message }) => displayNotification(this, { title: error, message, variant: 'danger' }));
},
async deleteUser() {
await deleteUser(this.username)
.then(() => displayNotification(this, { message: 'User deleted', variant: 'success' }))
.then(this.redirectToUsersPage)
.catch(({ error, message }) => displayNotification(this, { title: error, message, variant: 'danger' }));
},
},
};
</script>

<style scoped>
/deep/ .user-row td:first-child {
font-size: 16px;
vertical-align: middle;
}
</style>
41 changes: 41 additions & 0 deletions src/main/client/app/pages/users/user-name.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<template>
<span>
{{ user.username }}

<b-badge
v-if="user.admin"
variant="primary"
class="mr-1"
>
<font-awesome-icon icon="user-shield" /> Administrator
</b-badge>

<b-badge
v-if="user.oauth2User != null && user.oauth2User.provider === 'github'"
variant="dark"
>
<font-awesome-icon :icon="['fab','github']" /> Github login
</b-badge>

<b-badge
v-if="user.oauth2User != null && user.oauth2User.provider === 'gitlab'"
variant="warning"
>
<font-awesome-icon :icon="['fab','gitlab']" /> Gitlab login
</b-badge>

</span>
</template>

<script>
export default {
name: 'AppUserName',
props: {
user: {
type: Object,
required: true,
},
},
};
</script>
Loading

0 comments on commit 02cbf3e

Please sign in to comment.