Skip to content

Commit ea04e2c

Browse files
authored
feat(config-api): audit log, agama ADS spec, fix for 0 index search (#3369)
* feat(config-api): audit log changes * feat(config-api): audit log and request interceptor * feat(config-api): sync with main * feat(config-api): audit log, agama ADS spec, fix for 0 index search * feat(config-api): audit log, agama ADS spec, fix for 0 index search
1 parent 7dd35fb commit ea04e2c

File tree

18 files changed

+396
-43
lines changed

18 files changed

+396
-43
lines changed

jans-auth-server/common/src/main/java/io/jans/as/common/model/registration/Client.java

+8
Original file line numberDiff line numberDiff line change
@@ -1459,6 +1459,14 @@ public void setBackchannelUserCodeParameter(Boolean backchannelUserCodeParameter
14591459
this.backchannelUserCodeParameter = backchannelUserCodeParameter;
14601460
}
14611461

1462+
public String getDisplayName() {
1463+
return getClientName();
1464+
}
1465+
1466+
public void setDisplayName(String displayName) {
1467+
setClientName(displayName);
1468+
}
1469+
14621470
public String getDescription() {
14631471
return description;
14641472
}

jans-config-api/common/src/main/java/io/jans/configapi/model/configuration/ApiAppConfiguration.java

+10
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public class ApiAppConfiguration implements Configuration {
3636
private List<String> userExclusionAttributes;
3737
private List<String> userMandatoryAttributes;
3838
private AgamaConfiguration agamaConfiguration;
39+
private AuditLogConf auditLogConf;
3940

4041
public boolean isConfigOauthEnabled() {
4142
return configOauthEnabled;
@@ -230,6 +231,14 @@ public AgamaConfiguration getAgamaConfiguration() {
230231
public void setAgamaConfiguration(AgamaConfiguration agamaConfiguration) {
231232
this.agamaConfiguration = agamaConfiguration;
232233
}
234+
235+
public AuditLogConf getAuditLogConf() {
236+
return auditLogConf;
237+
}
238+
239+
public void setAuditLogConf(AuditLogConf auditLogConf) {
240+
this.auditLogConf = auditLogConf;
241+
}
233242

234243
@Override
235244
public String toString() {
@@ -246,6 +255,7 @@ public String toString() {
246255
+ " , userExclusionAttributes="+ userExclusionAttributes
247256
+ " , userMandatoryAttributes="+ userMandatoryAttributes
248257
+ " , agamaConfiguration="+ agamaConfiguration
258+
+ " , auditLogConf="+ auditLogConf
249259
+ "]";
250260
}
251261

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package io.jans.configapi.model.configuration;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import java.util.List;
5+
6+
@JsonIgnoreProperties(ignoreUnknown = true)
7+
public class AuditLogConf {
8+
9+
/**
10+
* Flag to enable and disable audit log
11+
*/
12+
private boolean enabled;
13+
14+
/**
15+
* List of header attributes
16+
*/
17+
private List<String> headerAttributes;
18+
19+
public boolean isEnabled() {
20+
return enabled;
21+
}
22+
23+
public void setEnabled(boolean enabled) {
24+
this.enabled = enabled;
25+
}
26+
27+
public List<String> getHeaderAttributes() {
28+
return headerAttributes;
29+
}
30+
31+
public void setHeaderAttributes(List<String> headerAttributes) {
32+
this.headerAttributes = headerAttributes;
33+
}
34+
35+
@Override
36+
public String toString() {
37+
return "AuditLogConf [enabled=" + enabled + ", headerAttributes=" + headerAttributes + "]";
38+
}
39+
40+
}

jans-config-api/docs/jans-config-api-swagger-auto.yaml

+56-23
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,8 @@ paths:
183183
description: InternalServerError
184184
security:
185185
- oauth2:
186-
- https://jans.io/oauth/config/agama.readonly
187186
- https://jans.io/oauth/config/agama.write
188-
- https://jans.io/oauth/config/read-all
187+
- https://jans.io/oauth/config/write-all
189188
delete:
190189
tags:
191190
- Agama - Developer Studio
@@ -212,9 +211,7 @@ paths:
212211
description: InternalServerError
213212
security:
214213
- oauth2:
215-
- https://jans.io/oauth/config/agama.readonly
216-
- https://jans.io/oauth/config/agama.write
217-
- https://jans.io/oauth/config/read-all
214+
- https://jans.io/oauth/config/agama.delete
218215
/api/v1/ads-deployment/list:
219216
get:
220217
tags:
@@ -612,6 +609,40 @@ paths:
612609
security:
613610
- oauth2:
614611
- https://jans.io/oauth/config/agama.write
612+
/api/v1/agama/syntax-check/{qname}:
613+
post:
614+
tags:
615+
- Agama - Configuration
616+
summary: Determine if the text passed is valid Agama code
617+
description: Determine if the text passed is valid Agama code
618+
operationId: agama-syntax-check
619+
parameters:
620+
- name: qname
621+
in: path
622+
required: true
623+
schema:
624+
type: string
625+
requestBody:
626+
content:
627+
text/plain:
628+
schema:
629+
type: string
630+
responses:
631+
"200":
632+
description: Agama Syntax Check message
633+
content:
634+
application/json:
635+
schema:
636+
type: string
637+
"401":
638+
description: Unauthorized
639+
"500":
640+
description: InternalServerError
641+
security:
642+
- oauth2:
643+
- https://jans.io/oauth/config/agama.readonly
644+
- https://jans.io/oauth/config/agama.write
645+
- https://jans.io/oauth/config/read-all
615646
/api/v1/agama/source/{qname}:
616647
put:
617648
tags:
@@ -7268,18 +7299,18 @@ components:
72687299
type: string
72697300
whitePagesCanView:
72707301
type: boolean
7271-
userCanView:
7302+
adminCanEdit:
72727303
type: boolean
7273-
userCanAccess:
7304+
adminCanAccess:
72747305
type: boolean
72757306
userCanEdit:
72767307
type: boolean
7277-
adminCanAccess:
7278-
type: boolean
7279-
adminCanEdit:
7308+
userCanView:
72807309
type: boolean
72817310
adminCanView:
72827311
type: boolean
7312+
userCanAccess:
7313+
type: boolean
72837314
baseDn:
72847315
type: string
72857316
PatchRequest:
@@ -7614,6 +7645,8 @@ components:
76147645
ttl:
76157646
type: integer
76167647
format: int32
7648+
displayName:
7649+
type: string
76177650
authenticationMethod:
76187651
type: string
76197652
enum:
@@ -8437,6 +8470,17 @@ components:
84378470
$ref: '#/components/schemas/SsaConfiguration'
84388471
blockWebviewAuthorizationEnabled:
84398472
type: boolean
8473+
fapi:
8474+
type: boolean
8475+
allResponseTypesSupported:
8476+
uniqueItems: true
8477+
type: array
8478+
items:
8479+
type: string
8480+
enum:
8481+
- code
8482+
- token
8483+
- id_token
84408484
enabledFeatureFlags:
84418485
uniqueItems: true
84428486
type: array
@@ -8464,17 +8508,6 @@ components:
84648508
- STAT
84658509
- PAR
84668510
- SSA
8467-
allResponseTypesSupported:
8468-
uniqueItems: true
8469-
type: array
8470-
items:
8471-
type: string
8472-
enum:
8473-
- code
8474-
- token
8475-
- id_token
8476-
fapi:
8477-
type: boolean
84788511
AuthenticationFilter:
84798512
required:
84808513
- baseDn
@@ -8768,13 +8801,13 @@ components:
87688801
type: boolean
87698802
internal:
87708803
type: boolean
8771-
locationPath:
8772-
type: string
87738804
locationType:
87748805
type: string
87758806
enum:
87768807
- ldap
87778808
- file
8809+
locationPath:
8810+
type: string
87788811
baseDn:
87798812
type: string
87808813
ScriptError:

jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/service/UserMgmtService.java

+2-5
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,7 @@ public String getPeopleBaseDn() {
6767
}
6868

6969
public PagedResult<User> searchUsers(SearchRequest searchRequest) {
70-
if (logger.isDebugEnabled()) {
71-
logger.debug("Search Users with searchRequest:{}", escapeLog(searchRequest));
72-
}
73-
70+
logger.debug("Search Users with searchRequest:{}", escapeLog(searchRequest));
7471
Filter searchFilter = null;
7572
List<Filter> filters = new ArrayList<>();
7673
if (searchRequest.getFilterAssertionValue() != null && !searchRequest.getFilterAssertionValue().isEmpty()) {
@@ -87,7 +84,7 @@ public PagedResult<User> searchUsers(SearchRequest searchRequest) {
8784
}
8885
searchFilter = Filter.createORFilter(filters);
8986
}
90-
87+
logger.debug("Users searchFilter:{}", searchFilter);
9188
return persistenceEntryManager.findPagedEntries(getPeopleBaseDn(), User.class, searchFilter, null,
9289
searchRequest.getSortBy(), SortOrder.getByValue(searchRequest.getSortOrder()),
9390
searchRequest.getStartIndex(), searchRequest.getCount(), searchRequest.getMaxCount());

jans-config-api/profiles/local/test.properties

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ test.scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/con
44
# jans.server
55
token.endpoint=https://jans.server1/jans-auth/restv1/token
66
token.grant.type=client_credentials
7-
test.client.id=1800.5957dfad-b2cb-4764-85fe-841e6bc870ff
8-
test.client.secret=ozu4fjIzoEbe
7+
test.client.id=1800.c94f1e10-7716-4dc8-b82d-4dd1169ed4f9
8+
test.client.secret=2M6r3vYeQEIT
99
test.issuer=https://jans.server1/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/*
2+
* Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.
3+
*
4+
* Copyright (c) 2020, Janssen Project
5+
*/
6+
7+
package io.jans.configapi.interceptor;
8+
9+
import io.jans.configapi.core.interceptor.RequestAuditInterceptor;
10+
import io.jans.configapi.model.configuration.AuditLogConf;
11+
import io.jans.configapi.util.AuthUtil;
12+
import jakarta.annotation.Priority;
13+
import jakarta.inject.Inject;
14+
import jakarta.servlet.http.HttpServletRequest;
15+
import jakarta.ws.rs.WebApplicationException;
16+
import jakarta.ws.rs.core.Context;
17+
import jakarta.ws.rs.core.HttpHeaders;
18+
import jakarta.ws.rs.core.UriInfo;
19+
20+
import java.lang.reflect.Method;
21+
import java.util.Collections;
22+
import java.util.Map;
23+
import java.util.HashMap;
24+
import java.util.List;
25+
26+
import org.slf4j.Logger;
27+
import org.slf4j.LoggerFactory;
28+
29+
import jakarta.interceptor.AroundInvoke;
30+
import jakarta.interceptor.Interceptor;
31+
import jakarta.interceptor.InvocationContext;
32+
33+
@Interceptor
34+
@RequestAuditInterceptor
35+
@Priority(Interceptor.Priority.APPLICATION)
36+
public class AuditLogInterceptor {
37+
38+
private static final Logger AUDIT_LOG = LoggerFactory.getLogger("audit");
39+
40+
@Context
41+
UriInfo info;
42+
43+
@Context
44+
HttpServletRequest request;
45+
46+
@Context
47+
private HttpHeaders httpHeaders;
48+
49+
@Inject
50+
AuthUtil authUtil;
51+
52+
@SuppressWarnings({ "all" })
53+
@AroundInvoke
54+
public Object aroundReadFrom(InvocationContext context) throws Exception {
55+
56+
try {
57+
processRequest(context);
58+
59+
} catch (Exception ex) {
60+
throw new WebApplicationException(ex);
61+
}
62+
return context.proceed();
63+
}
64+
65+
private void processRequest(InvocationContext context) {
66+
67+
Object[] ctxParameters = context.getParameters();
68+
Method method = context.getMethod();
69+
Class[] clazzArray = method.getParameterTypes();
70+
71+
if (clazzArray != null && clazzArray.length > 0) {
72+
for (int i = 0; i < clazzArray.length; i++) {
73+
74+
Object obj = ctxParameters[i];
75+
// Audit log
76+
logAuditData(context, obj);
77+
78+
}
79+
}
80+
}
81+
82+
private <T> void logAuditData(InvocationContext context, T obj) {
83+
try {
84+
AuditLogConf auditLogConf = getAuditLogConf();
85+
if (auditLogConf != null && auditLogConf.isEnabled()) {
86+
AUDIT_LOG.info("====== Request for endpoint:{}, method:{}, from:{}, user:{}, data:{} ", info.getPath(),
87+
context.getMethod(), request.getRemoteAddr(), httpHeaders.getHeaderString("User-inum"), obj);
88+
Map<String, String> attributeMap = getAuditHeaderAttributes(auditLogConf);
89+
AUDIT_LOG.info("attributeMap:{} ", attributeMap);
90+
}
91+
92+
} catch (Exception ex) {
93+
ex.printStackTrace();
94+
}
95+
96+
}
97+
98+
private AuditLogConf getAuditLogConf() {
99+
return this.authUtil.getAuditLogConf();
100+
}
101+
102+
private Map<String, String> getAuditHeaderAttributes(AuditLogConf auditLogConf) {
103+
104+
if (auditLogConf == null) {
105+
return Collections.emptyMap();
106+
}
107+
List<String> attributes = auditLogConf.getHeaderAttributes();
108+
109+
Map<String, String> attributeMap = null;
110+
if (attributes != null && !attributes.isEmpty()) {
111+
attributeMap = new HashMap<>();
112+
for (String attributeName : attributes) {
113+
114+
String attributeValue = httpHeaders.getHeaderString(attributeName);
115+
attributeMap.put(attributeName, attributeValue);
116+
}
117+
}
118+
return attributeMap;
119+
}
120+
121+
}

0 commit comments

Comments
 (0)