Fix users page with API keys + add spinner on key creation

This commit is contained in:
Weves
2024-01-17 03:04:39 -08:00
committed by Chris Weaver
parent db338bfddf
commit 8bf483904d
4 changed files with 23 additions and 5 deletions

View File

@@ -34,10 +34,10 @@ from danswer.server.models import FullUserSnapshot
from danswer.server.models import InvitedUserSnapshot from danswer.server.models import InvitedUserSnapshot
from danswer.server.models import MinimalUserSnapshot from danswer.server.models import MinimalUserSnapshot
from danswer.utils.logger import setup_logger from danswer.utils.logger import setup_logger
from ee.danswer.db.api_key import is_api_key_email_address
logger = setup_logger() logger = setup_logger()
router = APIRouter() router = APIRouter()
@@ -91,7 +91,11 @@ def list_all_users(
_: User | None = Depends(current_admin_user), _: User | None = Depends(current_admin_user),
db_session: Session = Depends(get_session), db_session: Session = Depends(get_session),
) -> AllUsersResponse: ) -> AllUsersResponse:
users = list_users(db_session, q=q) users = [
user
for user in list_users(db_session, q=q)
if not is_api_key_email_address(user.email)
]
accepted_emails = {user.email for user in users} accepted_emails = {user.email for user in users}
invited_emails = get_invited_users() invited_emails = get_invited_users()
if q: if q:

View File

@@ -11,10 +11,17 @@ from ee.danswer.auth.api_key import ApiKeyDescriptor
from ee.danswer.auth.api_key import build_displayable_api_key from ee.danswer.auth.api_key import build_displayable_api_key
from ee.danswer.auth.api_key import generate_api_key from ee.danswer.auth.api_key import generate_api_key
from ee.danswer.auth.api_key import hash_api_key from ee.danswer.auth.api_key import hash_api_key
from ee.danswer.db.constants import DANSWER_API_KEY_DUMMY_EMAIL_DOMAIN
_DANSWER_API_KEY = "danswer_api_key" _DANSWER_API_KEY = "danswer_api_key"
def is_api_key_email_address(email: str) -> bool:
return email.endswith(
f"@{DANSWER_API_KEY_DUMMY_EMAIL_DOMAIN}"
) and email.startswith(_DANSWER_API_KEY)
def fetch_api_keys(db_session: Session) -> list[ApiKeyDescriptor]: def fetch_api_keys(db_session: Session) -> list[ApiKeyDescriptor]:
api_keys = db_session.scalars(select(ApiKey)).all() api_keys = db_session.scalars(select(ApiKey)).all()
return [ return [
@@ -44,7 +51,7 @@ def insert_api_key(db_session: Session, user_id: uuid.UUID | None) -> ApiKeyDesc
api_key_user_row = User( api_key_user_row = User(
id=api_key_user_id, id=api_key_user_id,
email=f"{_DANSWER_API_KEY}__{api_key_user_id}", email=f"{_DANSWER_API_KEY}__{api_key_user_id}@{DANSWER_API_KEY_DUMMY_EMAIL_DOMAIN}",
# a random password for the "user" # a random password for the "user"
hashed_password=std_password_helper.hash(std_password_helper.generate()), hashed_password=std_password_helper.hash(std_password_helper.generate()),
is_active=True, is_active=True,

View File

@@ -0,0 +1 @@
DANSWER_API_KEY_DUMMY_EMAIL_DOMAIN = "danswerapikey.ai"

View File

@@ -23,6 +23,7 @@ import { Table } from "@tremor/react";
import { DeleteButton } from "@/components/DeleteButton"; import { DeleteButton } from "@/components/DeleteButton";
import { FiCopy, FiRefreshCw, FiX } from "react-icons/fi"; import { FiCopy, FiRefreshCw, FiX } from "react-icons/fi";
import { Modal } from "@/components/Modal"; import { Modal } from "@/components/Modal";
import { Spinner } from "@/components/Spinner";
interface APIKey { interface APIKey {
api_key_id: number; api_key_id: number;
@@ -95,6 +96,7 @@ function Main() {
} = useSWR<APIKey[]>("/api/admin/api-key", errorHandlingFetcher); } = useSWR<APIKey[]>("/api/admin/api-key", errorHandlingFetcher);
const [fullApiKey, setFullApiKey] = useState<string | null>(null); const [fullApiKey, setFullApiKey] = useState<string | null>(null);
const [keyIsGenerating, setKeyIsGenerating] = useState(false);
if (isLoading) { if (isLoading) {
return <ThreeDotsLoader />; return <ThreeDotsLoader />;
@@ -115,9 +117,11 @@ function Main() {
size="xs" size="xs"
className="mt-3" className="mt-3"
onClick={async () => { onClick={async () => {
setKeyIsGenerating(true);
const response = await fetch("/api/admin/api-key", { const response = await fetch("/api/admin/api-key", {
method: "POST", method: "POST",
}); });
setKeyIsGenerating(false);
if (!response.ok) { if (!response.ok) {
const errorMsg = await response.text(); const errorMsg = await response.text();
setPopup({ setPopup({
@@ -154,6 +158,8 @@ function Main() {
/> />
)} )}
{keyIsGenerating && <Spinner />}
<Text>{API_KEY_TEXT}</Text> <Text>{API_KEY_TEXT}</Text>
{newApiKeyButton} {newApiKeyButton}
@@ -187,12 +193,14 @@ function Main() {
border-border border-border
text-sm`} text-sm`}
onClick={async () => { onClick={async () => {
setKeyIsGenerating(true);
const response = await fetch( const response = await fetch(
`/api/admin/api-key/${apiKey.api_key_id}`, `/api/admin/api-key/${apiKey.api_key_id}`,
{ {
method: "PATCH", method: "PATCH",
} }
); );
setKeyIsGenerating(false);
if (!response.ok) { if (!response.ok) {
const errorMsg = await response.text(); const errorMsg = await response.text();
setPopup({ setPopup({
@@ -237,8 +245,6 @@ function Main() {
</Table> </Table>
</div> </div>
); );
return <div>{fullApiKey}</div>;
} }
export default function Page() { export default function Page() {