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

[Active users][Settings][Account settings] Adapt fields and sync data #135

Closed
wants to merge 5 commits into from

Conversation

carma12
Copy link
Collaborator

@carma12 carma12 commented Aug 3, 2023

The 'Account settings' section has different types of UI components. Only the 'Text input' ones (given by the IpaTextInput component) were adapted to retrieve the data from the metadata and update this value. This has been adapted and now more elements are capable to do that. Those are:

  • Text inputs accompanied with 'Add' and 'Delete' buttons
    • Field(s): 'Principal alias' (krbprincipalname)
  • Dropdown selectors
    • Field(s): 'Radius proxy configuration' (ipatokenradiusconfiglink) and 'External IdP configuration' (ipaidpconfiglink)
  • Data-time selectors
    • Field(s): 'Kerberos principal expiration (UTC) (krbprincipalexpiration)
  • Group of checkboxes
    • Field(s): 'User authentication types' (ipauserauthtype)

Also, the following fields have been adapted to use the IpaTextInput component:

  • 'User login' (uid)
  • 'Password' (has_password)
  • 'Password expiration' (krbpasswordexpiration)
  • 'UID' (uidnumber)
  • 'GID' (gidnumber)
  • 'Login shell' (loginshell)
  • 'Home directory' (homedirectory)
  • 'Radius proxy username' (ipatokenradiususername)
  • 'External IdP user identifier' (ipaidpsub)

Signed-off-by: Carla Martinez [email protected]

@carma12 carma12 added the WIP Work in Progress (do not merge) label Aug 3, 2023
@carma12 carma12 force-pushed the account-settings-sync-fields branch 4 times, most recently from 88755ec to 371416a Compare August 7, 2023 08:10
@carma12 carma12 force-pushed the account-settings-sync-fields branch 2 times, most recently from f1ace78 to 8bf91c4 Compare August 10, 2023 06:55
@carma12 carma12 changed the title 'Account settings' sync fields Active users][Settings][Account settings] Adapt fields and sync data Aug 10, 2023
@carma12 carma12 changed the title Active users][Settings][Account settings] Adapt fields and sync data [Active users][Settings][Account settings] Adapt fields and sync data Aug 10, 2023
@carma12 carma12 requested a review from pvoborni August 10, 2023 07:22
@carma12 carma12 force-pushed the account-settings-sync-fields branch 2 times, most recently from 29a4160 to 47c8def Compare August 10, 2023 14:23
The functionality to take data directly from
the metadata needs to be implemented for the
Text inputs with buttons. This should be
applied to the following field: 'Principal
alias' (`krbprincipalname`).

Signed-off-by: Carla Martinez <[email protected]>
@carma12 carma12 force-pushed the account-settings-sync-fields branch 2 times, most recently from df737a7 to d6254ec Compare August 11, 2023 08:23
The functionality for the group of checkboxes
needs to be implemented and applied to the
following field: 'User authentication types'
(`ipauserauthtype`).

Signed-off-by: Carla Martinez <[email protected]>
@carma12 carma12 force-pushed the account-settings-sync-fields branch from d6254ec to adb4c1f Compare August 11, 2023 08:38
The Select[1] components need to be adapted to
take data from the metadata. This will be
applied for the fields 'Radius proxy configuration'
and 'External IdP configuration'.

[1]- http://v4-archive.patternfly.org/v4/components/select
Signed-off-by: Carla Martinez <[email protected]>
The Date-time picker[1] component needs to be adapted
to take the data from the metadata and keep managing
its functionality while using other components/wrappers.

This is applied to the following field: 'Kerberos principal
expiration (UTC).

[1] - http://v4-archive.patternfly.org/v4/components/date-picker
Signed-off-by: Carla Martinez <[email protected]>
The following fields need to be adapted to use
the `IpaTextInput` component:
- 'User login' (`uid`)
- 'Password' (`has_password`)
- 'Password expiration' (`krbpasswordexpiration`)
- 'UID' (`uidnumber`)
- 'GID' (`gidnumber`)
- 'Login shell' (`loginshell`)
- 'Home directory' (`homedirectory`)
- 'Radius proxy username' (`ipatokenradiususername`)
- 'External IdP user identifier' (`ipaidpsub`)

