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

x-okta-multi-operation bug #561

Merged
merged 45 commits into from
Mar 25, 2021
Merged
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
92bfbc6
1. definitions.Application.x-openapi-v3-discriminator.mapping.SAML_1_1
sergiishamrai-okta Feb 25, 2021
aa8b77a
2. Not finished yet
sergiishamrai-okta Feb 25, 2021
3cbcf58
removed #2
sergiishamrai-okta Feb 26, 2021
c96d8f5
2. Missing code discriminator: https://github.com/okta/openapi/blob/d…
sergiishamrai-okta Feb 26, 2021
ea4c7c0
remove code duplication
sergiishamrai-okta Mar 1, 2021
955c419
1. Remove unused SamlApplicationV1
sergiishamrai-okta Mar 2, 2021
f9fbc0b
Whitespaces for generated code updated
sergiishamrai-okta Mar 5, 2021
0bdb070
4. supportedMDMFrameworks and platforms
sergiishamrai-okta Mar 9, 2021
ed1b10e
copyright is back
sergiishamrai-okta Mar 9, 2021
a334466
fix for enums inside list/array
sergiishamrai-okta Mar 9, 2021
995012e
clean code
sergiishamrai-okta Mar 9, 2021
84f6487
revert changes
sergiishamrai-okta Mar 9, 2021
bb165a9
Merge branch 'master' into okta-349906-open-api
sergiishamrai-okta Mar 9, 2021
9f8e8fc
clean code
sergiishamrai-okta Mar 9, 2021
6eb9ac8
new method + do not break the build in case of binary incompatibility
sergiishamrai-okta Mar 9, 2021
43bc492
do not break the build in case of binary incompatibility
sergiishamrai-okta Mar 9, 2021
e262015
LinkedObject object fixes
sergiishamrai-okta Mar 9, 2021
5e65cc0
LinkedObject object ITs
sergiishamrai-okta Mar 9, 2021
1b22cea
buggy implementation updateAuthorizationServerPolicy operation
sergiishamrai-okta Mar 9, 2021
8ccca1c
sync last updates + UserType object
sergiishamrai-okta Mar 10, 2021
bc17bfc
UTs updated
sergiishamrai-okta Mar 10, 2021
3d92248
UserFactor delete method
sergiishamrai-okta Mar 10, 2021
564eba3
Deletable interface issue
sergiishamrai-okta Mar 15, 2021
1532c41
Deletable interface issue
sergiishamrai-okta Mar 15, 2021
ae181a7
AuthorizationServerPolicyRule::deletePolicyRule renamed
sergiishamrai-okta Mar 15, 2021
e4eebd8
Merge branch 'master' into okta-349906-open-api
sergiishamrai-okta Mar 15, 2021
ac730e1
delete LinkedObject properly
sergiishamrai-okta Mar 15, 2021
f9419e8
CleanUp LinkedObjects
sergiishamrai-okta Mar 15, 2021
3723dbf
remove cleanUpLinkedObjects
sergiishamrai-okta Mar 15, 2021
3b08f8f
CreateUserRequest updated
sergiishamrai-okta Mar 16, 2021
2596dd7
Merge branch 'master' into okta-349906-open-api
sergiishamrai-okta Mar 16, 2021
67772c8
v2.3.0
sergiishamrai-okta Mar 16, 2021
ef9b375
Rollback unnecessary changes
sergiishamrai-okta Mar 16, 2021
c482df8
Disable build breaking for now
sergiishamrai-okta Mar 16, 2021
6a91121
Working on Migration guide
sergiishamrai-okta Mar 16, 2021
fe75882
Imports updated
sergiishamrai-okta Mar 17, 2021
abc19b3
Migration guide updated
sergiishamrai-okta Mar 17, 2021
d19a245
Migration guide updated
sergiishamrai-okta Mar 18, 2021
85e5c8a
v4.0.0-SNAPSHOT + Migration guide updated
sergiishamrai-okta Mar 18, 2021
311af05
ITs
sergiishamrai-okta Mar 19, 2021
5e15f4a
x-okta-multi-operation bug
sergiishamrai-okta Mar 19, 2021
0d02f62
x-okta-multi-operation bug
sergiishamrai-okta Mar 22, 2021
39b87a7
Merge branch 'master' into okta-375802-x-okta-multi-operation-bug
sergiishamrai-okta Mar 24, 2021
b8a12eb
x-okta-multi-operation fixed and Migration guide updated
sergiishamrai-okta Mar 24, 2021
893bbb5
Migration.md updated
sergiishamrai-okta Mar 25, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions MIGRATING.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ Below methods have been added.
- `UserSchema updateApplicationUserProfile(String appInstanceId, UserSchema userSchema)`
- `UserSchema updateApplicationUserProfile(String appInstanceId)`
- `UserSchema updateUserProfile(String schemaId, UserSchema userSchema)`

