Skip to content

Commit 4d66ffc

Browse files
Added support for secure & insecure basic authentication
1 parent a5295d3 commit 4d66ffc

File tree

3 files changed

+194
-7
lines changed

3 files changed

+194
-7
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,16 @@ run the following to get usage details:
2727

2828
./jsonldplayground --help
2929

30+
### Support for basic authentication
31+
32+
Authentication involves 5 options:
33+
34+
| Option | Description |
35+
|-----------------------|-----------------------------------|
36+
| `--username <user>` | username for basic authentication |
37+
| `[--password <pass>]` | password for basic authentication, defaults to the value of the `PASSWORD` environment variable, if any, or the empty string. |
38+
| `[--authHost <host>]` | host scope of the authentication, defaults to 'localhost' |
39+
| `[--authPort <port>]` | port scope of the authentication, defaults to '443' |
40+
| `[--isecure]` | Similar to `curl -k` or `curl --insecure`: if unspecified, all SSL connections are secure by default; if specified, trust everything (do not use for production!) |
41+
42+

jsonldplayground

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
#
77
# run ./jsonldplayground for the usage
88

9-
if [ ! -d "target/appassembler/bin" ]; then
10-
mvn -quiet clean install -DskipTests
9+
TOP=$(dirname $0)
10+
11+
if [ ! -d "${TOP}/target/appassembler/bin" ]; then
12+
(cd "${TOP}"; mvn -quiet clean install -DskipTests)
1113
fi
1214

