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

[Identity] Manual test fix #12858

Merged
merged 4 commits into from
Dec 17, 2020
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
19 changes: 16 additions & 3 deletions sdk/identity/identity/test/manual/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,22 @@ Webpack will compile the code and then host it in a local server at
`http://localhost:8080`. See the section below about CORS before attempting to
navigate to this URL.

You will need an AAD App Registration that has its redirect uri set to
`http://localhost:8080`. Its tenant ID and client (application) ID will need to
be entered into the UI to initiate the authentication process.
You will need to configure an AAD App Registration as follows:

- Create a new AAD App Registration.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made a new issue to change this to make use of the CLI: #12961

- Once created, go to the AAD section of the Azure portal.
- Go to the App Registration section in the AAD page.
- Click on the app that you want to use to authenticate.
- Go to the Authentication tab of your AAD application.
- Click on `+ Add a platform`, select `Single-page application`, enter `http://localhost:8080` as the redirect URI, then make sure to include implicit grant for "Access tokens" and "ID tokens".
- Keep in mind that if you belong to an organization, other restrictions based on the organization configurations might prevent you from authenticating. If These steps don't end up being effective, try again on a personal account.

Grant access to this AAD application to your Key Vault by:

- Creating a Key Vault (if you haven't created one).
- Either in the "Access policies" section of the creation form, or by going to your Key Vault's "Access policies" page, click con `+ Add Access Policy`, select all permissions, then select your AAD application as the "principal", then click "Add", then click "Save" if applicable.

With the AAD application and the Key Vault configured, make sure `npm start` is running, then go to `http://localhost:8080`, then enter the Tenant ID, the Client ID of the AAD application and the name of the Key Vault, then click on the `Get Keys` button, and a list of the available keys will be presented after the form in the web page.

## Avoiding CORS errors

Expand Down
4 changes: 2 additions & 2 deletions sdk/identity/identity/test/manual/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
"author": "Microsoft Corporation",
"license": "MIT",
"dependencies": {
"@azure/identity": "../..",
"@azure/keyvault-keys": "../../../../keyvault/keyvault-keys",
"@azure/identity": "1.2.0",
"@azure/keyvault-keys": "4.1.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"tslib": "^1.9.3"
Expand Down
85 changes: 53 additions & 32 deletions sdk/identity/identity/test/manual/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ import * as React from "react";
import * as ReactDOM from "react-dom";

import { InteractiveBrowserCredential, BrowserLoginStyle } from "@azure/identity";
import { KeyClient, Key } from "@azure/keyvault-keys";
import { KeyClient, KeyVaultKey } from "@azure/keyvault-keys";

const getRandomKeyName = () => `key${Math.random()}`.replace(/\./g, "");

interface ClientDetails {
tenantId: string,
clientId: string,
loginStyle: BrowserLoginStyle
loginStyle: BrowserLoginStyle,
keyName: string,
}

interface ClientDetailsEditorProps {
Expand All @@ -34,12 +37,10 @@ function readClientDetails(): ClientDetails {
}

function getCredential(clientDetails: ClientDetails): InteractiveBrowserCredential | undefined {
return clientDetails.tenantId.length > 0 && clientDetails.clientId.length > 0
sadasant marked this conversation as resolved.
Show resolved Hide resolved
? new InteractiveBrowserCredential(clientDetails.tenantId, clientDetails.clientId, { loginStyle: clientDetails.loginStyle })
: undefined
return clientDetails.tenantId.length > 0 && clientDetails.clientId.length > 0 ? new InteractiveBrowserCredential(clientDetails) : undefined;
}

function ClientDetailsEditor({ clientDetails , onSetClientDetails }: ClientDetailsEditorProps) {
function ClientDetailsEditor({ clientDetails, onSetClientDetails }: ClientDetailsEditorProps) {
const handleDetailsChange = (newDetails: ClientDetails) => {
storeClientDetails(newDetails)
onSetClientDetails(newDetails)
Expand All @@ -52,29 +53,41 @@ function ClientDetailsEditor({ clientDetails , onSetClientDetails }: ClientDetai
});
}

const setKeyName = (keyName: string) => {
handleDetailsChange({
...clientDetails,
keyName
});
}

return (
<div>
<h3>Enter the details of your Azure AD App Registration:</h3>
<form>
<label>
Tenant Id:
<input type="text" value={clientDetails.tenantId} onChange={({target}) => handleDetailsChange({ ...clientDetails, tenantId: target.value})} />
<input type="text" value={clientDetails.tenantId} onChange={({ target }) => handleDetailsChange({ ...clientDetails, tenantId: target.value })} />
</label>
<br />
<label>
Client Id:
<input type="text" value={clientDetails.clientId} onChange={({target}) => handleDetailsChange({ ...clientDetails, clientId: target.value})} />
<input type="text" value={clientDetails.clientId} onChange={({ target }) => handleDetailsChange({ ...clientDetails, clientId: target.value })} />
</label>
<br />
<label>
Fill to create a new key with this name:
<input type="text" value={getRandomKeyName()} onChange={({ target }) => setKeyName(target.value)} />
</label>
<h4>Login Flow Style</h4>
<div>
<label>
<input type="radio" value="popup" checked={clientDetails.loginStyle ==="popup" } onChange={({target}) => setLoginStyle(target.value as BrowserLoginStyle)} />
<input type="radio" value="popup" checked={clientDetails.loginStyle === "popup"} onChange={({ target }) => setLoginStyle(target.value as BrowserLoginStyle)} />
Popup
</label>
</div>
<div>
<label>
<input type="radio" value="redirect" checked={clientDetails.loginStyle === "redirect"} onChange={({target}) => setLoginStyle(target.value as BrowserLoginStyle)} />
<input type="radio" value="redirect" checked={clientDetails.loginStyle === "redirect"} onChange={({ target }) => setLoginStyle(target.value as BrowserLoginStyle)} />
Redirect
</label>
</div>
Expand All @@ -85,7 +98,7 @@ function ClientDetailsEditor({ clientDetails , onSetClientDetails }: ClientDetai

function useKeyVaultKeys(vaultName: string, clientDetails: ClientDetails) {
const [running, setRunning] = React.useState(false)
const [keys, setKeys] = React.useState<Key[]>(undefined)
const [keys, setKeys] = React.useState<KeyVaultKey[]>(undefined)
const [error, setErrorInner] = React.useState(undefined);
const url = `https://${vaultName}.vault.azure.net`;

Expand All @@ -108,8 +121,16 @@ function useKeyVaultKeys(vaultName: string, clientDetails: ClientDetails) {
const keyResult = [];
setKeys(keyResult);

for await (const keyAttributes of keyClient.listKeys()) {
keyResult.push(await keyClient.getKey(keyAttributes.name))
if (clientDetails.keyName) {
try {
await keyClient.createKey(clientDetails.keyName, "RSA");
} catch (e) {
console.info(e);
}
}

for await (const keyProperties of keyClient.listPropertiesOfKeys()) {
keyResult.push(await keyClient.getKey(keyProperties.name))
}

setKeys(keyResult);
Expand Down Expand Up @@ -143,34 +164,34 @@ const KeyVaultTest = ({ storedVaultName, clientDetails }: KeyVaultTestProps) =>
<form onSubmit={e => { fetchKeys(); e.preventDefault(); }}>
<label>
Vault Name:
<input type="text" value={vaultName} onChange={({target}) => handleVaultNameChange(target.value)} />
<input type="text" value={vaultName} onChange={({ target }) => handleVaultNameChange(target.value)} />
</label>
<input type="submit" value="Get Keys" />
</form>
{!error ? null : <h3 style={{color: "red"}}>{error}</h3> }
{!error ? null : <h3 style={{ color: "red" }}>{error}</h3>}
{!keys ? null :
(
<table>
<thead>
<tr>
<th>Key Name</th>
<th>Enabled</th>
<th>Expires</th>
</tr>
</thead>
<tbody>
{keys.map(key => <tr key={key.name}><td>{key.name}</td><td>{key.enabled.toString()}</td><td>{key.expires && key.expires.toDateString()}</td></tr>)}
</tbody>
</table>
)
(
<table>
<thead>
<tr>
<th>Key Name</th>
<th>Enabled</th>
<th>Expires</th>
</tr>
</thead>
<tbody>
{keys.map(key => <tr key={key.name}><td>{key.name}</td><td>{key.properties.enabled.toString()}</td><td>{key.properties.expiresOn && key.properties.expiresOn.toDateString()}</td></tr>)}
</tbody>
</table>
)
}
</div>
);
}

function TestPage() {
const storedVaultName = localStorage.getItem('keyVaultName');
const [clientDetails, setClientDetails] = React.useState<ClientDetails>(readClientDetails() || { tenantId: "", clientId: "", loginStyle: "popup"})
const [clientDetails, setClientDetails] = React.useState<ClientDetails>(readClientDetails() || { tenantId: "", clientId: "", loginStyle: "popup", keyName: "" })
return (
<div>
<h1>Azure SDK Browser Manual Tests</h1>
Expand All @@ -182,6 +203,6 @@ function TestPage() {
}

ReactDOM.render(
<TestPage />,
document.getElementById("app")
<TestPage />,
document.getElementById("app")
);