Below method has been removed.
- `ForgotPasswordResponse apiV1UsersUserIdCredentialsForgotPasswordPost(String userId)`
sergiishamrai-okta marked this conversation as resolved.
Show resolved Hide resolved

One of listed methods could be used instead
sergiishamrai-okta marked this conversation as resolved.
Show resolved Hide resolved
- `User.forgotPasswordGenerateOneTimeToken(Boolean sendEmail)`
- `User.forgotPasswordGenerateOneTimeToken()`
- `User.forgotPasswordSetNewPassword(UserCredentials userCredentials, Boolean sendEmail)`
- `User.forgotPasswordSetNewPassword(UserCredentials userCredentials)`

### Package `com.okta.sdk.resource.user.type.UserType`

Expand Down Expand Up @@ -304,6 +313,11 @@ Below method has undergone a signature change in the interest of naming consiste
- `void addAllAppsAsTargetToRole()` to `void addAllAppsAsTarget(String roleId)`
- `void deleteFactor()` to `void deleteFactor(String factorId)`

Below methods have been added.
- `ForgotPasswordResponse forgotPasswordGenerateOneTimeToken(Boolean sendEmail)`
- `ForgotPasswordResponse forgotPasswordGenerateOneTimeToken()`
- `ForgotPasswordResponse forgotPasswordSetNewPassword(UserCredentials userCredentials, Boolean sendEmail)`
- `ForgotPasswordResponse forgotPasswordSetNewPassword(UserCredentials userCredentials)`

## Migrating from 2.x.x to 3.0.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import com.okta.sdk.resource.role.AssignRoleRequest
import com.okta.sdk.resource.role.RoleType
import com.okta.sdk.resource.user.AuthenticationProviderType
import com.okta.sdk.resource.user.ChangePasswordRequest
import com.okta.sdk.resource.user.ForgotPasswordResponse
import com.okta.sdk.resource.user.PasswordCredential
import com.okta.sdk.resource.user.RecoveryQuestionCredential
import com.okta.sdk.resource.user.ResetPasswordToken
Expand Down Expand Up @@ -761,6 +762,67 @@ class UsersIT extends ITSupport implements CrudTestSupport {
assertThat user.getCredentials().getProvider().getType(), is(AuthenticationProviderType.IMPORT)
}

@Test
@Scenario("user-forgot-password-generate-one-time-token")
void forgotPasswordGenerateOttTest() {

def password = 'Passw0rd!2@3#'
def firstName = 'John'
def lastName = 'Forgot-Password'
def email = "john-${uniqueTestName}@example.com"

// 1. Create a user
User user = UserBuilder.instance()
.setEmail(email)
.setFirstName(firstName)
.setLastName(lastName)
.setPassword(password.toCharArray())
.setActive(true)
.setSecurityQuestion("How many roads must a man walk down?")
.setSecurityQuestionAnswer("forty two")
.buildAndCreate(client)
registerForCleanup(user)
validateUser(user, firstName, lastName, email)

ForgotPasswordResponse response = user.forgotPasswordGenerateOneTimeToken(false)
assertThat response.getResetPasswordUrl(), containsString("/signin/reset-password/")
}

@Test
@Scenario("user-forgot-password-set-new-password")
void forgotPasswordSetNewPasswordTest() {

def password = 'OldPassw0rd!2@3#'
def firstName = 'John'
def lastName = 'Forgot-Password'
def email = "john-${uniqueTestName}@example.com"

// 1. Create a user
User user = UserBuilder.instance()
.setEmail(email)
.setFirstName(firstName)
.setLastName(lastName)
.setPassword(password.toCharArray())
.setActive(true)
.setSecurityQuestion("How many roads must a man walk down?")
.setSecurityQuestionAnswer("forty two")
.buildAndCreate(client)
registerForCleanup(user)
validateUser(user, firstName, lastName, email)

UserCredentials userCredentials = client.instantiate(UserCredentials)
.setPassword(client.instantiate(PasswordCredential)
.setValue('NewPassw0rd!2@3#'.toCharArray()))
.setRecoveryQuestion(client.instantiate(RecoveryQuestionCredential)
.setQuestion('How many roads must a man walk down?')
.setAnswer('forty two'))

ForgotPasswordResponse response = user.forgotPasswordSetNewPassword(userCredentials, false)
assertThat response.get("recovery_question")["question"], equalTo("How many roads must a man walk down?")
assertThat response.get("provider")["type"], equalTo("OKTA")
assertThat response.get("provider")["name"], equalTo("OKTA")
}

