use of io.helidon.security.SecurityLevel in project helidon by oracle.
the class ScopeValidatorTest method testScopesOrPermit.
@Test
public void testScopesOrPermit() {
ScopeValidator validator = ScopeValidator.builder().useOrOperator(true).build();
ScopeValidator.Scope annot = mock(ScopeValidator.Scope.class);
when(annot.value()).thenReturn("calendar_get");
ScopeValidator.Scope annotTwo = mock(ScopeValidator.Scope.class);
when(annotTwo.value()).thenReturn("calendar_update");
ScopeValidator.Scopes scopes = mock(ScopeValidator.Scopes.class);
when(scopes.value()).thenReturn(new ScopeValidator.Scope[] { annot, annotTwo });
SecurityLevel appSecurityLevel = mock(SecurityLevel.class);
SecurityLevel classSecurityLevel = mock(SecurityLevel.class);
List<SecurityLevel> securityLevels = new ArrayList<>();
securityLevels.add(appSecurityLevel);
securityLevels.add(classSecurityLevel);
EndpointConfig ep = mock(EndpointConfig.class);
when(ep.securityLevels()).thenReturn(securityLevels);
when(classSecurityLevel.filterAnnotations(ScopeValidator.Scopes.class, EndpointConfig.AnnotationScope.METHOD)).thenReturn(List.of(scopes));
ScopeValidator.ScopesConfig sConfig = validator.fromAnnotations(ep);
Errors.Collector collector = Errors.collector();
ProviderRequest request = mock(ProviderRequest.class);
when(request.subject()).thenReturn(Optional.of(Subject.builder().principal(Principal.create("myAdmin")).addGrant(Grant.builder().type("scope").name("calendar_get").build()).build()));
when(request.service()).thenReturn(Optional.empty());
validator.validate(sConfig, collector, request);
collector.collect().checkValid();
}
use of io.helidon.security.SecurityLevel in project helidon by oracle.
the class ScopeValidatorTest method testScopesAndPermit.
@Test
public void testScopesAndPermit() {
ScopeValidator validator = ScopeValidator.create();
ScopeValidator.Scope annot = mock(ScopeValidator.Scope.class);
when(annot.value()).thenReturn("calendar_get");
ScopeValidator.Scope annotTwo = mock(ScopeValidator.Scope.class);
when(annotTwo.value()).thenReturn("calendar_update");
ScopeValidator.Scopes scopes = mock(ScopeValidator.Scopes.class);
when(scopes.value()).thenReturn(new ScopeValidator.Scope[] { annot, annotTwo });
SecurityLevel appSecurityLevel = mock(SecurityLevel.class);
SecurityLevel classSecurityLevel = mock(SecurityLevel.class);
List<SecurityLevel> securityLevels = new ArrayList<>();
securityLevels.add(appSecurityLevel);
securityLevels.add(classSecurityLevel);
EndpointConfig ep = mock(EndpointConfig.class);
when(ep.securityLevels()).thenReturn(securityLevels);
when(classSecurityLevel.filterAnnotations(ScopeValidator.Scopes.class, EndpointConfig.AnnotationScope.METHOD)).thenReturn(List.of(scopes));
ScopeValidator.ScopesConfig sConfig = validator.fromAnnotations(ep);
Errors.Collector collector = Errors.collector();
ProviderRequest request = mock(ProviderRequest.class);
when(request.subject()).thenReturn(Optional.of(Subject.builder().principal(Principal.create("myAdmin")).addGrant(Grant.builder().type("scope").name("calendar_get").build()).addGrant(Grant.builder().type("scope").name("calendar_update").build()).build()));
when(request.service()).thenReturn(Optional.empty());
validator.validate(sConfig, collector, request);
collector.collect().checkValid();
}
use of io.helidon.security.SecurityLevel in project helidon by oracle.
the class ScopeValidatorTest method testScopesOrDeny.
@Test
public void testScopesOrDeny() {
ScopeValidator validator = ScopeValidator.builder().useOrOperator(true).build();
ScopeValidator.Scope annot = mock(ScopeValidator.Scope.class);
when(annot.value()).thenReturn("calendar_get");
ScopeValidator.Scope annotTwo = mock(ScopeValidator.Scope.class);
when(annotTwo.value()).thenReturn("calendar_update");
ScopeValidator.Scopes scopes = mock(ScopeValidator.Scopes.class);
when(scopes.value()).thenReturn(new ScopeValidator.Scope[] { annot, annotTwo });
SecurityLevel appSecurityLevel = mock(SecurityLevel.class);
SecurityLevel classSecurityLevel = mock(SecurityLevel.class);
List<SecurityLevel> securityLevels = new ArrayList<>();
securityLevels.add(appSecurityLevel);
securityLevels.add(classSecurityLevel);
EndpointConfig ep = mock(EndpointConfig.class);
when(ep.securityLevels()).thenReturn(securityLevels);
when(classSecurityLevel.filterAnnotations(ScopeValidator.Scopes.class, EndpointConfig.AnnotationScope.METHOD)).thenReturn(List.of(scopes));
ScopeValidator.ScopesConfig sConfig = validator.fromAnnotations(ep);
Errors.Collector collector = Errors.collector();
ProviderRequest request = mock(ProviderRequest.class);
when(request.subject()).thenReturn(Optional.of(Subject.builder().principal(Principal.create("myAdmin")).addGrant(Grant.builder().type("scope").name("calendar_other").build()).build()));
when(request.service()).thenReturn(Optional.empty());
validator.validate(sConfig, collector, request);
if (collector.collect().isValid()) {
fail("User does not have any of the required scopes, should have failed");
}
}
use of io.helidon.security.SecurityLevel in project helidon by oracle.
the class TimeValidator method fromAnnotations.
@Override
public TimeConfig fromAnnotations(EndpointConfig endpointConfig) {
TimeConfig.Builder builder = TimeConfig.builder();
for (SecurityLevel securityLevel : endpointConfig.securityLevels()) {
for (EndpointConfig.AnnotationScope scope : EndpointConfig.AnnotationScope.values()) {
List<Annotation> annotations = new ArrayList<>();
for (Class<? extends Annotation> annotation : supportedAnnotations()) {
annotations.addAll(securityLevel.filterAnnotations(annotation, scope));
}
for (Annotation annotation : annotations) {
if (annotation instanceof DaysOfWeek) {
DaysOfWeek daw = (DaysOfWeek) annotation;
for (DayOfWeek dayOfWeek : daw.value()) {
builder.addDaysOfWeek(dayOfWeek);
}
} else if (annotation instanceof TimesOfDay) {
TimesOfDay tods = (TimesOfDay) annotation;
for (TimeOfDay tod : tods.value()) {
builder.addBetween(LocalTime.parse(tod.from()), LocalTime.parse(tod.to()));
}
} else if (annotation instanceof TimeOfDay) {
TimeOfDay tod = (TimeOfDay) annotation;
builder.addBetween(LocalTime.parse(tod.from()), LocalTime.parse(tod.to()));
}
}
}
}
return builder.build();
}
use of io.helidon.security.SecurityLevel in project helidon by oracle.
the class SecurityFilter method getMethodSecurity.
private SecurityDefinition getMethodSecurity(InvokedResource invokedResource, Method definitionMethod, ExtendedUriInfo uriInfo) {
// Check cache
// Jersey model 'definition method' is the method that contains JAX-RS/Jersey annotations. JAX-RS does not support
// merging annotations from a parent, so we don't have to look for annotations on corresponding methods of interfaces
// and abstract classes implemented by the definition method.
// Jersey model does not have a 'definition class', so we have to find it from a handler class
Class<?> obtainedClass = invokedResource.definitionClass().orElseThrow(() -> new SecurityException("Got definition method, cannot get definition class"));
Class<?> definitionClass = getRealClass(obtainedClass);
// Get the application for this request in case there's more than one
Application appInstance = serverRequest.context().get(Application.class).get();
// Create and cache security definition for application
Class<?> appRealClass = getRealClass(appInstance.getClass());
SecurityDefinition appClassSecurity = appClassSecurity(appRealClass);
if (definitionClass.getAnnotation(Path.class) == null) {
// this is a sub-resource
// I must locate the resource class and method that was invoked
PathVisitor visitor = new PathVisitor();
visitor.visit(uriInfo.getMatchedRuntimeResources());
Collections.reverse(visitor.list);
StringBuilder fullPathBuilder = new StringBuilder();
List<Method> methodsToProcess = new LinkedList<>();
for (Invocable m : visitor.list) {
// first the top most class (MpMainResource.sub())
// then the one under it (MpSubResource.sub())
// these methods are above our sub resource
Method parentDefMethod = m.getDefinitionMethod();
Class<?> parentClass = parentDefMethod.getDeclaringClass();
fullPathBuilder.append("/").append(parentClass.getName()).append(".").append(parentDefMethod.getName());
methodsToProcess.add(parentDefMethod);
}
fullPathBuilder.append("/").append(definitionClass.getName()).append(".").append(definitionMethod.getName());
methodsToProcess.add(definitionMethod);
String fullPath = fullPathBuilder.toString();
// now full path can be used as a cache
if (subResourceMethodSecurity(appRealClass).containsKey(fullPath)) {
return subResourceMethodSecurity(appRealClass).get(fullPath);
}
// now process each definition method and class
SecurityDefinition current = appClassSecurity;
for (Method method : methodsToProcess) {
Class<?> clazz = method.getDeclaringClass();
current = securityForClass(clazz, current);
Authenticated atn = method.getAnnotation(Authenticated.class);
Authorized atz = method.getAnnotation(Authorized.class);
Audited audited = method.getAnnotation(Audited.class);
SecurityDefinition methodDef = current.copyMe();
methodDef.add(atn);
methodDef.add(atz);
methodDef.add(audited);
SecurityLevel currentSecurityLevel = methodDef.getSecurityLevels().get(methodDef.getSecurityLevels().size() - 1);
Map<Class<? extends Annotation>, List<Annotation>> methodAnnotations = new HashMap<>();
addCustomAnnotations(methodAnnotations, method);
SecurityLevel newSecurityLevel = SecurityLevel.create(currentSecurityLevel).withMethodName(method.getName()).withMethodAnnotations(methodAnnotations).build();
methodDef.getSecurityLevels().set(methodDef.getSecurityLevels().size() - 1, newSecurityLevel);
for (AnnotationAnalyzer analyzer : analyzers) {
AnnotationAnalyzer.AnalyzerResponse analyzerResponse = analyzer.analyze(method, current.analyzerResponse(analyzer));
methodDef.analyzerResponse(analyzer, analyzerResponse);
}
current = methodDef;
}
subResourceMethodSecurity(appRealClass).put(fullPath, current);
return current;
}
if (resourceMethodSecurity(appRealClass).containsKey(definitionMethod)) {
return resourceMethodSecurity(appRealClass).get(definitionMethod);
}
SecurityDefinition resClassSecurity = resourceClassSecurity(appRealClass).computeIfAbsent(definitionClass, aClass -> securityForClass(definitionClass, appClassSecurity));
Authenticated atn = definitionMethod.getAnnotation(Authenticated.class);
Authorized atz = definitionMethod.getAnnotation(Authorized.class);
Audited audited = definitionMethod.getAnnotation(Audited.class);
SecurityDefinition methodDef = resClassSecurity.copyMe();
methodDef.add(atn);
methodDef.add(atz);
methodDef.add(audited);
int index = methodDef.getSecurityLevels().size() - 1;
SecurityLevel currentSecurityLevel = methodDef.getSecurityLevels().get(index);
Map<Class<? extends Annotation>, List<Annotation>> methodLevelAnnots = new HashMap<>();
addCustomAnnotations(methodLevelAnnots, definitionMethod);
methodDef.getSecurityLevels().set(index, SecurityLevel.create(currentSecurityLevel).withMethodName(definitionMethod.getName()).withMethodAnnotations(methodLevelAnnots).build());
resourceMethodSecurity(appRealClass).put(definitionMethod, methodDef);
for (AnnotationAnalyzer analyzer : analyzers) {
AnnotationAnalyzer.AnalyzerResponse analyzerResponse = analyzer.analyze(definitionMethod, resClassSecurity.analyzerResponse(analyzer));
methodDef.analyzerResponse(analyzer, analyzerResponse);
}
return methodDef;
}
Aggregations