usersettings: add new linked account setup

This commit is contained in:
Simone Gotti 2019-05-17 23:45:20 +02:00
parent 4862c6103e
commit 5aa383f23a
6 changed files with 149 additions and 3 deletions

View File

@ -15,7 +15,7 @@
<div class="level-item"> <div class="level-item">
<div> <div>
<span class="name">{{la.remote_user_name}}</span> <span class="name">{{la.remote_user_name}}</span>
<span class="remotesource-name">( {{laRemoteSourceName(la)}} )</span> <span class="remotesource-name">(on remote source {{laRemoteSourceName(la)}})</span>
</div> </div>
</div> </div>
</div> </div>
@ -32,6 +32,19 @@
</ul> </ul>
<div v-else>No linked accounts</div> <div v-else>No linked accounts</div>
</div> </div>
<div v-if="remotesources.length" class="panel-block is-block">
<h5 class="title is-5">Add new linked account</h5>
<div class="field is-grouped">
<div class="control">
<div class="select">
<select v-model="selectedRemoteSourceName">
<option v-for="rs in remotesources" v-bind:key="rs.id">{{ rs.name }}</option>
</select>
</div>
</div>
<button class="button is-primary" @click="addLinkedAccount()">Add Linked Account</button>
</div>
</div>
</nav> </nav>
<nav class="panel"> <nav class="panel">
@ -101,6 +114,8 @@ import {
deleteLinkedAccount deleteLinkedAccount
} from "@/util/data.js"; } from "@/util/data.js";
import { userAddLinkedAccountLink } from "@/util/link.js";
export default { export default {
components: {}, components: {},
name: "usersettings", name: "usersettings",
@ -113,7 +128,8 @@ export default {
user: [], user: [],
remotesources: [], remotesources: [],
token: null, token: null,
newtokenname: null newtokenname: null,
selectedRemoteSourceName: null
}; };
}, },
methods: { methods: {
@ -137,6 +153,9 @@ export default {
return; return;
} }
this.remotesources = data; this.remotesources = data;
if (this.remotesources.length) {
this.selectedRemoteSourceName = this.remotesources[0].name;
}
}, },
laRemoteSourceName(la) { laRemoteSourceName(la) {
for (var i = 0; i < this.remotesources.length; i++) { for (var i = 0; i < this.remotesources.length; i++) {
@ -146,6 +165,13 @@ export default {
} }
} }
}, },
addLinkedAccount() {
let path = userAddLinkedAccountLink(
this.user.username,
this.selectedRemoteSourceName
);
this.$router.push(path);
},
async createUserToken() { async createUserToken() {
this.resetErrors(); this.resetErrors();
@ -203,7 +229,7 @@ export default {
font-weight: bold; font-weight: bold;
} }
.remotesource-name { .remotesource-name {
margin-left: 1rem; margin-left: 0.5rem;
} }
} }
</style> </style>

View File

