Skip to content
This repository was archived by the owner on May 22, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ Some special features:
- Implementations with and without restrictions
- BasicScope (no restrictions)
- MicroServiceScope
- microService.topic.mode.scope.extra
- microService.topic.mode.limitation.extra
- Merging (and de-merging)
- user.email.read+write+delete.all+beta
- Pre-defined scopes
- Pre-defined limitations
- none (default)
- own
- self (only applicable to topics regarding a user itself)
Expand Down
12 changes: 12 additions & 0 deletions scope/src/main/java/com/gewia/common/scope/Scope.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,18 @@ public Scope addScopePart(String scopePart) {
*/
public abstract Scope addScopePart(ScopePart scopePart);

/**
* Adds the given <i>scopePart</i> at the given <i>index</i>.
*
* @param scopePart the scope part to add
* @param index the index to add the scope part at
*
* @return this
*
* @since 1.0
*/
public abstract Scope setScopePart(ScopePart scopePart, int index);

/**
* Removes the scope part at the given <i>index</i>.
*
Expand Down
28 changes: 27 additions & 1 deletion scope/src/main/java/com/gewia/common/scope/impl/BasicScope.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
*
* @since 1.0
*/
@RequiredArgsConstructor(access = AccessLevel.MODULE)
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
public class BasicScope extends Scope {

/**
Expand Down Expand Up @@ -52,5 +52,31 @@ public int getScopePartsSize() {
return this.scopeParts.size();
}

@Override
public Scope setScopePart(ScopePart scopePart, int index) {
this.scopeParts.set(index, scopePart);
return this;
}

@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj == null) return false;
if (!(obj instanceof Scope)) return false;

Scope scope = (Scope) obj;
List<ScopePart> parts = scope.getScopeParts();
for (int i = 0, partsSize = parts.size(); i < partsSize; i++) {
ScopePart scopePart = parts.get(i);
if (!scopePart.equals(this.getScopePart(i))) return false;
}

return true;
}

@Override
public int hashCode() {
return super.hashCode();
}

}
106 changes: 106 additions & 0 deletions scope/src/main/java/com/gewia/common/scope/impl/MicroServiceScope.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.gewia.common.scope.impl;

import com.gewia.common.scope.Scope;
import com.gewia.common.scope.ScopePart;
import com.gewia.common.scope.impl.util.Limitation;
import com.gewia.common.scope.impl.util.Mode;
import java.util.Collections;
import java.util.List;

/**
* MicroServiceScope is specified by the following schema: 'microService.topic.mode.limitation.(extra)' .
* Example: user.user.write.all - lets the given application/user write/create <i>all</i> users.
*/
public class MicroServiceScope extends BasicScope {

public MicroServiceScope(ScopePart microService, ScopePart topic, Mode mode, Limitation limitation, ScopePart... extra) {
super();

this.addScopePart(microService);
this.addScopePart(topic);
this.addScopePart(mode.getScopePart());
this.addScopePart(limitation.getScopePart());

for (ScopePart scopePart : extra) this.addScopePart(scopePart);
}

@Override
public Scope removeScopePart(int index) {
if (index <= 3) throw new UnsupportedOperationException("MicroServiceScopes have to fit the schema.");
return super.removeScopePart(index);
}

/**
* Gets the currently available scope parts.
*
* <p>
* The returned list is an unmodifiable list, because of the restrictions of {@link MicroServiceScope}.
* </p>
*
* @return all scope parts
*
* @since 1.0
*/
@Override
public List<ScopePart> getScopeParts() {
return Collections.unmodifiableList(super.getScopeParts());
}


/**
* Adds the given <i>scopePart</i> at the given <i>index</i>.
*
* @param scopePart the scope part to add
* @param index the index to add the scope part at
*
* @return this
*
* @throws IllegalArgumentException if the schema isn't fulfilled (e.g. invalid mode or limitation)
*
* @since 1.0
*/
@Override
public Scope setScopePart(ScopePart scopePart, int index) {
if (index == 2 && !Mode.isMode(scopePart)) throw new IllegalArgumentException("Third index has to be a valid mode.");
if (index == 3 && !Limitation.isLimitation(scopePart)) throw new IllegalArgumentException("Fourth index has to be a valid limitation");

return this.setScopePart(scopePart, index);
}

public ScopePart getMicroService() {
return this.getScopePart(0);
}

public ScopePart getTopic() {
return this.getScopePart(1);
}

public Mode getMode() {
return Mode.find(this.getScopePart(2).getContent());
}

public Limitation getLimitation() {
return Limitation.find(this.getScopePart(3).getContent());
}

public MicroServiceScope setMicroService(ScopePart microService) {
this.setScopePart(microService, 0);
return this;
}

public MicroServiceScope setTopic(ScopePart topic) {
this.setScopePart(topic, 1);
return this;
}

public MicroServiceScope setMode(Mode mode) {
this.setScopePart(mode.getScopePart(), 2);
return this;
}

public MicroServiceScope setLimitation(Limitation limitation) {
this.setScopePart(limitation.getScopePart(), 3);
return this;
}

}
43 changes: 41 additions & 2 deletions scope/src/main/java/com/gewia/common/scope/impl/ScopeFactory.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,57 @@
package com.gewia.common.scope.impl;

import com.gewia.common.scope.Scope;
import com.gewia.common.scope.ScopePart;
import com.gewia.common.scope.impl.util.Limitation;
import com.gewia.common.scope.impl.util.Mode;

public class ScopeFactory {

/**
* Creates a {@link BasicScope} with not further restrictions.
* Creates a {@link BasicScope} with no further restrictions.
*
* @return a {@link BasicScope}
* @return a new {@link BasicScope}
*
* @since 1.0
*/
public static Scope createBasicScope() {
return new BasicScope();
}

/**
* Creates a {@link MicroServiceScope} with it's specified restrictions.
*
* @param microService the micro service the scope belongs to
* @param topic the topic of the scope
* @param mode the mode of the scope
* @param limitation the limitation of the scope
* @param extra extra information
*
* @return a new {@link MicroServiceScope}
*
* @see MicroServiceScope
* @since 1.0
*/
public static MicroServiceScope createMicroServiceScope(String microService, String topic, Mode mode, Limitation limitation, ScopePart... extra) {
return createMicroServiceScope(new ScopePart(microService), new ScopePart(topic), mode, limitation, extra);
}

/**
* Creates a {@link MicroServiceScope} with it's specified restrictions.
*
* @param microService the micro service the scope belongs to
* @param topic the topic of the scope
* @param mode the mode of the scope
* @param limitation the limitation of the scope
* @param extra extra information
*
* @return a new {@link MicroServiceScope}
*
* @see MicroServiceScope
* @since 1.0
*/
public static MicroServiceScope createMicroServiceScope(ScopePart microService, ScopePart topic, Mode mode, Limitation limitation, ScopePart... extra) {
return new MicroServiceScope(microService, topic, mode, limitation, extra);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.gewia.common.scope.impl.util;

import com.gewia.common.scope.ScopePart;
import lombok.Getter;

public enum Limitation {

NONE,
OWN,
SELF,
ALL,
BETA;

private static final Limitation[] VALUES = Limitation.values(); // #values() always creates a new copy of the array

@Getter private final ScopePart scopePart = new ScopePart(this.name().toLowerCase());

public static Limitation find(String name) {
for (Limitation limitation : VALUES)
if (limitation.name().equalsIgnoreCase(name)) return limitation;

return null;
}

public static boolean isLimitation(ScopePart scopePart) {
return find(scopePart.getContent()) != null;
}

}
27 changes: 27 additions & 0 deletions scope/src/main/java/com/gewia/common/scope/impl/util/Mode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.gewia.common.scope.impl.util;

import com.gewia.common.scope.ScopePart;
import lombok.Getter;

public enum Mode {

READ,
WRITE,
DELETE;

private static final Mode[] VALUES = Mode.values(); // #values() always creates a new copy of the array

@Getter private final ScopePart scopePart = new ScopePart(this.name().toLowerCase());

public static Mode find(String name) {
for (Mode mode : VALUES)
if (mode.name().equalsIgnoreCase(name)) return mode;

return null;
}

public static boolean isMode(ScopePart scopePart) {
return find(scopePart.getContent()) != null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ public void basicCreateAndReadAndDeleteTest() {
Assert.assertEquals("Scope parts size not zero", 0, scope.getScopePartsSize());
Assert.assertEquals("Output not empty", 0, scope.toString().length());

scope.addScopeParts("user", "email", "read");

Assert.assertEquals(
"Returned scope not the same",
"Scope does not fulfill expectation",
scope,
scope.addScopeParts("user", "email", "read")
ScopeFactory.createBasicScope().addScopeParts("user", "email", "read")
);

Assert.assertEquals("Scope output doesn't match", "user.email.read", scope.toString());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.gewia.common.scope.test;

import com.gewia.common.scope.impl.ScopeFactory;
import com.gewia.common.scope.impl.MicroServiceScope;
import com.gewia.common.scope.impl.util.Limitation;
import com.gewia.common.scope.impl.util.Mode;
import org.junit.Assert;
import org.junit.Test;

public class MicroServiceScopeTest {

@Test
public void microServiceCreateAndReadAndDeleteTest() {
MicroServiceScope scope = ScopeFactory.createMicroServiceScope(
"testMicroService",
"test",
Mode.WRITE,
Limitation.ALL
);

Assert.assertFalse("Scope parts empty", scope.getScopeParts().isEmpty());
Assert.assertEquals("Scope parts size not zero", 4, scope.getScopePartsSize());

Assert.assertEquals(
"Scope does not fulfill expectation",
scope,
ScopeFactory.createBasicScope().addScopeParts("testMicroService", "test", "write", "all")
);

Assert.assertEquals("Scope output doesn't match", "testMicroService.test.write.all", scope.toString());
Assert.assertEquals("Scope parts do not match size (list access)", 4, scope.getScopeParts().size());
Assert.assertEquals("Scope parts do not match size", 4, scope.getScopePartsSize());

Assert.assertThrows("Scope didn't catch out of bound remove", IndexOutOfBoundsException.class,() -> scope.removeScopePart(4));

for (int index = 0; index < 3; index++) {
int finalIndex = index;
Assert.assertThrows("Scope didn't catch not schema-compliant remove", UnsupportedOperationException.class,() -> scope.removeScopePart(finalIndex));
}

Assert.assertEquals("Scope output doesn't match", "testMicroService.test.write.all", scope.toString());
Assert.assertEquals("Scope parts do not match size (list access)", 4, scope.getScopeParts().size());
Assert.assertEquals("Scope parts do not match size", 4, scope.getScopePartsSize());
}

}