Skip to content

Commit

Permalink
Make user pwd not required with oidc
Browse files Browse the repository at this point in the history
Signed-off-by: Andrea Lamparelli <[email protected]>
  • Loading branch information
lampajr committed Jan 7, 2025
1 parent 9038d5c commit f510a25
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 152 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,14 @@ private static UserRepresentation convertUserRepresentation(UserService.NewUser
rep.setLastName(user.user.lastName);
rep.setEnabled(true);

CredentialRepresentation credentials = new CredentialRepresentation();
credentials.setType(CredentialRepresentation.PASSWORD);
credentials.setTemporary(true);
credentials.setValue(user.password);
rep.setCredentials(List.of(credentials));
if (user.password != null && !user.password.isBlank()) {
CredentialRepresentation credentials = new CredentialRepresentation();
credentials.setType(CredentialRepresentation.PASSWORD);
credentials.setTemporary(true);
credentials.setValue(user.password);
rep.setCredentials(List.of(credentials));
}

return rep;
}

Expand Down
125 changes: 6 additions & 119 deletions horreum-web/src/domain/admin/Administrators.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,17 @@ import { useSelector } from "react-redux"
import { Button,
DualListSelector,
Form,
FormGroup,
HelperText,
HelperTextItem,
FormHelperText,
Modal,
Spinner,
TextInput } from "@patternfly/react-core"
FormGroup
} from "@patternfly/react-core"

import { TabFunctionsRef } from "../../components/SavedTabs"
import {userApi, UserData} from "../../api"
import UserSearch from "../../components/UserSearch"
import { isAdminSelector, userName } from "../../auth"
import { noop } from "../../utils"
import {isAdminSelector, userName} from "../../auth"
import {AppContext} from "../../context/appContext";
import {AppContextType} from "../../context/@types/appContextTypes";
import NewUserModal from "../user/NewUserModal";
import {noop} from "../../utils";


function userElement(u: UserData) {
Expand Down Expand Up @@ -114,117 +110,8 @@ export default function Administrators(props: AdministratorsProps) {
<NewUserModal
isOpen={createNewUser}
onClose={() => setCreateNewUser(false)}
onCreate={(user, password) => {
return userApi.createUser({ user, password }).then(
() => {
alerting.dispatchInfo(
"USER_CREATED",
"User created",
"User was successfully created",
3000
)
},
error => alerting.dispatchError(error, "USER_NOT_CREATED", "Failed to create new user.")
)
}}
onCreate={noop}
/>
</Form>
)
}

type NewUserModalProps = {
isOpen: boolean
onClose(): void
onCreate(user: UserData, password: string): Promise<unknown>
}

