-
Notifications
You must be signed in to change notification settings - Fork 271
Add impersonate User feature #7988
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
base: master
Are you sure you want to change the base?
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #7988 +/- ##
==========================================
- Coverage 41.85% 41.79% -0.07%
==========================================
Files 42 42
Lines 939 938 -1
Branches 238 238
==========================================
- Hits 393 392 -1
+ Misses 527 502 -25
- Partials 19 44 +25
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
|
||
function authenticate() { | ||
|
||
const requestUrl = authorization_endpoint |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are loading the spa-sdk from console/index.html. So this iframe too may have access to that. If it does, we can use the spa sdk methods to build the authorization URL, instead of chaining params manually
"&redirect_uri=" + window.location.origin + window.location.pathname + | ||
"&state=sample_state&scope=internal_user_impersonate&response_type=id_token%20subject_token" + | ||
"&requested_subject=" + userId + | ||
"&nonce=2131236&code_challenge=" + code_challenge + "&code_challenge_method=S256"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's randomize the nonce
value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PS: If you are using spa sdk, we wouldn't need to worry about this.
window.location.href = requestUrl; | ||
} else { | ||
if (sessionStorage.getItem("impersonation_artifacts") === null) { | ||
sessionStorage.setItem("impersonation_artifacts", hash); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the id token fragment, isn't it? if it is, let's use a better name for the session storage key
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it contains id_token & subject_token this is why I named it as impersonation_artifacts.
features/admin.roles.v2/components/edit-role/edit-role-basic.tsx
Outdated
Show resolved
Hide resolved
const [ codeChallenge, setCodeChallenge ] = useState<string>(undefined); | ||
const [ idToken, setIdToken ] = useState(undefined); | ||
const [ subjectToken, setSubjectToken ] = useState(undefined); | ||
const [ authenticatedUserRoles, setAuthenticatedUserRoles ] = useState<RolesMemberInterface[]>([]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall we try defining a custom hook for the impersonation logic? otherwise the user profile component file is getting longer and impersonation logic is tightly coupled to the user profile component.
We can move the state variables, useEffects and other logic to this custom hook.
"Content-Type": "application/x-www-form-urlencoded" | ||
}, | ||
method: "post", | ||
shouldAttachIDPAccessToken: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This wouldn't be necessary.
* | ||
* @returns A generated code verifier. | ||
*/ | ||
public static generateCodeVerifier(): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't there already a method in @wso2is/core for this?
* @param plain - The code verifier. | ||
* @returns A generated code challange. | ||
*/ | ||
public static sha256 = async (plain: string) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's improve the function name. If this is not already available in SDK or @wso2is/core module, let's move this function there.
impersonateUserZone: { | ||
actionTitle: "Impersonate User", | ||
header: "Impersonate User", | ||
subheader: "Once Started impersonating the user, you will no longer be able to login with your identity until you terminated the session." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use the third person narrative, if possible
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the narrative used for other danger zone items as well.
modules/react-components/src/components/danger-zone/danger-zone-group.tsx
Outdated
Show resolved
Hide resolved
modules/react-components/src/components/danger-zone/danger-zone-group.tsx
Outdated
Show resolved
Hide resolved
modules/react-components/src/components/danger-zone/danger-zone-group.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Add changeset.
- Let's update the PR title and describe to accurately describe the improvement.
- Also, let's add a screencast to get a better idea about the UX.
commonPostLogoutUrl : commonPostLogoutUrl, | ||
impersonationRoleName: _config.accountApp.impersonationRoleName, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_config is to get dynamic values. since impersonationrolename is something that wouldn't change, we shouldn't use it here, IMO.
@@ -4,6 +4,8 @@ | |||
"homeRealmId": "" | |||
}, | |||
"accountApp": { | |||
"clientID": "MY_ACCOUNT", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's update the deployment.config.json.j2 and framework as well, since this file is for local development only.
@@ -0,0 +1,45 @@ | |||
<!-- | |||
~ Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use the license header for open source code.
@@ -127,7 +129,8 @@ export const EditRole: FunctionComponent<EditRoleProps> = (props: EditRoleProps) | |||
render: () => ( | |||
<ResourceTab.Pane controlledSegmentation attached={ false }> | |||
<BasicRoleDetails | |||
isReadOnly={ isAdminRole || isEveryoneRole || isReadOnly || isSharedRole } | |||
isReadOnly={ isAdminRole || isEveryoneRole || isReadOnly || isSharedRole | |||
|| roleObject?.displayName === accountAppImpersonateRoleName } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of comparing the display name, shall we use role.meta.systemRole
property? (I'm assuming the myaccount impersonation role is a system role. correct me if im wrong)
@@ -102,6 +107,7 @@ import { | |||
isMultipleEmailsAndMobileNumbersEnabled, | |||
isSchemaReadOnly | |||
} from "../utils/user-management-utils"; | |||
import { log } from "console"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unnecessary, isn't it?
@@ -161,7 +167,7 @@ interface UserProfilePropsInterface extends TestableComponentInterface { | |||
*/ | |||
editUserDisclaimerMessage?: ReactNode; | |||
/** | |||
* Admin user type | |||
* Admin user typeisLoading: isAuthenticatedUserFetchRequestLoading |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isloading property is not properly added it seems
// Load My Account Application and check | ||
// 1. If it has skip login consent. | ||
// 2. If it has disabled application. | ||
// 3. If it has shared with the sub org. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be the doc comment of the isMyAccountImpersonatable
function
<div> | ||
<iframe | ||
hidden | ||
src={ "https://localhost:9001/console/resources/init-impersonate.html" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hardcoded console url wouldn't work in other deployments. There should be a util method to get the console base URL. let's use that here
{ | ||
!isUserManagedByParentOrg && ( | ||
<DangerZone | ||
data-testid={ `${ testId }-danger-zone-toggle` } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of a toggle, cannot we use a button?
for example, when admin starts impersonating a user, he/she clicks on the impersonate button. once the process started, button text is changed to "Stop impersonation" (or a similar text). When admin decides to finish impersonating, they can do so by clicking on the button.
Also we can show a banner in the myaccount that reminds admin that they are impersonating a user. I understand that these should have suggested during ux reviews, so +1 to track these suggestions as future improvements if applicable.
🦋 Changeset detectedThe changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. |
@@ -0,0 +1,45 @@ | |||
<!-- | |||
~ Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com). All Rights Reserved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use the license header for open source code. Please check and update other places too.
Purpose
Usecase:
Impersonate User
button.Note:
Impersonation resource will be registered under my account by default - immutable
impersonate-myaccount role will be created by default - immutable
impersonation application permission will be assigned to the role by default - immutable
Admin has to assign users to the role.
Related Issues
Related PRs
Checklist
Security checks