Skip to content

Commit

Permalink
[Feature] Add app setting to control auth check (#436)
Browse files Browse the repository at this point in the history
Co-authored-by: Ian Seabock (Centific Technologies Inc) <[email protected]>
  • Loading branch information
iseabock and Ian Seabock (Centific Technologies Inc) committed Dec 14, 2023
1 parent e576b31 commit 62b4f97
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 47 deletions.
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,11 @@ Deployment will take several minutes. When it completes, you should be able to n
### Add an identity provider
After deployment, you will need to add an identity provider to provide authentication support in your app. See [this tutorial](https://learn.microsoft.com/en-us/azure/app-service/scenario-secure-app-authentication-app-service) for more information.

If you don't add an identity provider, the chat functionality of your app will be blocked to prevent unauthorized access to your resources and data. To remove this restriction, or add further access controls, update the logic in `getUserInfoList` in `frontend/src/pages/chat/Chat.tsx`. For example, disable the authorization check like so:
```
const getUserInfoList = async () => {
setShowAuthMessage(false);
}
```
If you don't add an identity provider, the chat functionality of your app will be blocked to prevent unauthorized access to your resources and data.

To remove this restriction, you can add `AUTH_ENABLED=False` to the environment variables. This will disable authentication and allow anyone to access the chat functionality of your app. **This is not recommended for production apps.**

To add further access controls, update the logic in `getUserInfoList` in `frontend/src/pages/chat/Chat.tsx`.

## Common Customization Scenarios
Feel free to fork this repository and make your own modifications to the UX or backend logic. For example, you may want to change aspects of the chat display, or expose some of the settings in `app.py` in the UI for users to try out different behaviors.
Expand Down
12 changes: 12 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ def assets(path):
ELASTICSEARCH_STRICTNESS = os.environ.get("ELASTICSEARCH_STRICTNESS", SEARCH_STRICTNESS)
ELASTICSEARCH_EMBEDDING_MODEL_ID = os.environ.get("ELASTICSEARCH_EMBEDDING_MODEL_ID")

# Frontend Settings via Environment Variables
AUTH_ENABLED = os.environ.get("AUTH_ENABLED", "true").lower()
frontend_settings = { "auth_enabled": AUTH_ENABLED }


# Initialize a CosmosDB client with AAD auth and containers for Chat History
cosmos_conversation_client = None
if AZURE_COSMOSDB_DATABASE and AZURE_COSMOSDB_ACCOUNT and AZURE_COSMOSDB_CONVERSATIONS_CONTAINER:
Expand Down Expand Up @@ -829,6 +834,13 @@ def ensure_cosmos():

return jsonify({"message": "CosmosDB is configured and working"}), 200

@app.route("/frontend_settings", methods=["GET"])
def get_frontend_settings():
try:
return jsonify(frontend_settings), 200
except Exception as e:
logging.exception("Exception in /frontend_settings")
return jsonify({"error": str(e)}), 500

def generate_title(conversation_messages):
## make sure the messages are sorted by _ts descending
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,3 +297,15 @@ export const historyEnsure = async (): Promise<CosmosDBHealth> => {
return response;
}

export const frontendSettings = async (): Promise<Response | null> => {
const response = await fetch("/frontend_settings", {
method: "GET",
}).then((res) => {
return res.json()
}).catch((err) => {
console.error("There was an issue fetching your data.");
return null
})

return response
}
4 changes: 4 additions & 0 deletions frontend/src/api/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,8 @@ export enum ChatHistoryLoadingState {
export type ErrorMessage = {
title: string,
subtitle: string
}

export type FrontendSettings = {
auth_enabled?: string | null;
}
9 changes: 7 additions & 2 deletions frontend/src/pages/chat/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const enum messageStatus {

const Chat = () => {
const appStateContext = useContext(AppStateContext)
const AUTH_ENABLED = appStateContext?.state.frontendSettings?.auth_enabled === "true" ;
const chatMessageStreamEnd = useRef<HTMLDivElement | null>(null);
const [isLoading, setIsLoading] = useState<boolean>(false);
const [showLoadingMessage, setShowLoadingMessage] = useState<boolean>(false);
Expand Down Expand Up @@ -93,6 +94,10 @@ const Chat = () => {
}, [appStateContext?.state.chatHistoryLoadingState])

const getUserInfoList = async () => {
if (!AUTH_ENABLED) {
setShowAuthMessage(false);
return;
}
const userInfoList = await getUserInfo();
if (userInfoList.length === 0 && window.location.hostname !== "127.0.0.1") {
setShowAuthMessage(true);
Expand Down Expand Up @@ -525,8 +530,8 @@ const Chat = () => {
}, [processMessages]);

useEffect(() => {
getUserInfoList();
}, []);
if (AUTH_ENABLED !== undefined) getUserInfoList();
}, [AUTH_ENABLED]);

useLayoutEffect(() => {
chatMessageStreamEnd.current?.scrollIntoView({ behavior: "smooth" })
Expand Down
20 changes: 17 additions & 3 deletions frontend/src/state/AppProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { createContext, useReducer, ReactNode, useEffect } from 'react';
import { appStateReducer } from './AppReducer';
import { ChatHistoryLoadingState, CosmosDBHealth, historyList, historyEnsure, CosmosDBStatus } from '../api';
import { Conversation } from '../api';
import { Conversation, ChatHistoryLoadingState, CosmosDBHealth, historyList, historyEnsure, CosmosDBStatus, frontendSettings, FrontendSettings } from '../api';

export interface AppState {
isChatHistoryOpen: boolean;
Expand All @@ -10,6 +9,7 @@ export interface AppState {
chatHistory: Conversation[] | null;
filteredChatHistory: Conversation[] | null;
currentChat: Conversation | null;
frontendSettings: FrontendSettings | null;
}

export type Action =
Expand All @@ -24,6 +24,7 @@ export type Action =
| { type: 'DELETE_CHAT_HISTORY'} // API Call
| { type: 'DELETE_CURRENT_CHAT_MESSAGES', payload: string } // API Call
| { type: 'FETCH_CHAT_HISTORY', payload: Conversation[] | null } // API Call
| { type: 'FETCH_FRONTEND_SETTINGS', payload: FrontendSettings | null } // API Call

const initialState: AppState = {
isChatHistoryOpen: false,
Expand All @@ -34,7 +35,8 @@ const initialState: AppState = {
isCosmosDBAvailable: {
cosmosDB: false,
status: CosmosDBStatus.NotConfigured,
}
},
frontendSettings: null,
};

export const AppStateContext = createContext<{
Expand Down Expand Up @@ -99,6 +101,18 @@ type AppStateProviderProps = {
}
getHistoryEnsure();
}, []);

useEffect(() => {
const getFrontendSettings = async () => {
frontendSettings().then((response) => {
dispatch({ type: 'FETCH_FRONTEND_SETTINGS', payload: response as FrontendSettings });
})
.catch((err) => {
console.error("There was an issue fetching your data.");
})
}
getFrontendSettings();
}, []);

return (
<AppStateContext.Provider value={{ state, dispatch }}>
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/state/AppReducer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ export const appStateReducer = (state: AppState, action: Action): AppState => {
return { ...state, chatHistory: action.payload };
case 'SET_COSMOSDB_STATUS':
return { ...state, isCosmosDBAvailable: action.payload };
case 'FETCH_FRONTEND_SETTINGS':
return { ...state, frontendSettings: action.payload };
default:
return state;
}
Expand Down
68 changes: 34 additions & 34 deletions static/assets/index-88c94d86.js → static/assets/index-d0e2f128.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Azure AI</title>
<script type="module" crossorigin src="/assets/index-88c94d86.js"></script>
<script type="module" crossorigin src="/assets/index-d0e2f128.js"></script>
<link rel="stylesheet" href="/assets/index-ab082006.css">
</head>
<body>
Expand Down

0 comments on commit 62b4f97

Please sign in to comment.