function NewUserModal(props: NewUserModalProps) {
const [username, setUsername] = useState<string>()
const [password, setPassword] = useState<string>()
const [email, setEmail] = useState<string>()
const [firstName, setFirstName] = useState<string>()
const [lastName, setLastName] = useState<string>()
const [creating, setCreating] = useState(false)
const valid = username && password && email && /^.+@.+\..+$/.test(email)
useEffect(() => {
setUsername(undefined)
setPassword("")
setEmail("")
setFirstName("")
setLastName("")
}, [props.isOpen])
return (
<Modal
title="Create new user"
isOpen={props.isOpen}
onClose={props.onClose}
actions={[
<Button
isDisabled={!valid}
onClick={() => {
setCreating(true)
props
.onCreate({ id: "", username: username || "", email, firstName, lastName }, password || "")
.catch(noop)
.finally(() => {
setCreating(false)
props.onClose()
})
}}
>
Create
</Button>,
<Button variant="secondary" onClick={props.onClose}>
Cancel
</Button>,
]}
>
{creating ? (
<Spinner size="xl" />
) : (
<Form isHorizontal>
<FormGroup isRequired label="Username" fieldId="username">
<TextInput
isRequired
value={username}
onChange={(_event, val) => setUsername(val)}
validated={username ? "default" : "error"}
/>
</FormGroup>
<FormGroup
isRequired
label="Temporary password"
fieldId="password"
>
<TextInput
isRequired
value={password}
onChange={(_event, val) => setPassword(val)}
validated={password ? "default" : "error"}
/>
<FormHelperText>
<HelperText>
<HelperTextItem variant={password ? "default" : "error"}>This password is only temporary and the user will change it during first login.</HelperTextItem>
</HelperText>
</FormHelperText>
</FormGroup>
<FormGroup isRequired label="Email" fieldId="email">
<TextInput
isRequired
type="email"
value={email}
onChange={(_event, val) => setEmail(val)}
validated={email && /^.+@.+\..+$/.test(email) ? "default" : "error"}
/>
</FormGroup>
<FormGroup label="First name" fieldId="firstName">
<TextInput value={firstName} onChange={(_event, val) => setFirstName(val)} />
</FormGroup>
<FormGroup label="Last name" fieldId="lastName">
<TextInput value={lastName} onChange={(_event, val) => setLastName(val)} />
</FormGroup>
</Form>
)}
</Modal>
)
}
2 changes: 1 addition & 1 deletion horreum-web/src/domain/admin/Teams.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ export default function Teams(props: TeamsProps) {
team={selected.name}
isOpen={newUserModalOpen}
onClose={() => setNewUserModalOpen(false)}
onCreate={(user, roles) => {
onCreate={(user, _, roles) => {
if (teamFuncsRef.current) {
teamFuncsRef.current.addMember(user, roles)
}
Expand Down
2 changes: 1 addition & 1 deletion horreum-web/src/domain/user/ManagedTeams.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export default function ManagedTeams(props: ManagedTeamsProps) {
team={team.key}
isOpen={createNewUser}
onClose={() => setCreateNewUser(false)}
onCreate={(user, roles) => {
onCreate={(user, _, roles) => {
teamMembersFuncs.current && teamMembersFuncs.current.addMember(user, roles)
}}
/>
Expand Down
60 changes: 34 additions & 26 deletions horreum-web/src/domain/user/NewUserModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ import {userApi, UserData} from "../../api"
import { getRoles } from "./TeamMembers"
import {AppContext} from "../../context/appContext";
import {AppContextType} from "../../context/@types/appContextTypes";
import {useSelector} from "react-redux";
import {oidcSelector} from "../../auth";


type NewUserModalProps = {
team: string
team?: string
isOpen: boolean
onClose(): void
onCreate(user: UserData, roles: string[]): void
onCreate(user: UserData, password: string | undefined, roles: string[]): void
}

export default function NewUserModal(props: NewUserModalProps) {
Expand All @@ -38,7 +40,8 @@ export default function NewUserModal(props: NewUserModalProps) {
const [tester, setTester] = useState(true)
const [uploader, setUploader] = useState(false)
const [manager, setManager] = useState(false)
const valid = username && password && email && /^.+@.+\..+$/.test(email)
const isOidc = useSelector(oidcSelector) !== undefined;
const valid = username && (password || isOidc) && email && /^.+@.+\..+$/.test(email)
useEffect(() => {
setUsername(undefined)
setPassword("")
Expand All @@ -61,10 +64,10 @@ export default function NewUserModal(props: NewUserModalProps) {
onClick={() => {
setCreating(true)
const user = { id: "", username: username || "", email, firstName, lastName }
const roles = getRoles(viewer, tester, uploader, manager)
const roles = props.team ? getRoles(viewer, tester, uploader, manager) : []
userApi.createUser({ user, password, team: props.team, roles })
.then(() => {
props.onCreate(user, roles)
props.onCreate(user, password, roles)
alerting.dispatchInfo(
"USER_CREATED",
"User created",
Expand Down Expand Up @@ -94,22 +97,24 @@ export default function NewUserModal(props: NewUserModalProps) {
<Form isHorizontal>
<FormGroup isRequired label="Username" fieldId="username">
<TextInput
id="username"
isRequired
value={username}
onChange={(_event, val) => setUsername(val)}
validated={username ? "default" : "error"}
/>
</FormGroup>
<FormGroup
isRequired
isRequired={!isOidc}
label="Temporary password"
fieldId="password"
>
<TextInput
isRequired
id="password"
isRequired={!isOidc}
value={password}
onChange={(_event, val) => setPassword(val)}
validated={password ? "default" : "error"}
validated={(password || isOidc) ? "default" : "error"}
/>
<FormHelperText>
<HelperText>
Expand All @@ -119,6 +124,7 @@ export default function NewUserModal(props: NewUserModalProps) {
</FormGroup>
<FormGroup isRequired label="Email" fieldId="email">
<TextInput
id="email"
isRequired
type="email"
value={email}
Expand All @@ -127,27 +133,29 @@ export default function NewUserModal(props: NewUserModalProps) {
/>
</FormGroup>
<FormGroup label="First name" fieldId="firstName">
<TextInput value={firstName} onChange={(_event, val) => setFirstName(val)} />
<TextInput id="first_name" value={firstName} onChange={(_event, val) => setFirstName(val)} />
</FormGroup>
<FormGroup label="Last name" fieldId="lastName">
<TextInput value={lastName} onChange={(_event, val) => setLastName(val)} />
</FormGroup>
<FormGroup label="Permissions" fieldId="permissions">
<List isPlain>
<ListItem>
<Checkbox id="viewer" isChecked={viewer} onChange={(_event, val) => setViewer(val)} label="Viewer" />
</ListItem>
<ListItem>
<Checkbox id="tester" isChecked={tester} onChange={(_event, val) => setTester(val)} label="Tester" />
</ListItem>
<ListItem>
<Checkbox id="uploader" isChecked={uploader} onChange={(_event, val) => setUploader(val)} label="Uploader" />
</ListItem>
<ListItem>
<Checkbox id="manager" isChecked={manager} onChange={(_event, val) => setManager(val)} label="Manager" />
</ListItem>
</List>
<TextInput id="last_name" value={lastName} onChange={(_event, val) => setLastName(val)} />
</FormGroup>
{props.team && (
<FormGroup label="Permissions" fieldId="permissions">
<List isPlain>
<ListItem>
<Checkbox id="viewer" isChecked={viewer} onChange={(_event, val) => setViewer(val)} label="Viewer" />
</ListItem>
<ListItem>
<Checkbox id="tester" isChecked={tester} onChange={(_event, val) => setTester(val)} label="Tester" />
</ListItem>
<ListItem>
<Checkbox id="uploader" isChecked={uploader} onChange={(_event, val) => setUploader(val)} label="Uploader" />
</ListItem>
<ListItem>
<Checkbox id="manager" isChecked={manager} onChange={(_event, val) => setManager(val)} label="Manager" />
</ListItem>
</List>
</FormGroup>
)}
</Form>
)}
</Modal>
Expand Down

0 comments on commit f510a25

Please sign in to comment.