Signed-off-by: Carla Martinez <[email protected]>
@carma12 carma12 force-pushed the account-settings-sync-fields branch from adb4c1f to e615727 Compare August 11, 2023 08:46
@carma12 carma12 removed the WIP Work in Progress (do not merge) label Aug 11, 2023
Copy link
Member

@pvoborni pvoborni left a comment

Choose a reason for hiding this comment

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

The MR is humongous having it split into multiple would be better.

Providing review after reading first 2 patches. The rest will come later.

We can discuss how and when to address them as some could be done in separate MRs so that this MR won't become sn impossible task.

aria-label="user login"
isDisabled
<IpaTextInput
name={"uid"}
Copy link
Member

Choose a reason for hiding this comment

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

I think it would be valid and probably better also notation: name="uid" as this is a constant thus no need to wrap it with {}.

But I understand why it is used as we used it also in Identity section.

newValue: string | string[],
paramName: string
) => {
if (!isSimpleValue(paramName)) {
Copy link
Member

Choose a reason for hiding this comment

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

import { isSimpleValue } from "./userUtils"; should not be used in ipaObjectUtils module as that implementation is limited to user object thus would be unusable for other object types.

In this form, this method should be in userUtils module.

To be generic for other objects, we would need to find a different way, e.g. pass the isSimpleValue method to the updateIpaObject or something else.

@@ -14,6 +14,7 @@ interface PropsToDataTimePicker {
toggleIndicator?: React.ElementType | null;
toggleOnToggle?: (value: boolean, event: any) => void;
toggleStyle?: React.CSSProperties | undefined;
// isDisabled: boolean;
Copy link
Member

Choose a reason for hiding this comment

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

Changes in this file looks like forgotten leftovers.

const minutes = date.substring(10, 12);
const seconds = date.substring(12, 14);

const dateFormat = new Date(
Copy link
Member

Choose a reason for hiding this comment

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

I don't think call create UTC Date. See in Individual date and time component values https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date#parameters You can also check the old UI implementation https://github.com/freeipa/freeipa/blob/master/install/ui/src/freeipa/datetime.js#L44

// less than 10.
// - E.g.: 3 --> 03
export const getFullDay = (day: Date) => {
return (day.getDate() < 10 ? "0" : "") + day.getDate();
Copy link
Member

Choose a reason for hiding this comment

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

const minutes = getFullMinutes(date);
const seconds = getFullSeconds(date);

return (
Copy link
Member

Choose a reason for hiding this comment

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

As indicated by the Z at the end, the idea is to return UTC date. But the method used are not using UTC dates. The getXXXmethods should be using the UTC variants getUTCXXX. E.g. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getUTCFullYear

This probably works only because similar mistake is done in parsing part. But it might have side effect in displaying dates.

React.useEffect(() => {
if (props.ipaObject !== undefined) {
// Parse ipaObject into 'User' type to access the 'datetime' parameter
const user = props.ipaObject as unknown as User;
Copy link
Member

Choose a reason for hiding this comment

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

IpaCalendar component should not have any reference to a specific object type (in this case user). The raw value should be obtained the same way as in text input, e.g.:

const { required, readOnly, value, onChange } = getParamProperties(props);

After that you can extract the base64 value and change it into Date object. There is also no need to do it in an effect as it is simple conversion of value from props.

But the question is whether we should be doing this parsing here. I think that the conversion from base64 to Date or string (depending what we find more useful) should happen in apiToUser method in userUtils or any similar method that is used in rpc for other object types.

The reason is that in ipaObject should be of the same type/structure after changing it. Or in other words, it should be possible to set it to the same value and be regarded as a same value. Atm the source is object with base64 string and after modification it is string, thus this doesn't apply.

@pvoborni pvoborni self-assigned this Aug 21, 2023
Copy link
Member

@pvoborni pvoborni left a comment

Choose a reason for hiding this comment

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

Added review for "selectors".


useEffect(() => {
const idpList: string[] = [];
props.idpConf.map((item) => {
Copy link
Member

Choose a reason for hiding this comment

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

There should be an additional "empty" item which allows users to remove radius proxy or display nothing when a user doesn't have a proxy defined.

Atm, after adding a radius proxy to IPA, this control shows that the users have it even though they don't.

@@ -197,6 +202,59 @@ const UsersAccountSettings = (props: PropsToUsersAccountSettings) => {
</Button>,
];

// Dropdown 'Radius proxy configuration'
const [isRadiusConfOpen, setIsRadiusConfOpen] = useState(false);
Copy link
Member

Choose a reason for hiding this comment

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

Most of this logic could be generalized and be part of IpaSelect - thus reusable for other parts. The only specific part is translation of radius proxy objects into list of strings. The same applies for idp config.

const [radiusConfSelected, setRadiusConfSelected] = useState(
ipaObject.ipatokenradiusconfiglink
);
const [radiusConfOptions, setRadiusConfOptions] = useState<string[]>([]);
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't need to be a state. And the conversion from radiusProxyConf doesn't need to be in an effect -> simplification.

@@ -23,6 +30,8 @@ type UserSettingsData = {
certData?: Record<string, unknown>;
refetch: () => void;
modifiedValues: () => Partial<User>;
radiusServer: RadiusServer[];
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't the name be plural for both radius proxies and idp servers? As it is an array.

@@ -102,6 +148,54 @@ const useUserSettingsData = (userId: string): UserSettingsData => {
setModified(modified);
}, [user, userFullData]);

// Detect any change for 'radiusServer'
useEffect(() => {
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand why this // Detect any change for 'radiusServer' and // Detect any change for 'idpServer' code exist. E.g. selected radius proxy should be part of ipatokenradiusconfiglink attribute of user object. Detection of its change is already implemented in the // Detect any change in 'originalUser' and 'user' objects.

The loaded lists of radius proxies and idp servers are just information to show as options in the select.

const [modified, setModified] = useState(false);

// Data displayed and modified by the user
const [user, setUser] = useState<Partial<User>>({});
const [radiusServer, setRadiusServer] = useState<RadiusServer[]>([]);
Copy link
Member

Choose a reason for hiding this comment

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

const [radiusServer, setRadiusServer] = useState<RadiusServer[]>([]);
const [idpServer, setIdpServer] = useState<IDPServer[]>([]);

should not be needed as it is just copying info from their "data" counterparts.

But the hook should return the data counterparts the same way as it is doing for e.g. metadata.

@@ -197,6 +202,59 @@ const UsersAccountSettings = (props: PropsToUsersAccountSettings) => {
</Button>,
];

// Dropdown 'Radius proxy configuration'
const [isRadiusConfOpen, setIsRadiusConfOpen] = useState(false);
const [radiusConfSelected, setRadiusConfSelected] = useState(
Copy link
Member

Choose a reason for hiding this comment

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

The "selected" state is not needed as the value is already part of user/ipaObject.

@pvoborni
Copy link
Member

Actually I think that each commit should be a separate MR so that we can merge one by one. Without it, it may takes us forever to merge this. This is especially true for the last checkboxes and krbprincipal aliases. I don't want to comment these 2 here as it would be better to have the commentary to be in its own place.

@carma12
Copy link
Collaborator Author

carma12 commented Aug 25, 2023

As agreed, this PR will contain the functionality related to the Datetime selector, as most of the comments are focused on that one. The rest of the commit messages will be addressed in different PRs. These are the ones created so far:

I will be adding the rest of the PRs when they are created.

objectName="user"
metadata={props.metadata}
idx={idx}
readOnly={true} // This field is always read-only
Copy link
Collaborator

Choose a reason for hiding this comment

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

Very minor issue, but I think you get a build warning when a prop is explicitly set to true or false. A boolean prop is set or it isn't. Again, if it's not generating a warning then don't worry about it, but I've seen this trigger annoying messages. :-)

@pvoborni
Copy link
Member

@carma12 this PR can be closed, right? As I think all the parts were already merged separately.

@carma12
Copy link
Collaborator Author

carma12 commented Sep 18, 2023

@carma12 carma12 closed this Sep 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants