-
Notifications
You must be signed in to change notification settings - Fork 12
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
Conversation
88755ec
to
371416a
Compare
f1ace78
to
8bf91c4
Compare
29a4160
to
47c8def
Compare
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]>
df737a7
to
d6254ec
Compare
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]>
d6254ec
to
adb4c1f
Compare
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]>
adb4c1f
to
e615727
Compare
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.
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"} |
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.
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)) { |
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.
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; |
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.
Changes in this file looks like forgotten leftovers.
const minutes = date.substring(10, 12); | ||
const seconds = date.substring(12, 14); | ||
|
||
const dateFormat = new Date( |
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.
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(); |
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.
I think something line the following would also work: String(day.getDate()).padStart(2, "0")
(untested)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/String
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
const minutes = getFullMinutes(date); | ||
const seconds = getFullSeconds(date); | ||
|
||
return ( |
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.
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 getXXX
methods 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; |
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.
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.
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.
Added review for "selectors".
|
||
useEffect(() => { | ||
const idpList: string[] = []; | ||
props.idpConf.map((item) => { |
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.
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); |
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.
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[]>([]); |
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 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[]; |
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.
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(() => { |
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.
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[]>([]); |
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.
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( |
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.
The "selected" state is not needed as the value is already part of user/ipaObject.
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. |
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 |
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.
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. :-)
@carma12 this PR can be closed, right? As I think all the parts were already merged separately. |
@pvoborni - Correct. This PR has been split to manage the changes in the following PRs:
Hence, closing this one. NOTE: The modals will be handled in a different PR as well. |
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:krbprincipalname
)ipatokenradiusconfiglink
) and 'External IdP configuration' (ipaidpconfiglink
)krbprincipalexpiration
)ipauserauthtype
)Also, the following fields have been adapted to use the
IpaTextInput
component:uid
)has_password
)krbpasswordexpiration
)uidnumber
)gidnumber
)loginshell
)homedirectory
)ipatokenradiususername
)ipaidpsub
)Signed-off-by: Carla Martinez [email protected]