Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Jan 25, 2024
2 parents d818af4 + d24d507 commit a455158
Show file tree
Hide file tree
Showing 50 changed files with 591 additions and 180 deletions.
28 changes: 23 additions & 5 deletions docs/admin-gui/self-service/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -228,22 +228,40 @@ Old password field and Password propagation section can be configured (can be hi
<password>
<propagationUserControl>mapping</propagationUserControl>
<passwordChangeSecurity>oldPassword</passwordChangeSecurity>
<passwordHintConfigurability>alwaysConfigure</passwordHintConfigurability>
</password>
----

[%autowidth]
|===
| Attribute | Description | Possible values

| propagationUserControl
| *propagationUserControl*
| Constraints that define how propagation of the credentials can be controlled by the +
user. E.g. if user can choose where the password change will be propagated.
| _mapping_ (Credentials propagation will be determined by the mappings. User cannot choose where the credentials will be propagated.The credentials propagation dialog will not be shown.)_userChoice_ (The user can choose where the credentials will be propagated.The propagation dialog will be shown.)onlyMapping(Credentials propagation will be determined by the mappings. User cannot choose where the credentials will be propagated. But the propagation dialog will be shown.)identityManagerMandatory(Identity Manager Repository will be propagated always. The user can choose where the other credentials will be propagated. The propagation dialog will be shown.)
| _**mapping**_ (Credentials propagation will be determined by the mappings. User cannot choose where the credentials will be propagated.The credentials propagation dialog will not be shown.)

_**userChoice**_ (The user can choose where the credentials will be propagated.The propagation dialog will be shown.)

_**onlyMapping**_(Credentials propagation will be determined by the mappings. User cannot choose where the credentials will be propagated. But the propagation dialog will be shown.)

_**identityManagerMandatory**_(Identity Manager Repository will be propagated always. The user can choose where the other credentials will be propagated. The propagation dialog will be shown.)

| passwordChangeSecurity
| Additional security applied when changing a password.This applies when user is changing his own password. It does NOT applywhen administrator changes password of other user.
| _none_ (No additional security. Password can be changed by supplying new value.)_oldPassword_ (User must supply old password to change the password.)
| Additional security applied when changing a password.This applies when user is changing his own password. It does NOT apply when administrator changes password of other user.
| _**none**_ (No additional security. Password can be changed by supplying new value.)

_**oldPassword**_ (User must supply old password to change the password.)

_**oldPasswordIfExists**_ (User must supply old password, if exists, to change the password.)

| *passwordHintConfigurability*
| Additional configurability applied when changing or resetting a password.
This applies when user is changing or resetting his own password. It does NOT apply
when administrator changes password of other user. Default value is _**alwaysConfigure**_.
| _**alwaysConfigure**_ (Always configurable password hint, during changing and resetting password.)

_**neverConfigure**_ (Never configurable password hint, during changing and resetting password.)

|===

Expand Down Expand Up @@ -284,4 +302,4 @@ image::image2017-1-16-1-34-10.png[]

The view also can be switched to All organizations view - to see all available organizatoins, All roles view - to see all available roles and All services view - to see all available services.

Only requestable items should be displayed on the Request a role page. Requestable is a status which is computed according to Requestable field of the assignable item and according to the authorizations of the user (for now, this requestable status is computed only for Role type objects).
Only requestable items should be displayed on the Request a role page. Requestable is a status which is computed according to Requestable field of the assignable item and according to the authorizations of the user (for now, this requestable status is computed only for Role type objects).
119 changes: 119 additions & 0 deletions docs/security/authentication/administrator-initial-password.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
= Administrator Initial Password
:page-since: "4.8.1"

Since version 4.8.1 MidPoint distribution does not come with default administrator password `5ecr3t`, but rather provides several ways to set initial password or if initial password is not set, password is generated.




== Using Generated Password

If clean installation of midPoint is started without any configuration for initial password, during first run of midPoint password will be generated
and printed out in the logs.

To obtain it, you should start your midPoint instance and search logs for `Administrator initial password`.
The password may contain spaces, so it is enclosed with double qoutes. Do not forget to remove qoutes.

WARNING: after first login to Administrator account change the password, or disable built-in administrator, because initial password may still be present in logs or environment variables after some time.

.Obtaining password from logs:

[source, shell]
----
$ grep "Administrator initial password" var/log/midpoint.log <1>
2024-01-24 11:21:35,392 [] [main] WARN (com.evolveum.midpoint.init.DataImport): Administrator initial password (except double quotes): "Ec5s !f7a" <2>
----
<1> Searching logs using `grep` for initial password
<2> The initial password is `Ec5s !f7a` (you should copy it without leading and trailing qoutes)



== Setup of initial password

Initial password must conform to <<default-password-policy,default password policy>>, otherwise administrator user will not be created.

You can configure initial password:

* <<environment-variable>> (recommended way)
* <<java-property>>
* <<config-xml>>


[[default-password-policy]]
=== Default Password Policy

Default password policy is stricter since midPoint 4.8.1 and following are the requirements for password:

* length: 8 - 14 characters
* at least one uppercase letter
* at least one lowercase letter
* at least one number
* you can use also special characters


[[environment-variable]]
=== Using environment variable

Setting initial password using environment variable provides most possibilites and it is also compatible also with Docker conventions.

You need to set environment variable `MP_SET_midpoint_administrator_initialPassword` to value of initial password.

NOTE: This is useful for developers also, they can configure their environment variables to store default midPoint password so it will not change with any new run.

.Shell
[source, shell]
----
export MP_SET_midpoint_administrator_initialPassword=Test5ecr3t
bin/midpoint.sh start
----

=== Docker Examples

.Docker
[source, bash]
-----
docker run evolveum/midpoint ... -E MP_SET_midpoint_administrator_initialPassword=Test5ecr3t ...
-----


.Docker Compose
[source, yaml]
----
version: "3.3"
services:
midpoint:
image: evolveum/midpoint
environment:
MP_SET_midpoint_administrator_initialPassword: Test5ecr3t
...
----


[[java-property]]
=== Using java property

It is possible to also set default initial password using java property `midpoint.administrator.initialPassword`.

[source, shell]
----
bin/midpoint.sh start -Dmidpoint.administrator.initialPassword=Test5ecr3t
----

[[config-xml]]
=== Using config.xml

If any of previous methods does not work for you, it is possible to setup initial password using `config.xml`, which contains also other infrastructure passwords.


. config.xml
[source, xml]
----
<configuration>
<midpoint>
....
<administrator>
<initialPassword>xml5ecr3t</initialPassword>
</administrator>
</midpoint>
</configuration>
----
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.delta.ReferenceDelta;
import com.evolveum.midpoint.util.exception.CommonException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;

Expand All @@ -18,13 +19,13 @@
*/
public interface PrismObjectWrapper<O extends ObjectType> extends PrismContainerWrapper<O> {

ObjectDelta<O> getObjectDelta() throws SchemaException;
ObjectDelta<O> getObjectDelta() throws CommonException;

PrismObject<O> getObject();

PrismObject<O> getObjectOld();

PrismObject<O> getObjectApplyDelta() throws SchemaException;
PrismObject<O> getObjectApplyDelta() throws CommonException;

String getOid();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2867,15 +2867,19 @@ public static List<AssignmentObjectRelation> divideAssignmentRelationsByAllValue
newRelation.setRelations(assignmentObjectRelation.getRelations());
newRelation.setArchetypeRefs(Collections.singletonList(archetypeRef));
newRelation.setDescription(assignmentObjectRelation.getDescription());
resultList.add(newRelation);
if (!assignmentObjectRelationAlreadyExists(resultList, newRelation)) {
resultList.add(newRelation);
}
});
} else {
AssignmentObjectRelation newRelation = new AssignmentObjectRelation();
newRelation.setObjectTypes(Collections.singletonList(objectType));
newRelation.setRelations(assignmentObjectRelation.getRelations());
newRelation.setArchetypeRefs(assignmentObjectRelation.getArchetypeRefs());
newRelation.setDescription(assignmentObjectRelation.getDescription());
resultList.add(newRelation);
if (!assignmentObjectRelationAlreadyExists(resultList, newRelation)) {
resultList.add(newRelation);
}
}
});
} else {
Expand Down Expand Up @@ -2917,34 +2921,34 @@ public static boolean assignmentObjectRelationAlreadyExists(List<AssignmentObjec
for (AssignmentObjectRelation rel : list) {
if (CollectionUtils.isNotEmpty(rel.getRelations()) && CollectionUtils.isEmpty(relation.getRelations())
|| CollectionUtils.isEmpty(rel.getRelations()) && CollectionUtils.isNotEmpty(relation.getRelations())) {
return false;
continue;
}
if (CollectionUtils.isNotEmpty(rel.getRelations()) && CollectionUtils.isNotEmpty(relation.getRelations())) {
if (!rel.getRelations().get(0).equals(relation.getRelations().get(0))) {
return false;
if (!QNameUtil.match(rel.getRelations().get(0), (relation.getRelations().get(0)))) {
continue;
}
}
if (CollectionUtils.isNotEmpty(rel.getObjectTypes()) && CollectionUtils.isEmpty(relation.getObjectTypes())
|| CollectionUtils.isEmpty(rel.getObjectTypes()) && CollectionUtils.isNotEmpty(relation.getObjectTypes())) {
return false;
continue;
}
if (CollectionUtils.isNotEmpty(rel.getObjectTypes()) && CollectionUtils.isNotEmpty(relation.getObjectTypes())) {
if (!rel.getObjectTypes().get(0).equals(relation.getObjectTypes().get(0))) {
return false;
if (!QNameUtil.match(rel.getObjectTypes().get(0), relation.getObjectTypes().get(0))) {
continue;
}
}
if (CollectionUtils.isNotEmpty(rel.getArchetypeRefs()) && CollectionUtils.isEmpty(relation.getArchetypeRefs())
|| CollectionUtils.isEmpty(rel.getArchetypeRefs()) && CollectionUtils.isNotEmpty(relation.getArchetypeRefs())) {
return false;
continue;
}
if (CollectionUtils.isNotEmpty(rel.getArchetypeRefs()) && CollectionUtils.isNotEmpty(relation.getArchetypeRefs())) {
if (!rel.getArchetypeRefs().get(0).equals(relation.getArchetypeRefs().get(0))) {
return false;
continue;
}
}
return true;
}
return true;
return false;
}

private static Collection<ObjectDeltaOperation<? extends ObjectType>> saveTask(ObjectDelta<TaskType> delta, OperationResult result, PageBase pageBase) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2010-2023 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/
package com.evolveum.midpoint.gui.impl.factory.wrapper;

import com.evolveum.midpoint.gui.api.prism.ItemStatus;
import com.evolveum.midpoint.gui.api.prism.wrapper.PrismObjectWrapper;
import com.evolveum.midpoint.gui.impl.prism.wrapper.AssignmentHolderWrapper;
import com.evolveum.midpoint.prism.*;
import com.evolveum.midpoint.util.QNameUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentHolderType;

import jakarta.annotation.PostConstruct;
import org.springframework.stereotype.Component;

/**
* @author skublik
*
* Wrapper factory for AssignmentHolderType.
*/
@Component
public class AssignmentHolderWrapperFactoryImpl extends PrismObjectWrapperFactoryImpl<AssignmentHolderType> {

@Override
public PrismObjectWrapper<AssignmentHolderType> createObjectWrapper(PrismObject<AssignmentHolderType> object, ItemStatus status) {
return new AssignmentHolderWrapper(object, status);
}

@Override
public boolean match(ItemDefinition<?> def) {
return def instanceof PrismObjectDefinition && AssignmentHolderType.class.isAssignableFrom(def.getTypeClass());
}

@Override
public int getOrder() {
return 98;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void register() {

@Override
public int getOrder() {
return 99;
return 97;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,12 +311,6 @@ public Collection<ObjectDeltaOperation<? extends ObjectType>> saveOrPreviewPerfo
}
checkValidationErrors(target, objectDetailsModels.getValidationErrors());

for (ObjectDelta<? extends ObjectType> delta : deltas) {
if (delta.isAdd()) {
removeExtraParentOrgRef(delta.getObjectToAdd().asObjectable());
}
}

} catch (Throwable ex) {
result.recordFatalError(getString("pageAdminObjectDetails.message.cantCreateObject"), ex);
LoggingUtils.logUnexpectedException(LOGGER, "Create Object failed", ex);
Expand All @@ -339,53 +333,6 @@ public Collection<ObjectDeltaOperation<? extends ObjectType>> saveOrPreviewPerfo
return executedDeltas;
}

/**
* Removes `parentOrgRef` values from a to-be-created object that should not be there, because of the object's inactivity.
*
* == Rationale
*
* Because of the authorization requirements (both when the object editing starts - see edit schema,
* and when the operation is submitted to execution), we manually set-up a `parentOrgRef` value for each org assignment
* that is pre-created in the new object. This is typically when the object is created as a child in a given org via GUI:
* The GUI creates the respective org assignment and `parentOrgRef` value.
*
* (Note that this is not wholly correct, and is more a workaround than a real solution. The real solution would be
* to either call the projector to do this, or to change the authorization evaluation to not depend on `parentOrgRef`.
* That way or another, it is currently so. See also MID-3234.)
*
* The problem occurs when the object is changed to `draft` or similar LC state during editing. The added `parentOrgRef`
* should no longer be there, as the current implementation is that the org assignment(s) are inactive in such object LC
* states (unless the state model says otherwise). If they are present and should not be, the model refuses
* the ADD operation (see MID-9264). So this method removes them.
*
* == Limitations
*
* We do NOT treat general cases here, like when the respective assignment itself is modified (e.g.,
* disabled, validity changed, LC state changed, etc.). We only treat the case when the object as a whole is
* put into "assignments inactive" LC state.
*/
private void removeExtraParentOrgRef(@NotNull ObjectType object) throws ConfigurationException {
if (!(object instanceof AssignmentHolderType)) {
return; // There are no assignments to be considered
}

SystemConfigurationType config = MidPointApplication.get().getSystemConfigurationIfAvailable();
LifecycleStateModelType objectStateModel =
ArchetypeManager.determineLifecycleModel(object.asPrismObject(), config);

// As for the task execution mode is concerned, we are interested only in whether production or development config
// is to be used. Currently, all GUI "object details page" actions are carried out in production mode. So we can
// safely use TaskExecutionMode.PRODUCTION here.
boolean assignmentsActive = MidPointApplication.get().getActivationComputer().lifecycleHasActiveAssignments(
object.getLifecycleState(), objectStateModel, TaskExecutionMode.PRODUCTION);

if (!assignmentsActive) {
// We assume that this is a new object. All parentOrgRef values should come through assignments.
// Hence, if assignments are not active, we can remove all such values.
object.getParentOrgRef().clear();
}
}

protected void postProcessResultForWizard(
OperationResult result,
Collection<ObjectDeltaOperation<? extends ObjectType>> executedDeltas,
Expand Down

0 comments on commit a455158

Please sign in to comment.