@ -5,6 +5,7 @@ import User from "./views/User.vue";
import Org from "./views/Org.vue"; import Org from "./views/Org.vue";
import Project from "./views/Project.vue"; import Project from "./views/Project.vue";
import ProjectGroup from "./views/ProjectGroup.vue"; import ProjectGroup from "./views/ProjectGroup.vue";
import AddLinkedAccount from "./views/AddLinkedAccount.vue";
import usersettings from "./components/usersettings.vue"; import usersettings from "./components/usersettings.vue";
import projects from "./components/projects.vue"; import projects from "./components/projects.vue";
import projectsettings from "./components/projectsettings.vue"; import projectsettings from "./components/projectsettings.vue";
@ -101,6 +102,12 @@ const router = new VueRouter({
component: usersettings, component: usersettings,
props: (route) => ({ username: route.params.username }), props: (route) => ({ username: route.params.username }),
}, },
{
path: "linkedaccounts/add/:remotesource",
name: "user add linked account",
component: AddLinkedAccount,
props: (route) => ({ username: route.params.username, remoteSourceName: route.params.remotesource })
},
{ {
path: "createprojectgroup", path: "createprojectgroup",
name: "user create project group", name: "user create project group",

View File

@ -150,6 +150,19 @@ export async function deleteUserToken(username, tokenname) {
return await fetch(apiurl(path), init) return await fetch(apiurl(path), init)
} }
export async function createUserLinkedAccount(username, remotesourcename, loginname, password) {
let path = "/users/" + username + "/linkedaccounts"
let init = {
method: "POST",
body: JSON.stringify({
remote_source_name: remotesourcename,
remote_source_login_name: loginname,
remote_source_login_password: password,
})
}
return await fetch(apiurl(path), init)
}
export async function deleteLinkedAccount(username, laid) { export async function deleteLinkedAccount(username, laid) {
let path = "/users/" + username + "/linkedaccounts/" + laid let path = "/users/" + username + "/linkedaccounts/" + laid
let init = { let init = {

View File

@ -39,6 +39,10 @@ export function userLocalRunTaskLink(username, runid, taskid) {
return { name: "user local run task", params: { username: username, runid: runid, taskid: taskid } } return { name: "user local run task", params: { username: username, runid: runid, taskid: taskid } }
} }
export function userAddLinkedAccountLink(username, remotesourcename) {
return { name: "user add linked account", params: { username: username, remotesource: remotesourcename } }
}
export function orgMembersLink(orgname) { export function orgMembersLink(orgname) {
return { name: "org members", params: { orgname: orgname } } return { name: "org members", params: { orgname: orgname } }
} }

View File

@ -0,0 +1,91 @@
<template>
<div>
<div class="column is-4 is-offset-4">
<div v-if="remotesource">
<LoginForm
v-if="remotesource.auth_type == 'password'"
action="Add Linked Account"
:name="remotesource.name"
v-on:login="doAddLinkedAccount(remotesource.name, $event.username, $event.password)"
/>
<button
v-else
class="button is-info is-fullwidth"
@click="doAddLinkedAccount(remotesource.name)"
>Add Linked Account with {{remotesource.name}}</button>
</div>
<div v-if="addLinkedAccountError" class="message is-danger">
<div class="message-body">{{ addLinkedAccountError }}</div>
</div>
</div>
</div>
</template>
<script>
import LoginForm from "@/components/loginform";
import { fetchRemoteSources, createUserLinkedAccount } from "@/util/data";
export default {
name: "AddLinkedAccount",
props: {
username: String,
remoteSourceName: String
},
components: {
LoginForm
},
data: function() {
return {
addLinkedAccountError: null,
remotesource: null
};
},
methods: {
resetErrors() {
this.addLinkedAccountError = null;
},
async fetchRemoteSources() {
let { data, error } = await fetchRemoteSources();
if (error) {
this.$store.dispatch("setError", error);
return;
}
for (var i = 0; i < data.length; i++) {
let remotesource = data[i];
if (remotesource.name == this.remoteSourceName) {
this.remotesource = remotesource;
break;
}
}
},
async doAddLinkedAccount(rsName, loginname, password) {
let { data, error } = await createUserLinkedAccount(
this.username,
rsName,
loginname,
password
);
if (error) {
this.addLinkedAccountError = error;
return;
}
if (data.oauth2_redirect) {
window.location = data.oauth2_redirect;
return;
}
this.$router.push({
name: "user settings",
params: { username: this.username }
});
}
},
created: function() {
this.fetchRemoteSources();
}
};
</script>

View File

@ -45,6 +45,11 @@ export default {
} else if (data.request_type === "authorize") { } else if (data.request_type === "authorize") {
this.$store.dispatch("setRegisterUser", data.response); this.$store.dispatch("setRegisterUser", data.response);
this.$router.push("/register"); this.$router.push("/register");
} else if (data.request_type === "createuserla") {
this.$router.push({
name: "user settings",
params: { username: this.username }
});
} }
} }
}, },