mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-10-10 21:26:01 +02:00
Fix users page with API keys + add spinner on key creation
This commit is contained in:
@@ -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:
|
||||||
|
@@ -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,
|
||||||
|
1
backend/ee/danswer/db/constants.py
Normal file
1
backend/ee/danswer/db/constants.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
DANSWER_API_KEY_DUMMY_EMAIL_DOMAIN = "danswerapikey.ai"
|
@@ -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() {
|
||||||
|
Reference in New Issue
Block a user