Adding basic endpoints for API keys.

This commit is contained in:
Michael Drury 2022-02-09 23:16:24 +00:00
parent 911f2780ef
commit 45a965b041
7 changed files with 52 additions and 27 deletions

View File

@ -165,4 +165,8 @@
.secondary-action { .secondary-action {
margin-right: auto; margin-right: auto;
} }
.spectrum-Dialog-buttonGroup {
padding-left: 0;
}
</style> </style>

View File

@ -4,7 +4,6 @@
import { onMount } from "svelte" import { onMount } from "svelte"
let apiKey = null let apiKey = null
let loaded = false
async function generateAPIKey() { async function generateAPIKey() {
try { try {
@ -16,21 +15,20 @@
} }
onMount(async () => { onMount(async () => {
apiKey = auth.fetchAPIKey() apiKey = await auth.fetchAPIKey()
}) })
</script> </script>
{#if loaded}
<ModalContent <ModalContent
title="Developer information" title="Developer information"
showSecondaryButton showConfirmButton={false}
showSecondaryButton={true}
secondaryButtonText="Re-generate key" secondaryButtonText="Re-generate key"
secondaryButtonAction={generateAPIKey} secondaryAction={generateAPIKey}
> >
<Body size="S"> <Body size="S">
You can find information about your developer account here, such as the You can find information about your developer account here, such as the API
API key used to access the Budibase API. key used to access the Budibase API.
</Body> </Body>
<Input disabled bind:value={apiKey} label="API key" /> <Input disabled bind:value={apiKey} label="API key" />
</ModalContent> </ModalContent>
{/if}

View File

@ -19,14 +19,12 @@
import { gradient } from "actions" import { gradient } from "actions"
import UpdateUserInfoModal from "components/settings/UpdateUserInfoModal.svelte" import UpdateUserInfoModal from "components/settings/UpdateUserInfoModal.svelte"
import ChangePasswordModal from "components/settings/ChangePasswordModal.svelte" import ChangePasswordModal from "components/settings/ChangePasswordModal.svelte"
import UpdateAPIKeyModal from "components/settings/UpdateAPIKeyModal.svelte"
import { processStringSync } from "@budibase/string-templates" import { processStringSync } from "@budibase/string-templates"
import Logo from "assets/bb-emblem.svg" import Logo from "assets/bb-emblem.svg"
let loaded = false let loaded = false
let userInfoModal let userInfoModal
let changePasswordModal let changePasswordModal
let apiKeyModal
onMount(async () => { onMount(async () => {
try { try {
@ -83,12 +81,6 @@
<MenuItem icon="UserEdit" on:click={() => userInfoModal.show()}> <MenuItem icon="UserEdit" on:click={() => userInfoModal.show()}>
Update user information Update user information
</MenuItem> </MenuItem>
<MenuItem
icon="UserDeveloper"
on:click={() => apiKeyModal.show()}
>
View developer information
</MenuItem>
<MenuItem <MenuItem
icon="LockClosed" icon="LockClosed"
on:click={() => changePasswordModal.show()} on:click={() => changePasswordModal.show()}
@ -163,9 +155,6 @@
<Modal bind:this={changePasswordModal}> <Modal bind:this={changePasswordModal}>
<ChangePasswordModal /> <ChangePasswordModal />
</Modal> </Modal>
<Modal bind:this={apiKeyModal}>
<UpdateAPIKeyModal />
</Modal>
{/if} {/if}
<style> <style>

View File

@ -18,11 +18,13 @@
import { onMount } from "svelte" import { onMount } from "svelte"
import UpdateUserInfoModal from "components/settings/UpdateUserInfoModal.svelte" import UpdateUserInfoModal from "components/settings/UpdateUserInfoModal.svelte"
import ChangePasswordModal from "components/settings/ChangePasswordModal.svelte" import ChangePasswordModal from "components/settings/ChangePasswordModal.svelte"
import UpdateAPIKeyModal from "components/settings/UpdateAPIKeyModal.svelte"
import Logo from "assets/bb-emblem.svg" import Logo from "assets/bb-emblem.svg"
let loaded = false let loaded = false
let userInfoModal let userInfoModal
let changePasswordModal let changePasswordModal
let apiKeyModal
let mobileMenuVisible = false let mobileMenuVisible = false
$: menu = buildMenu($auth.isAdmin) $: menu = buildMenu($auth.isAdmin)
@ -162,6 +164,11 @@
<MenuItem icon="UserEdit" on:click={() => userInfoModal.show()}> <MenuItem icon="UserEdit" on:click={() => userInfoModal.show()}>
Update user information Update user information
</MenuItem> </MenuItem>
{#if $auth.isBuilder}
<MenuItem icon="Key" on:click={() => apiKeyModal.show()}>
View developer information
</MenuItem>
{/if}
<MenuItem <MenuItem
icon="LockClosed" icon="LockClosed"
on:click={() => changePasswordModal.show()} on:click={() => changePasswordModal.show()}
@ -186,6 +193,9 @@
<Modal bind:this={changePasswordModal}> <Modal bind:this={changePasswordModal}>
<ChangePasswordModal /> <ChangePasswordModal />
</Modal> </Modal>
<Modal bind:this={apiKeyModal}>
<UpdateAPIKeyModal />
</Modal>
{/if} {/if}
<style> <style>

View File

@ -280,3 +280,15 @@ exports.inviteAccept = async ctx => {
ctx.throw(400, "Unable to create new user, invitation invalid.") ctx.throw(400, "Unable to create new user, invitation invalid.")
} }
} }
exports.generateAPIKey = async ctx => {
ctx.body = {
apiKey: "a175402a-89fc-11ec-a8a3-0242ac120002",
}
}
exports.fetchAPIKey = async ctx => {
ctx.body = {
apiKey: "a175402a-89fc-11ec-a8a3-0242ac120002",
}
}

View File

@ -4,6 +4,7 @@ const joiValidator = require("../../../middleware/joi-validator")
const adminOnly = require("../../../middleware/adminOnly") const adminOnly = require("../../../middleware/adminOnly")
const Joi = require("joi") const Joi = require("joi")
const cloudRestricted = require("../../../middleware/cloudRestricted") const cloudRestricted = require("../../../middleware/cloudRestricted")
const builderOnly = require("../../../middleware/builderOnly")
const router = Router() const router = Router()
@ -95,6 +96,8 @@ router
buildAdminInitValidation(), buildAdminInitValidation(),
controller.adminUser controller.adminUser
) )
.post("/api/global/users/api/key", builderOnly, controller.generateAPIKey)
.get("/api/global/users/api/key", builderOnly, controller.fetchAPIKey)
.get("/api/global/users/self", controller.getSelf) .get("/api/global/users/self", controller.getSelf)
.get("/api/global/users/tenant/:id", controller.tenantUserLookup) .get("/api/global/users/tenant/:id", controller.tenantUserLookup)
// global endpoint but needs to come at end (blocks other endpoints otherwise) // global endpoint but needs to come at end (blocks other endpoints otherwise)

View File

@ -0,0 +1,9 @@
module.exports = async (ctx, next) => {
if (
!ctx.internal &&
(!ctx.user || !ctx.user.builder || !ctx.user.builder.global)
) {
ctx.throw(403, "Builder user only endpoint.")
}
return next()
}