Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for authentication via x-remote headers #2

Merged
merged 6 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions backend/danswer/auth/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,12 @@ async def create(
) -> models.UP:
verify_email_is_invited(user_create.email)
verify_email_domain(user_create.email)
if hasattr(user_create, "role"):
user_count = await get_user_count()
if user_count == 0 or user_create.email in get_default_admin_user_emails():
user_create.role = UserRole.ADMIN
else:
user_create.role = UserRole.BASIC
# if hasattr(user_create, "role"):
# user_count = await get_user_count()
# if user_count == 0 or user_create.email in get_default_admin_user_emails():
# user_create.role = UserRole.ADMIN
# else:
# user_create.role = UserRole.BASIC
return await super().create(user_create, safe=safe, request=request) # type: ignore

async def oauth_callback(
Expand Down
10 changes: 5 additions & 5 deletions backend/danswer/db/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ async def get_user_count() -> int:
# Need to override this because FastAPI Users doesn't give flexibility for backend field creation logic in OAuth flow
class SQLAlchemyUserAdminDB(SQLAlchemyUserDatabase):
async def create(self, create_dict: Dict[str, Any]) -> UP:
user_count = await get_user_count()
if user_count == 0 or create_dict["email"] in get_default_admin_user_emails():
create_dict["role"] = UserRole.ADMIN
else:
create_dict["role"] = UserRole.BASIC
# user_count = await get_user_count()
# if user_count == 0 or create_dict["email"] in get_default_admin_user_emails():
# create_dict["role"] = UserRole.ADMIN
# else:
# create_dict["role"] = UserRole.BASIC
return await super().create(create_dict)


Expand Down
2 changes: 1 addition & 1 deletion deployment/helm/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ home: https://www.danswer.ai/
sources:
- "https://github.com/danswer-ai/danswer"
type: application
version: 0.1.0-azimuth.1
version: 0.2.0
appVersion: v0.5.10
dependencies:
- name: postgresql
Expand Down
3 changes: 2 additions & 1 deletion deployment/helm/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ appVersionOverride: # e.g "v0.3.93"
# tags to refer to downstream StackHPC-modified images.
# The full image ref will be:
# {{ image-name }}:{{ image-tag or appVersion }}-{{ tagSuffix }}
tagSuffix: stackhpc.1
# tagSuffix: stackhpc.1
tagSuffix: stackhpc.2

zenithClient:
iconUrl: https://raw.githubusercontent.com/danswer-ai/danswer/1fabd9372d66cd54238847197c33f091a724803b/Danswer.png
Expand Down
70 changes: 70 additions & 0 deletions web/src/app/auth/login/HeaderLogin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"use client";

import { usePopup } from "@/components/admin/connectors/Popup";
import { basicLogin, basicSignup } from "@/lib/user";
import { useRouter } from "next/navigation";
import { useEffect } from "react";
import { Spinner } from "@/components/Spinner";
import { v4 as uuidv4 } from 'uuid';

export function HeaderLoginLoading({
user, groups
}: {
user: string;
groups: string[];
}) {
console.log(user, groups);

const router = useRouter();
const { popup, setPopup } = usePopup();
const email = `${user}@default.com`;
const password = `not-used-${uuidv4()}`
const role = groups.includes("/admins") ? "admin" : "basic"

async function tryLogin() {
// TODO: Update user role here if groups have changed?

// TODO: Use other API endpoints here to update user roles
// and check for existence instead of attempting sign up
// Endpoints:
// - /api/manage/users
// - /api/manage/promote-user-to-admin (auth required)
// - /api/manage/demote-admin-to-user (auth required)

// signup every time.
// Ensure user exists
const response = await basicSignup(email, password, role);
if (!response.ok) {
const errorDetail = (await response.json()).detail;

if (errorDetail !== "REGISTER_USER_ALREADY_EXISTS") {
setPopup({
type: "error",
message: `Failed to sign up - ${errorDetail}`,
});
}
}
// Login as user
const loginResponse = await basicLogin(email, password);
if (loginResponse.ok) {
router.push("/");
} else {
const errorDetail = (await loginResponse.json()).detail;
setPopup({
type: "error",
message: `Failed to login - ${errorDetail}`,
});
}
}

useEffect(() => {
tryLogin()
}, []);

return (
<>
{popup}
<Spinner />
</>
);
}
41 changes: 24 additions & 17 deletions web/src/app/auth/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import Link from "next/link";
import { Logo } from "@/components/Logo";
import { LoginText } from "./LoginText";
import { getSecondsUntilExpiration } from "@/lib/time";
import { headers } from 'next/headers';
import { HeaderLoginLoading } from "./HeaderLogin";

const Page = async ({
searchParams,
Expand Down Expand Up @@ -69,6 +71,9 @@ const Page = async ({
return redirect(authUrl);
}

const userHeader = headers().get('x-remote-user');
const groupsHeader = headers().get('x-remote-group');

return (
<main>
<div className="absolute top-10x w-full">
Expand All @@ -90,23 +95,25 @@ const Page = async ({
</>
)}
{authTypeMetadata?.authType === "basic" && (
<Card className="mt-4 w-96">
<div className="flex">
<Title className="mb-2 mx-auto font-bold">
<LoginText />
</Title>
</div>
<EmailPasswordForm />
<div className="flex">
<Text className="mt-4 mx-auto">
Don&apos;t have an account?{" "}
<Link href="/auth/signup" className="text-link font-medium">
Create an account
</Link>
</Text>
</div>
</Card>
)}
(userHeader && groupsHeader) ?
<HeaderLoginLoading user={userHeader} groups={groupsHeader.split(',')} /> : (
<Card className="mt-4 w-96">
<div className="flex">
<Title className="mb-2 mx-auto font-bold">
<LoginText />
</Title>
</div>
<EmailPasswordForm />
<div className="flex">
<Text className="mt-4 mx-auto">
Don&apos;t have an account?{" "}
<Link href="/auth/signup" className="text-link font-medium">
Create an account
</Link>
</Text>
</div>
</Card>
))}
</div>
</div>
</main>
Expand Down
3 changes: 2 additions & 1 deletion web/src/lib/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export const basicLogin = async (
return response;
};

export const basicSignup = async (email: string, password: string) => {
export const basicSignup = async (email: string, password: string, role = "basic") => {
const response = await fetch("/api/auth/register", {
method: "POST",
credentials: "include",
Expand All @@ -53,6 +53,7 @@ export const basicSignup = async (email: string, password: string) => {
email,
username: email,
password,
role,
}),
});
return response;
Expand Down
Loading