feat: add create remote source form
This commit is contained in:
parent
53f542601c
commit
64c9a807c7
|
@ -0,0 +1,151 @@
|
||||||
|
<template>
|
||||||
|
<div class="w-6/12">
|
||||||
|
<h1>
|
||||||
|
If you need more advanced options or a little help,
|
||||||
|
<a
|
||||||
|
class="text-blue-600"
|
||||||
|
rel="noopener noreferrer nofollow"
|
||||||
|
href="https://agola.io/tryit/#test-using-a-local-gitea-instance"
|
||||||
|
>
|
||||||
|
take a look at the documentation
|
||||||
|
</a>
|
||||||
|
</h1>
|
||||||
|
<form
|
||||||
|
class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4"
|
||||||
|
@submit.prevent="$emit('createSource', { token, name, type, clientId, clientSecret, url, skipVerify, sshHostKey, skipSshHostKeyCheck })"
|
||||||
|
>
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="block text-sm font-bold mb-2" for="token">Agola Admin token</label>
|
||||||
|
<input
|
||||||
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
|
id="token"
|
||||||
|
type="password"
|
||||||
|
placeholder="Agola Admin token"
|
||||||
|
v-model="token"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="block text-sm font-bold mb-2" for="type">Type</label>
|
||||||
|
<select
|
||||||
|
class="border bg-white rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
|
id="type"
|
||||||
|
v-model="type"
|
||||||
|
>
|
||||||
|
<option value="gitea">Gitea</option>
|
||||||
|
<option value="gitlab">GitLab</option>
|
||||||
|
<option value="github">GitHub</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="block text-sm font-bold mb-2" for="name">Source name</label>
|
||||||
|
<input
|
||||||
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
|
id="name"
|
||||||
|
pattern="^[a-zA-Z][a-zA-Z0-9]*([-]?[a-zA-Z0-9]+)+$"
|
||||||
|
type="text"
|
||||||
|
placeholder="Source name (only numbers, letters and -)"
|
||||||
|
v-model="name"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="block text-sm font-bold mb-2" for="url">Source API URL</label>
|
||||||
|
<input
|
||||||
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
|
id="url"
|
||||||
|
type="text"
|
||||||
|
placeholder="API URL"
|
||||||
|
v-model="url"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="mb-4 flex flex-row">
|
||||||
|
<input
|
||||||
|
id="skip_verify"
|
||||||
|
type="checkbox"
|
||||||
|
class="h-6 w-6 border border-gray-300 rounded-md checked:bg-blue-600 checked:border-transparent focus:outline-none"
|
||||||
|
v-model="skipVerify"
|
||||||
|
>
|
||||||
|
<label class="text-sm mt-auto font-bold mx-2" for="skip_verify">Skip TLS certificate validation</label>
|
||||||
|
</div>
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="block text-sm font-bold mb-2" for="ssh_key">Source Public SSH Key</label>
|
||||||
|
<input
|
||||||
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
|
id="ssh_key"
|
||||||
|
type="text"
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder="Public SSH key"
|
||||||
|
v-model="sshHostKey"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="mb-4 flex flex-row">
|
||||||
|
<input
|
||||||
|
id="skip_ssh_key_check"
|
||||||
|
type="checkbox"
|
||||||
|
class="h-6 w-6 border border-gray-300 rounded-md checked:bg-blue-600 checked:border-transparent focus:outline-none"
|
||||||
|
v-model="skipSshHostKeyCheck"
|
||||||
|
>
|
||||||
|
<label class="text-sm mt-auto font-bold mx-2" for="skip_ssh_key_check">Skip SSH host key check</label>
|
||||||
|
</div>
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="block text-sm font-bold mb-2" for="client_id">Source client ID</label>
|
||||||
|
<input
|
||||||
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
|
id="client_id"
|
||||||
|
type="text"
|
||||||
|
placeholder="Client ID"
|
||||||
|
v-model="clientId"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="block text-sm font-bold mb-2" for="client_secret">Source client secret</label>
|
||||||
|
<input
|
||||||
|
class="appearance-none border rounded w-full py-2 px-3 leading-tight focus:outline-none focus:shadow-outline"
|
||||||
|
id="client_secret"
|
||||||
|
type="password"
|
||||||
|
placeholder="Client secret"
|
||||||
|
v-model="clientSecret"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-center">
|
||||||
|
<button
|
||||||
|
class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
|
||||||
|
type="submit"
|
||||||
|
>Create</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { GITHUB_SSH_KEY, GITHUB_API_URL } from "@/util/data"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "CreateSourceForm",
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
name: null,
|
||||||
|
token: null,
|
||||||
|
url: null,
|
||||||
|
sshHostKey: null,
|
||||||
|
skipVerify: false,
|
||||||
|
skipSshHostKeyCheck: false,
|
||||||
|
type: 'gitea', // default value for select
|
||||||
|
clientId: null,
|
||||||
|
clientSecret: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
type: function(value) {
|
||||||
|
if (value === "github") {
|
||||||
|
this.url = GITHUB_API_URL;
|
||||||
|
this.sshHostKey = GITHUB_SSH_KEY;
|
||||||
|
this.skipVerify = false;
|
||||||
|
this.skipSshHostKeyCheck = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import Oauth2 from "./views/Oauth2.vue";
|
||||||
import Register from "./views/Register.vue";
|
import Register from "./views/Register.vue";
|
||||||
import Login from "./views/Login.vue";
|
import Login from "./views/Login.vue";
|
||||||
import Logout from "./views/Logout.vue";
|
import Logout from "./views/Logout.vue";
|
||||||
|
import CreateSource from "./views/CreateSource.vue";
|
||||||
|
|
||||||
import { parseRef, projectRunLink } from "@/util/link.js";
|
import { parseRef, projectRunLink } from "@/util/link.js";
|
||||||
import { fetchProject } from "@/util/data.js";
|
import { fetchProject } from "@/util/data.js";
|
||||||
|
@ -37,6 +38,11 @@ const router = new VueRouter({
|
||||||
name: "register",
|
name: "register",
|
||||||
component: Register,
|
component: Register,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/newsource",
|
||||||
|
name: "newsource",
|
||||||
|
component: CreateSource,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/login",
|
path: "/login",
|
||||||
name: "login",
|
name: "login",
|
||||||
|
@ -383,4 +389,4 @@ router.beforeEach(async (to, from, next) => {
|
||||||
next()
|
next()
|
||||||
})
|
})
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
|
|
@ -64,7 +64,7 @@ export async function registerapi(init) {
|
||||||
return await window.fetch(registerurl(), init);
|
return await window.fetch(registerurl(), init);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetch(url, init, signal) {
|
export async function fetch(url, init, signal, token, tokenType = "bearer") {
|
||||||
if (!init) {
|
if (!init) {
|
||||||
init = {};
|
init = {};
|
||||||
}
|
}
|
||||||
|
@ -74,9 +74,9 @@ export async function fetch(url, init, signal) {
|
||||||
if (signal) {
|
if (signal) {
|
||||||
init["signal"] = signal;
|
init["signal"] = signal;
|
||||||
}
|
}
|
||||||
let idToken = getIdToken();
|
let idToken = token || getIdToken();
|
||||||
if (idToken) {
|
if (idToken) {
|
||||||
init.headers["Authorization"] = "bearer " + idToken;
|
init.headers["Authorization"] = tokenType + " " + idToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await window.fetch(url, init);
|
return await window.fetch(url, init);
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
import { apiurl, fetch as authfetch, loginapi, registerapi } from "@/util/auth";
|
import { apiurl, fetch as authfetch, loginapi, registerapi } from "@/util/auth";
|
||||||
|
|
||||||
export async function fetch(url, init, signal) {
|
export const GITHUB_API_URL = "https://api.github.com";
|
||||||
|
export const GITHUB_SSH_KEY = "github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==";
|
||||||
|
|
||||||
|
export async function fetch(url, init, signal, token, tokenType) {
|
||||||
try {
|
try {
|
||||||
let res = await authfetch(url, init, signal);
|
let res = await authfetch(url, init, signal, token, tokenType);
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
if (res.status === 401) {
|
if (res.status === 401) {
|
||||||
router.push({
|
router.push({
|
||||||
|
@ -186,6 +189,30 @@ export async function fetchVariables(ownertype, ref, all, signal) {
|
||||||
return await fetch(apiurl(path), null, signal);
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function createRemoteSource(
|
||||||
|
token, type, name, clientID, clientSecret, apiURL, authType, skipVerify,
|
||||||
|
sshHostKey, skipSshHostKeyCheck, registrationEnabled, loginEnabled, signal,
|
||||||
|
) {
|
||||||
|
let path = "/remotesources";
|
||||||
|
let init = {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify({
|
||||||
|
name,
|
||||||
|
apiurl: apiURL,
|
||||||
|
type,
|
||||||
|
auth_type: authType,
|
||||||
|
skip_verify: skipVerify,
|
||||||
|
ssh_host_key: sshHostKey,
|
||||||
|
skip_ssh_host_key_check: skipSshHostKeyCheck,
|
||||||
|
oauth_2_client_id: clientID,
|
||||||
|
oauth_2_client_secret: clientSecret,
|
||||||
|
registration_enabled: registrationEnabled,
|
||||||
|
login_enabled: loginEnabled,
|
||||||
|
})
|
||||||
|
};
|
||||||
|
return await fetch(apiurl(path), init, signal, token, "token");
|
||||||
|
}
|
||||||
|
|
||||||
export async function createOrganization(orgname, visibility, signal) {
|
export async function createOrganization(orgname, visibility, signal) {
|
||||||
let path = "/orgs";
|
let path = "/orgs";
|
||||||
let init = {
|
let init = {
|
||||||
|
@ -390,3 +417,4 @@ export async function deleteProjectGroup(projectgroupref, signal) {
|
||||||
};
|
};
|
||||||
return await fetch(apiurl(path), init, signal);
|
return await fetch(apiurl(path), init, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
v-if="error"
|
||||||
|
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||||
|
role="alert"
|
||||||
|
>
|
||||||
|
<span class="block sm:inline">{{ error }}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div >
|
||||||
|
<div
|
||||||
|
class="flex justify-center items-center w-max"
|
||||||
|
>
|
||||||
|
<CreateSourceForm
|
||||||
|
v-on:createSource="createSource($event)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import CreateSourceForm from "@/components/createsourceform";
|
||||||
|
import { createRemoteSource } from "@/util/data.js";
|
||||||
|
import router from "@/router";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "CreateSource",
|
||||||
|
components: {
|
||||||
|
CreateSourceForm
|
||||||
|
},
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
error: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async createSource({
|
||||||
|
token, name, type, clientId, clientSecret, url, skipVerify, sshHostKey,
|
||||||
|
skipSshHostKeyCheck,
|
||||||
|
}) {
|
||||||
|
const res = await createRemoteSource(
|
||||||
|
token, type, name, clientId, clientSecret, url, "oauth2", skipVerify,
|
||||||
|
sshHostKey, skipSshHostKeyCheck, true, true, undefined,
|
||||||
|
);
|
||||||
|
if (res.error)
|
||||||
|
this.$store.dispatch("setError", res.error);
|
||||||
|
else
|
||||||
|
router.push({name: "login"});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted: function() {
|
||||||
|
this.$store.dispatch("setError", null);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,14 @@
|
||||||
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||||
>
|
>
|
||||||
No remote sources defined
|
No remote sources defined
|
||||||
|
<router-link
|
||||||
|
class="underline text-blue-600 block"
|
||||||
|
to="/newsource"
|
||||||
|
>
|
||||||
|
<button class="btn btn-blue">
|
||||||
|
Create one
|
||||||
|
</button>
|
||||||
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-else-if="!hasLoginRemoteSources"
|
v-else-if="!hasLoginRemoteSources"
|
||||||
|
|
|
@ -28,6 +28,14 @@
|
||||||
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
class="mb-10 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"
|
||||||
>
|
>
|
||||||
No remote sources defined
|
No remote sources defined
|
||||||
|
<router-link
|
||||||
|
class="underline text-blue-600 block"
|
||||||
|
to="/newsource"
|
||||||
|
>
|
||||||
|
<button class="btn btn-blue">
|
||||||
|
Create one
|
||||||
|
</button>
|
||||||
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-else-if="!hasRegisterRemoteSources"
|
v-else-if="!hasRegisterRemoteSources"
|
||||||
|
|
Loading…
Reference in New Issue