Skip to content
Permalink
Browse files
Merge pull request #8 from myrle-krantz/develop
Preparation work for securing communication between applications done in the name of a user.
  • Loading branch information
myrle-krantz committed May 2, 2017
2 parents 4188673 + 45ca1ba commit f6e4927418adec924210cca67f0c0a1c6edf12a6
Showing 40 changed files with 1,383 additions and 124 deletions.
@@ -168,6 +168,35 @@ Signature getApplicationSignature(@PathVariable("applicationidentifier") String
void deleteApplicationPermission(@PathVariable("applicationidentifier") String applicationIdentifier,
@PathVariable("permissionidentifier") String permittableEndpointGroupIdentifier);

@RequestMapping(value = "/applications/{applicationidentifier}/callendpointset", method = RequestMethod.POST,
consumes = {MediaType.APPLICATION_JSON_VALUE},
produces = {MediaType.ALL_VALUE})
void createApplicationCallEndpointSet(@PathVariable("applicationidentifier") String applicationIdentifier, CallEndpointSet callEndpointSet);

@RequestMapping(value = "/applications/{applicationidentifier}/callendpointset/{callendpointsetidentifier}", method = RequestMethod.PUT,
consumes = {MediaType.APPLICATION_JSON_VALUE},
produces = {MediaType.ALL_VALUE})
void changeApplicationCallEndpointSet(@PathVariable("applicationidentifier") String applicationIdentifier,
@PathVariable("callendpointsetidentifier") String callEndpointSetIdentifier,
CallEndpointSet callEndpointSet);

@RequestMapping(value = "/applications/{applicationidentifier}/callendpointset", method = RequestMethod.GET,
consumes = {MediaType.APPLICATION_JSON_VALUE},
produces = {MediaType.ALL_VALUE})
List<CallEndpointSet> getApplicationCallEndpointSets(@PathVariable("applicationidentifier") String applicationIdentifier);

@RequestMapping(value = "/applications/{applicationidentifier}/callendpointset/{callendpointsetidentifier}", method = RequestMethod.GET,
consumes = {MediaType.APPLICATION_JSON_VALUE},
produces = {MediaType.ALL_VALUE})
CallEndpointSet getApplicationCallEndpointSet(@PathVariable("applicationidentifier") String applicationIdentifier,
@PathVariable("callendpointsetidentifier") String callEndpointSetIdentifier);

@RequestMapping(value = "/applications/{applicationidentifier}/callendpointset/{callendpointsetidentifier}", method = RequestMethod.DELETE,
consumes = {MediaType.APPLICATION_JSON_VALUE},
produces = {MediaType.ALL_VALUE})
void deleteApplicationCallEndpointSet(@PathVariable("applicationidentifier") String applicationIdentifier,
@PathVariable("callendpointsetidentifier") String callEndpointSetIdentifier);

@RequestMapping(value = "/applications/{applicationidentifier}/permissions/{permissionidentifier}/users/{useridentifier}/enabled", method = RequestMethod.PUT,
consumes = {MediaType.APPLICATION_JSON_VALUE},
produces = {MediaType.ALL_VALUE})
@@ -17,6 +17,8 @@

import org.hibernate.validator.constraints.NotBlank;

import javax.annotation.Nullable;
import javax.validation.constraints.Null;
import java.util.Objects;

/**
@@ -38,8 +40,9 @@ public class Authentication {

/**
* If password expiration is in the past, then the tokens provided only allow the user to change his/her password.
* If password expiration is null then password will never expire.
*/
@NotBlank
@Nullable
private String passwordExpiration;

public Authentication()
@@ -0,0 +1,75 @@
/*
* Copyright 2017 The Mifos Initiative.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.mifos.identity.api.v1.domain;

import io.mifos.core.lang.validation.constraints.ValidIdentifier;

import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Objects;

/**
* @author Myrle Krantz
*/
@SuppressWarnings({"unused", "WeakerAccess"})
public class CallEndpointSet {
@ValidIdentifier
private String identifier;

@NotNull
private List<String> permittableEndpointGroupIdentifiers;

public CallEndpointSet() {
}

public String getIdentifier() {
return identifier;
}

public void setIdentifier(String identifier) {
this.identifier = identifier;
}

public List<String> getPermittableEndpointGroupIdentifiers() {
return permittableEndpointGroupIdentifiers;
}

public void setPermittableEndpointGroupIdentifiers(List<String> permittableEndpointGroupIdentifiers) {
this.permittableEndpointGroupIdentifiers = permittableEndpointGroupIdentifiers;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CallEndpointSet that = (CallEndpointSet) o;
return Objects.equals(identifier, that.identifier) &&
Objects.equals(permittableEndpointGroupIdentifiers, that.permittableEndpointGroupIdentifiers);
}

@Override
public int hashCode() {
return Objects.hash(identifier, permittableEndpointGroupIdentifiers);
}

@Override
public String toString() {
return "CallEndpointSet{" +
"identifier='" + identifier + '\'' +
", permittableEndpointGroupIdentifiers=" + permittableEndpointGroupIdentifiers +
'}';
}
}
@@ -16,6 +16,7 @@
package io.mifos.identity.api.v1.domain;

import io.mifos.core.lang.validation.constraints.ValidIdentifier;
import io.mifos.identity.api.v1.validation.ChangeableRole;
import org.hibernate.validator.constraints.ScriptAssert;
import org.springframework.util.Assert;

@@ -29,9 +30,9 @@
* @author Myrle Krantz
*/
@SuppressWarnings("unused")
@ScriptAssert(lang = "javascript", script = "_this.identifier !== \"deactivated\"")
public class Role {
@ValidIdentifier
@ChangeableRole
private String identifier;

@NotNull
@@ -15,6 +15,7 @@
*/
package io.mifos.identity.api.v1.domain;

import io.mifos.identity.api.v1.validation.NotRootRole;
import org.hibernate.validator.constraints.NotBlank;

import java.util.Objects;
@@ -25,6 +26,7 @@
@SuppressWarnings({"unused", "WeakerAccess"})
public class RoleIdentifier {
@NotBlank
@NotRootRole
private String identifier;

public RoleIdentifier() {
@@ -0,0 +1,73 @@
/*
* Copyright 2017 The Mifos Initiative.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.mifos.identity.api.v1.events;

import java.util.Objects;

/**
* @author Myrle Krantz
*/
@SuppressWarnings({"WeakerAccess", "unused"})
public class ApplicationCallEndpointSetEvent {
private String applicationIdentifier;
private String callEndpointSetIdentifier;

public ApplicationCallEndpointSetEvent() {
}

public ApplicationCallEndpointSetEvent(String applicationIdentifier, String callEndpointSetIdentifier) {
this.applicationIdentifier = applicationIdentifier;
this.callEndpointSetIdentifier = callEndpointSetIdentifier;
}

public String getApplicationIdentifier() {
return applicationIdentifier;
}

public void setApplicationIdentifier(String applicationIdentifier) {
this.applicationIdentifier = applicationIdentifier;
}

public String getCallEndpointSetIdentifier() {
return callEndpointSetIdentifier;
}

public void setCallEndpointSetIdentifier(String callEndpointSetIdentifier) {
this.callEndpointSetIdentifier = callEndpointSetIdentifier;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ApplicationCallEndpointSetEvent that = (ApplicationCallEndpointSetEvent) o;
return Objects.equals(applicationIdentifier, that.applicationIdentifier) &&
Objects.equals(callEndpointSetIdentifier, that.callEndpointSetIdentifier);
}

@Override
public int hashCode() {
return Objects.hash(applicationIdentifier, callEndpointSetIdentifier);
}

@Override
public String toString() {
return "ApplicationCallEndpointSetEvent{" +
"applicationIdentifier='" + applicationIdentifier + '\'' +
", callEndpointSetIdentifier='" + callEndpointSetIdentifier + '\'' +
'}';
}
}
@@ -38,6 +38,9 @@ public interface EventConstants {

String OPERATION_PUT_APPLICATION_SIGNATURE = "put-application-signature";
String OPERATION_DELETE_APPLICATION = "delete-application";
String OPERATION_POST_APPLICATION_CALLENDPOINTSET = "post-application-callendpointset";
String OPERATION_PUT_APPLICATION_CALLENDPOINTSET = "put-application-callendpointset";
String OPERATION_DELETE_APPLICATION_CALLENDPOINTSET = "delete-application-callendpointset";
String OPERATION_POST_APPLICATION_PERMISSION = "post-application-permission";
String OPERATION_DELETE_APPLICATION_PERMISSION = "delete-application-permission";
String OPERATION_PUT_APPLICATION_PERMISSION_USER_ENABLED = "put-application-permission-user-enabled";
@@ -56,6 +59,9 @@ public interface EventConstants {

String SELECTOR_PUT_APPLICATION_SIGNATURE = OPERATION_HEADER + " = '" + OPERATION_PUT_APPLICATION_SIGNATURE + "'";
String SELECTOR_DELETE_APPLICATION = OPERATION_HEADER + " = '" + OPERATION_DELETE_APPLICATION + "'";
String SELECTOR_POST_APPLICATION_CALLENDPOINTSET = OPERATION_HEADER + " = '" + OPERATION_POST_APPLICATION_CALLENDPOINTSET + "'";
String SELECTOR_PUT_APPLICATION_CALLENDPOINTSET = OPERATION_HEADER + " = '" + OPERATION_PUT_APPLICATION_CALLENDPOINTSET + "'";
String SELECTOR_DELETE_APPLICATION_CALLENDPOINTSET = OPERATION_HEADER + " = '" + OPERATION_DELETE_APPLICATION_CALLENDPOINTSET + "'";
String SELECTOR_POST_APPLICATION_PERMISSION = OPERATION_HEADER + " = '" + OPERATION_POST_APPLICATION_PERMISSION + "'";
String SELECTOR_DELETE_APPLICATION_PERMISSION = OPERATION_HEADER + " = '" + OPERATION_DELETE_APPLICATION_PERMISSION + "'";
String SELECTOR_PUT_APPLICATION_PERMISSION_USER_ENABLED = OPERATION_HEADER + " = '" + OPERATION_PUT_APPLICATION_PERMISSION_USER_ENABLED + "'";
@@ -0,0 +1,38 @@
/*
* Copyright 2017 The Mifos Initiative.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.mifos.identity.api.v1.validation;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

/**
* @author Myrle Krantz
*/
@SuppressWarnings({"unused", "WeakerAccess"})
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
validatedBy = {CheckRoleChangeable.class}
)
public @interface ChangeableRole {
String message() default "The role 'pharaoh' cannot be changed or deleted.";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};
}
@@ -0,0 +1,34 @@
/*
* Copyright 2017 The Mifos Initiative.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.mifos.identity.api.v1.validation;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

/**
* @author Myrle Krantz
*/
public class CheckNotRootRole implements ConstraintValidator<NotRootRole, String> {
@Override
public void initialize(final NotRootRole constraintAnnotation) {

}

@Override
public boolean isValid(final String value, final ConstraintValidatorContext context) {
return !value.equals("pharaoh");
}
}
@@ -0,0 +1,39 @@
/*
* Copyright 2017 The Mifos Initiative.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.mifos.identity.api.v1.validation;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

/**
* @author Myrle Krantz
*/
@SuppressWarnings("WeakerAccess")
public class CheckRoleChangeable implements ConstraintValidator<ChangeableRole, String> {
@Override
public void initialize(final ChangeableRole constraintAnnotation) {

}

@Override
public boolean isValid(final String value, final ConstraintValidatorContext context) {
return isChangeableRoleIdentifier(value);
}

public static boolean isChangeableRoleIdentifier(final String value) {
return !value.equals("pharaoh") && !value.equals("deactivated");
}
}

0 comments on commit f6e4927

Please sign in to comment.