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

feat(config-api): audit log, agama ADS spec, fix for 0 index search #3369

Merged
merged 11 commits into from
Dec 20, 2022
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
Original file line number Diff line number Diff line change
Expand Up @@ -1459,6 +1459,14 @@ public void setBackchannelUserCodeParameter(Boolean backchannelUserCodeParameter
this.backchannelUserCodeParameter = backchannelUserCodeParameter;
}

public String getDisplayName() {
return getClientName();
}

public void setDisplayName(String displayName) {
setClientName(displayName);
}

public String getDescription() {
return description;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public class ApiAppConfiguration implements Configuration {
private List<String> userExclusionAttributes;
private List<String> userMandatoryAttributes;
private AgamaConfiguration agamaConfiguration;
private AuditLogConf auditLogConf;

public boolean isConfigOauthEnabled() {
return configOauthEnabled;
Expand Down Expand Up @@ -230,6 +231,14 @@ public AgamaConfiguration getAgamaConfiguration() {
public void setAgamaConfiguration(AgamaConfiguration agamaConfiguration) {
this.agamaConfiguration = agamaConfiguration;
}

public AuditLogConf getAuditLogConf() {
return auditLogConf;
}

public void setAuditLogConf(AuditLogConf auditLogConf) {
this.auditLogConf = auditLogConf;
}

@Override
public String toString() {
Expand All @@ -246,6 +255,7 @@ public String toString() {
+ " , userExclusionAttributes="+ userExclusionAttributes
+ " , userMandatoryAttributes="+ userMandatoryAttributes
+ " , agamaConfiguration="+ agamaConfiguration
+ " , auditLogConf="+ auditLogConf
+ "]";
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package io.jans.configapi.model.configuration;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.util.List;

@JsonIgnoreProperties(ignoreUnknown = true)
public class AuditLogConf {

/**
* Flag to enable and disable audit log
*/
private boolean enabled;

/**
* List of header attributes
*/
private List<String> headerAttributes;

public boolean isEnabled() {
return enabled;
}

public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

public List<String> getHeaderAttributes() {
return headerAttributes;
}

public void setHeaderAttributes(List<String> headerAttributes) {
this.headerAttributes = headerAttributes;
}

@Override
public String toString() {
return "AuditLogConf [enabled=" + enabled + ", headerAttributes=" + headerAttributes + "]";
}

}
79 changes: 56 additions & 23 deletions jans-config-api/docs/jans-config-api-swagger-auto.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,8 @@ paths:
description: InternalServerError
security:
- oauth2:
- https://jans.io/oauth/config/agama.readonly
- https://jans.io/oauth/config/agama.write
- https://jans.io/oauth/config/read-all
- https://jans.io/oauth/config/write-all
delete:
tags:
- Agama - Developer Studio
Expand All @@ -212,9 +211,7 @@ paths:
description: InternalServerError
security:
- oauth2:
- https://jans.io/oauth/config/agama.readonly
- https://jans.io/oauth/config/agama.write
- https://jans.io/oauth/config/read-all
- https://jans.io/oauth/config/agama.delete
/api/v1/ads-deployment/list:
get:
tags:
Expand Down Expand Up @@ -612,6 +609,40 @@ paths:
security:
- oauth2:
- https://jans.io/oauth/config/agama.write
/api/v1/agama/syntax-check/{qname}:
post:
tags:
- Agama - Configuration
summary: Determine if the text passed is valid Agama code
description: Determine if the text passed is valid Agama code
operationId: agama-syntax-check
parameters:
- name: qname
in: path
required: true
schema:
type: string
requestBody:
content:
text/plain:
schema:
type: string
responses:
"200":
description: Agama Syntax Check message
content:
application/json:
schema:
type: string
"401":
description: Unauthorized
"500":
description: InternalServerError
security:
- oauth2:
- https://jans.io/oauth/config/agama.readonly
- https://jans.io/oauth/config/agama.write
- https://jans.io/oauth/config/read-all
/api/v1/agama/source/{qname}:
put:
tags:
Expand Down Expand Up @@ -7268,18 +7299,18 @@ components:
type: string
whitePagesCanView:
type: boolean
userCanView:
adminCanEdit:
type: boolean
userCanAccess:
adminCanAccess:
type: boolean
userCanEdit:
type: boolean
adminCanAccess:
type: boolean
adminCanEdit:
userCanView:
type: boolean
adminCanView:
type: boolean
userCanAccess:
type: boolean
baseDn:
type: string
PatchRequest:
Expand Down Expand Up @@ -7614,6 +7645,8 @@ components:
ttl:
type: integer
format: int32
displayName:
type: string
authenticationMethod:
type: string
enum:
Expand Down Expand Up @@ -8437,6 +8470,17 @@ components:
$ref: '#/components/schemas/SsaConfiguration'
blockWebviewAuthorizationEnabled:
type: boolean
fapi:
type: boolean
allResponseTypesSupported:
uniqueItems: true
type: array
items:
type: string
enum:
- code
- token
- id_token
enabledFeatureFlags:
uniqueItems: true
type: array
Expand Down Expand Up @@ -8464,17 +8508,6 @@ components:
- STAT
- PAR
- SSA
allResponseTypesSupported:
uniqueItems: true
type: array
items:
type: string
enum:
- code
- token
- id_token
fapi:
type: boolean
AuthenticationFilter:
required:
- baseDn
Expand Down Expand Up @@ -8768,13 +8801,13 @@ components:
type: boolean
internal:
type: boolean
locationPath:
type: string
locationType:
type: string
enum:
- ldap
- file
locationPath:
type: string
baseDn:
type: string
ScriptError:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,7 @@ public String getPeopleBaseDn() {
}

public PagedResult<User> searchUsers(SearchRequest searchRequest) {
if (logger.isDebugEnabled()) {
logger.debug("Search Users with searchRequest:{}", escapeLog(searchRequest));
}

logger.debug("Search Users with searchRequest:{}", escapeLog(searchRequest));
Filter searchFilter = null;
List<Filter> filters = new ArrayList<>();
if (searchRequest.getFilterAssertionValue() != null && !searchRequest.getFilterAssertionValue().isEmpty()) {
Expand All @@ -87,7 +84,7 @@ public PagedResult<User> searchUsers(SearchRequest searchRequest) {
}
searchFilter = Filter.createORFilter(filters);
}

logger.debug("Users searchFilter:{}", searchFilter);
return persistenceEntryManager.findPagedEntries(getPeopleBaseDn(), User.class, searchFilter, null,
searchRequest.getSortBy(), SortOrder.getByValue(searchRequest.getSortOrder()),
searchRequest.getStartIndex(), searchRequest.getCount(), searchRequest.getMaxCount());
Expand Down
4 changes: 2 additions & 2 deletions jans-config-api/profiles/local/test.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ test.scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/con
# jans.server
token.endpoint=https://jans.server1/jans-auth/restv1/token
token.grant.type=client_credentials
test.client.id=1800.5957dfad-b2cb-4764-85fe-841e6bc870ff
test.client.secret=ozu4fjIzoEbe
test.client.id=1800.c94f1e10-7716-4dc8-b82d-4dd1169ed4f9
test.client.secret=2M6r3vYeQEIT
test.issuer=https://jans.server1/
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.
*
* Copyright (c) 2020, Janssen Project
*/

package io.jans.configapi.interceptor;

import io.jans.configapi.core.interceptor.RequestAuditInterceptor;
import io.jans.configapi.model.configuration.AuditLogConf;
import io.jans.configapi.util.AuthUtil;
import jakarta.annotation.Priority;
import jakarta.inject.Inject;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.UriInfo;

import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jakarta.interceptor.AroundInvoke;
import jakarta.interceptor.Interceptor;
import jakarta.interceptor.InvocationContext;

@Interceptor
@RequestAuditInterceptor
@Priority(Interceptor.Priority.APPLICATION)
public class AuditLogInterceptor {

private static final Logger AUDIT_LOG = LoggerFactory.getLogger("audit");

@Context
UriInfo info;

@Context
HttpServletRequest request;

@Context
private HttpHeaders httpHeaders;

@Inject
AuthUtil authUtil;

@SuppressWarnings({ "all" })
@AroundInvoke
public Object aroundReadFrom(InvocationContext context) throws Exception {

try {
processRequest(context);

} catch (Exception ex) {
throw new WebApplicationException(ex);
}
return context.proceed();
}

private void processRequest(InvocationContext context) {

Object[] ctxParameters = context.getParameters();
Method method = context.getMethod();
Class[] clazzArray = method.getParameterTypes();

if (clazzArray != null && clazzArray.length > 0) {
for (int i = 0; i < clazzArray.length; i++) {

Object obj = ctxParameters[i];
// Audit log
logAuditData(context, obj);

}
}
}

private <T> void logAuditData(InvocationContext context, T obj) {
try {
AuditLogConf auditLogConf = getAuditLogConf();
if (auditLogConf != null && auditLogConf.isEnabled()) {
AUDIT_LOG.info("====== Request for endpoint:{}, method:{}, from:{}, user:{}, data:{} ", info.getPath(),
context.getMethod(), request.getRemoteAddr(), httpHeaders.getHeaderString("User-inum"), obj);
Map<String, String> attributeMap = getAuditHeaderAttributes(auditLogConf);
AUDIT_LOG.info("attributeMap:{} ", attributeMap);
}

} catch (Exception ex) {
ex.printStackTrace();
}

}

private AuditLogConf getAuditLogConf() {
return this.authUtil.getAuditLogConf();
}

private Map<String, String> getAuditHeaderAttributes(AuditLogConf auditLogConf) {

if (auditLogConf == null) {
return Collections.emptyMap();
}
List<String> attributes = auditLogConf.getHeaderAttributes();

Map<String, String> attributeMap = null;
if (attributes != null && !attributes.isEmpty()) {
attributeMap = new HashMap<>();
for (String attributeName : attributes) {

String attributeValue = httpHeaders.getHeaderString(attributeName);
attributeMap.put(attributeName, attributeValue);
}
}
return attributeMap;
}

}
Loading