private void ensureCustomProperties() {
def userSchemaUri = "/api/v1/meta/schemas/user/default"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@
import io.swagger.models.Response;
import io.swagger.models.Swagger;
import io.swagger.models.parameters.BodyParameter;
import io.swagger.models.parameters.Parameter;
import io.swagger.models.properties.ArrayProperty;
import io.swagger.models.properties.Property;
import io.swagger.models.properties.RefProperty;
import io.swagger.parser.SwaggerException;
import io.swagger.util.Json;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
Expand Down Expand Up @@ -338,17 +340,36 @@ private void handleOktaLinkedOperations(Swagger swagger) {
swagger.getPaths().forEach((pathName, path) -> {
Optional<Map.Entry<HttpMethod, Operation>> operationEntry =
path.getOperationMap().entrySet().stream().filter(
e -> e.getValue().getOperationId() != null &&
e.getValue().getOperationId().equals(operationId)).findFirst();
oper -> {
//Looking for an operationId in paths:path:operationId
if (oper.getValue().getOperationId() != null
&& oper.getValue().getOperationId().equals(operationId)) {
return true;
}
//Looking for an operationId in paths:path:method:x-okta-multi-operation:operationId
List<Operation> xOktaMultiOperation = getOktaMultiOperationObject(oper.getValue());
if (xOktaMultiOperation != null &&
xOktaMultiOperation
.stream()
.anyMatch(multiOper -> multiOper.getOperationId().equals(operationId))
) {
return true;
}
return false;
}
).findFirst();

if (operationEntry.isPresent()) {

Operation operation = operationEntry.get().getValue();

//Trying to get an Operation from x-okta-multi-operation
Operation xOktaMultiOperation = produceOperationFromXOktaMultiOperation(operation, operationId);

CodegenOperation cgOperation = fromOperation(
pathName,
operationEntry.get().getKey().name().toLowerCase(),
operation,
xOktaMultiOperation != null ? xOktaMultiOperation : operation,
swagger.getDefinitions(),
swagger);

Expand Down Expand Up @@ -465,6 +486,77 @@ else if ("read".equals(alias) || "create".equals(alias)) {
});
}

private List<Operation> getOktaMultiOperationObject(Operation operation) {
Object multiOperationObject = operation.getVendorExtensions().get("x-okta-multi-operation");
List<Operation> xOktaMultiOperationList = new ArrayList<>();
if (multiOperationObject instanceof List) {
for(Object node : (List)multiOperationObject) {
Operation multiOperation = Json.mapper().convertValue(node, Operation.class);
xOktaMultiOperationList.add(multiOperation);
}
return xOktaMultiOperationList;
}
return null;
}

private Operation produceOperationFromXOktaMultiOperation(Operation operation, String operationId) {

Operation xOktaMultiOperation = null;

List<Operation> xOktaMultiOperationList = getOktaMultiOperationObject(operation);
if (xOktaMultiOperationList != null) {
Optional<Operation> operationFromXOktaMultiOperation = xOktaMultiOperationList.stream()
.filter(multiOper -> multiOper.getOperationId().equals(operationId)).findFirst();

if (operationFromXOktaMultiOperation.isPresent()) {
Operation xOktaMultiOperationTmp = operationFromXOktaMultiOperation.get();
xOktaMultiOperation = new Operation();

// VendorExtensions deep copy
Map<String, Object> vendorExtensions = new LinkedHashMap<>(operation.getVendorExtensions());
xOktaMultiOperation.setVendorExtensions(vendorExtensions);

// Tags deep copy
List<String> tags = new ArrayList<>(operation.getTags());
xOktaMultiOperation.setTags(tags);

xOktaMultiOperation.setSummary(operation.getSummary());
xOktaMultiOperation.setDescription(xOktaMultiOperationTmp.getDescription());
xOktaMultiOperation.setOperationId(xOktaMultiOperationTmp.getOperationId());

// Consumes deep copy
List<String> consumes = new ArrayList<>(operation.getConsumes());
xOktaMultiOperation.setConsumes(consumes);

// Produces deep copy
List<String> produces = new ArrayList<>(operation.getProduces());
xOktaMultiOperation.setProduces(produces);

// Parameters deep copy
List<Parameter> parameters = new ArrayList<>(operation.getParameters());
xOktaMultiOperation.setParameters(parameters);

// Responses deep copy
Map<String, Response> responses = new LinkedHashMap<>(operation.getResponses());
xOktaMultiOperation.setResponses(responses);

// Security deep copy
List<Map<String, List<String>>> security = new ArrayList<>(operation.getSecurity());
xOktaMultiOperation.setSecurity(security);

//Add params defined in x-okta-multi-operation
for(Parameter p: xOktaMultiOperationTmp.getParameters()) {
if (p instanceof BodyParameter && ((BodyParameter) p).getSchema() != null) {
xOktaMultiOperation.getParameters().add(p);
} else if (!(p instanceof BodyParameter)) {
xOktaMultiOperation.getParameters().add(p);
}
}
}
}
return xOktaMultiOperation;
}

private Map<String, String> createArgMap(ObjectNode n) {

Map<String, String> argMap = new LinkedHashMap<>();
Expand Down