13-
chmod u+x target/appassembler/bin/*
14-
target/appassembler/bin/jsonldplayground "$@"
15+
chmod u+x "${TOP}/target/appassembler/bin"/*
16+
"${TOP}/target/appassembler/bin/jsonldplayground" "$@"

src/main/java/com/github/jsonldjava/tools/Playground.java

Lines changed: 175 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,51 @@
66
import java.io.IOException;
77
import java.io.InputStreamReader;
88
import java.io.StringReader;
9+
import java.net.Socket;
10+
import java.security.cert.CertificateException;
11+
import java.security.cert.X509Certificate;
912
import java.util.Arrays;
1013
import java.util.HashMap;
1114
import java.util.LinkedHashSet;
1215
import java.util.Map;
1316
import java.util.Set;
1417

18+
import javax.net.ssl.HostnameVerifier;
19+
import javax.net.ssl.SSLContext;
20+
import javax.net.ssl.SSLEngine;
21+
import javax.net.ssl.SSLSession;
22+
import javax.net.ssl.TrustManager;
23+
import javax.net.ssl.X509ExtendedTrustManager;
24+
import javax.net.ssl.X509TrustManager;
25+
1526
import joptsimple.OptionException;
1627
import joptsimple.OptionParser;
1728
import joptsimple.OptionSet;
1829
import joptsimple.OptionSpec;
1930
import joptsimple.ValueConversionException;
2031
import joptsimple.ValueConverter;
2132

33+
import org.apache.http.auth.AuthScope;
34+
import org.apache.http.auth.UsernamePasswordCredentials;
35+
import org.apache.http.client.CredentialsProvider;
36+
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
37+
import org.apache.http.impl.client.BasicCredentialsProvider;
38+
import org.apache.http.impl.client.CloseableHttpClient;
39+
import org.apache.http.impl.client.cache.BasicHttpCacheStorage;
40+
import org.apache.http.impl.client.cache.CacheConfig;
41+
import org.apache.http.impl.client.cache.CachingHttpClientBuilder;
2242
import org.eclipse.rdf4j.model.Model;
2343
import org.eclipse.rdf4j.rio.RDFFormat;
2444
import org.eclipse.rdf4j.rio.RDFParserRegistry;
2545
import org.eclipse.rdf4j.rio.Rio;
2646

47+
import com.github.jsonldjava.core.DocumentLoader;
48+
import com.github.jsonldjava.core.JsonLdConsts;
49+
import com.github.jsonldjava.core.JsonLdApi;
2750
import com.github.jsonldjava.core.JsonLdOptions;
2851
import com.github.jsonldjava.core.JsonLdProcessor;
52+
import com.github.jsonldjava.core.RDFDataset;
53+
import com.github.jsonldjava.utils.JarCacheStorage;
2954
import com.github.jsonldjava.utils.JsonUtils;
3055

3156
public class Playground {
@@ -50,6 +75,37 @@ private static Map<String, RDFFormat> getOutputFormats() {
5075
return outputFormats;
5176
}
5277

78+
private static class InsecureX509TrustManager extends X509ExtendedTrustManager implements X509TrustManager {
79+
80+
public void checkClientTrusted(X509Certificate[] xcs, String string) {
81+
}
82+
83+
@Override
84+
public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {
85+
}
86+
87+
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
88+
return null;
89+
}
90+
91+
92+
@Override
93+
public void checkClientTrusted(X509Certificate[] x509Certificates, String s, Socket socket) throws CertificateException {
94+
}
95+
96+
@Override
97+
public void checkServerTrusted(X509Certificate[] x509Certificates, String s, Socket socket) throws CertificateException {
98+
}
99+
100+
@Override
101+
public void checkClientTrusted(X509Certificate[] x509Certificates, String s, SSLEngine sslEngine) throws CertificateException {
102+
}
103+
104+
@Override
105+
public void checkServerTrusted(X509Certificate[] x509Certificates, String s, SSLEngine sslEngine) throws CertificateException {
106+
}
107+
}
108+
53109
public static void main(String[] args) throws Exception {
54110

55111
final Map<String, RDFFormat> formats = getOutputFormats();
@@ -145,6 +201,22 @@ public Class<String> valueType() {
145201
"The way to output the results from fromRDF. Defaults to expanded. Valid values are: "
146202
+ outputForms);
147203

204+
final OptionSpec<String> usernameOption = parser.accepts("username").withOptionalArg()
205+
.ofType(String.class).describedAs("username for basic authentication credentials");
206+
207+
final OptionSpec<String> passwordOption = parser.accepts("password").withOptionalArg()
208+
.ofType(String.class).describedAs("password for basic authentication credentials (defaults to value of 'PASSWORD' environment property, if set, or empty string otherwise)");
209+
210+
final OptionSpec<String> authHostOption = parser.accepts("authHost").withOptionalArg()
211+
.ofType(String.class).defaultsTo("localhost")
212+
.describedAs("host authentication scope");
213+
214+
final OptionSpec<Integer> authPortOption = parser.accepts("authPort").withOptionalArg()
215+
.ofType(Integer.class).defaultsTo(443)
216+
.describedAs("host port authentication scope");
217+
218+
final OptionSpec<Void> authInsecureOption = parser.accepts("insecure","Similar to `curl -k` or `curl --insecure`: if unspecified, all SSL connections are secure by default; if specified, trust everything (do not use for production!)");
219+
148220
OptionSet options = null;
149221

150222
try {
@@ -167,7 +239,7 @@ public Class<String> valueType() {
167239
opts.setBase(options.valueOf(base));
168240
opts.outputForm = options.valueOf(outputForm);
169241
opts.format = options.has(outputFormat) ? options.valueOf(outputFormat).getDefaultMIMEType()
170-
: "application/nquads";
242+
: JsonLdConsts.APPLICATION_NQUADS;
171243
final RDFFormat sesameOutputFormat = options.valueOf(outputFormat);
172244
final RDFFormat sesameInputFormat = Rio
173245
.getParserFormatForFileName(options.valueOf(inputFile).getName())
@@ -186,6 +258,85 @@ public Class<String> valueType() {
186258
opts.setBase(options.valueOf(inputFile).toURI().toASCIIString());
187259
}
188260

261+
if (options.hasArgument(usernameOption)) {
262+
final String username = options.valueOf(usernameOption);
263+
final String envPassword = System.getenv("PASSWORD");
264+
final String password = options.hasArgument(passwordOption)
265+
? options.valueOf(passwordOption)
266+
: (null != envPassword) ? envPassword : "";
267+
final String authHost = options.valueOf(authHostOption);
268+
final Integer authPort = options.valueOf(authPortOption);
269+
270+
final DocumentLoader documentLoader = new DocumentLoader();
271+
272+
final CredentialsProvider credsProvider = new BasicCredentialsProvider();
273+
credsProvider.setCredentials(
274+
new AuthScope(authHost, authPort),
275+
new UsernamePasswordCredentials(username, password));
276+
277+
final CacheConfig cacheConfig = CacheConfig.custom()
278+
.setMaxCacheEntries(1000)
279+
.setMaxObjectSize(1024 * 128).build();
280+
281+
if (options.has(authInsecureOption)) {
282+
283+
final SSLContext ctx = SSLContext.getInstance("TLS");
284+
final X509TrustManager tm = new InsecureX509TrustManager();
285+
ctx.init(null, new TrustManager[] { tm }, null);
286+
287+
final HostnameVerifier v = new HostnameVerifier() {
288+
289+
@Override
290+
public boolean verify(String s, SSLSession sslSession) {
291+
return true;
292+
}
293+
};
294+
295+
final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(ctx, v);
296+
297+
final CloseableHttpClient httpClient = CachingHttpClientBuilder
298+
.create()
299+
// allow caching
300+
.setCacheConfig(cacheConfig)
301+
// Wrap the local JarCacheStorage around a BasicHttpCacheStorage
302+
.setHttpCacheStorage(
303+
new JarCacheStorage(null, cacheConfig, new BasicHttpCacheStorage(
304+
cacheConfig)))
305+
306+
// Add in the credentials provider
307+
.setDefaultCredentialsProvider(credsProvider)
308+
309+
// insecure ssl connections
310+
.setSSLSocketFactory(sslsf)
311+
312+
// When you are finished setting the properties, call build
313+
.build();
314+
documentLoader.setHttpClient(httpClient);
315+
opts.setDocumentLoader(documentLoader);
316+
317+
} else {
318+
319+
final CloseableHttpClient httpClient = CachingHttpClientBuilder
320+
.create()
321+
// allow caching
322+
.setCacheConfig(cacheConfig)
323+
// Wrap the local JarCacheStorage around a BasicHttpCacheStorage
324+
.setHttpCacheStorage(
325+
new JarCacheStorage(null, cacheConfig, new BasicHttpCacheStorage(
326+
cacheConfig)))
327+
328+
// Add in the credentials provider
329+
.setDefaultCredentialsProvider(credsProvider)
330+
331+
// When you are finished setting the properties, call build
332+
.build();
333+
334+
documentLoader.setHttpClient(httpClient);
335+
opts.setDocumentLoader(documentLoader);
336+
337+
}
338+
}
339+
189340
if ("fromrdf".equals(processingOptionValue)) {
190341
inobj = readFile(options.valueOf(inputFile));
191342
} else {
@@ -223,7 +374,26 @@ public Class<String> valueType() {
223374
}
224375
outobj = JsonLdProcessor.compact(inobj, ctxobj, opts);
225376
} else if ("normalize".equals(processingOptionValue)) {
226-
outobj = JsonLdProcessor.normalize(inobj, opts);
377+
// see https://github.com/jsonld-java/jsonld-java/issues/193
378+
// outobj = JsonLdProcessor.normalize(inobj, opts);
379+
380+
// see https://github.com/jsonld-java/jsonld-java/issues/194
381+
// until this is fixed, it is necessary to clear the format so that JsonLdProcessor won't try to interpret it.
382+
opts.format = null;
383+
384+
// If an output format is specified, add a callback to show the result.
385+
Object result = JsonLdProcessor.toRDF(
386+
inobj,
387+
options.has(outputFormat)
388+
? new RDF4JJSONLDTripleCallback(Rio.createWriter(sesameOutputFormat, System.out))
389+
: null,
390+
opts);
391+
if (RDFDataset.class.isInstance(result)) {
392+
RDFDataset rdfds = RDFDataset.class.cast(result);
393+
outobj = new JsonLdApi(opts).normalize(rdfds);
394+
} else
395+
outobj = result;
396+
227397
} else if ("frame".equals(processingOptionValue)) {
228398
if (ctxobj != null && !(ctxobj instanceof Map)) {
229399
System.out.println(
@@ -244,7 +414,9 @@ public Class<String> valueType() {
244414
if ("tordf".equals(processingOptionValue)) {
245415
// Already serialised above
246416
} else if ("normalize".equals(processingOptionValue)) {
247-
System.out.println((String) outobj);
417+
if (!options.has(outputFormat))
418+
// if no output format was specified, then show the result.
419+
System.out.println(JsonUtils.toPrettyString(outobj));
248420
} else {
249421
System.out.println(JsonUtils.toPrettyString(outobj));
250422
}

0 commit comments

Comments
 (0)