2121
2222package org .apache .jena .fuseki .mod .shiro ;
2323
24- import static org .junit .jupiter .api .Assertions .assertEquals ;
25- import static org .junit .jupiter .api .Assertions .assertNotNull ;
26- import static org .junit .jupiter .api .Assertions .assertThrows ;
27-
2824import java .net .Authenticator ;
2925import java .net .http .HttpClient ;
3026
27+ import java .util .regex .Pattern ;
3128import org .junit .jupiter .api .AfterEach ;
3229import org .junit .jupiter .api .BeforeEach ;
30+ import org .junit .jupiter .api .Disabled ;
3331import org .junit .jupiter .api .Test ;
3432
3533import org .apache .jena .atlas .lib .Lib ;
5250import org .apache .jena .sparql .exec .http .GSP ;
5351import org .apache .jena .sparql .exec .http .QueryExecHTTP ;
5452
53+ import static org .junit .jupiter .api .Assertions .*;
54+
5555public class TestModShiro {
5656 static final String unlocal = determineUnlocal ();
5757 static final String localRE = "(localhost)|(127.0.0.1)|(::1)" ;
@@ -158,7 +158,7 @@ private FusekiServer.Builder serverBuilderWithShiro(String filename) {
158158 HttpClient httpClient = HttpEnv .httpClientBuilder ().authenticator (authenticator ).build ();
159159 attemptByLocalhost (server , httpClient , dsname );
160160 // and a SPARQL query
161- QueryExecHTTP .service (URL ).httpClient (httpClient ).query ("ASK{}" ). ask () ;
161+ QueryExecHTTP .service (URL ).httpClient (httpClient ).query ("ASK{}" );
162162 }
163163
164164 // user-password via registration
@@ -168,17 +168,113 @@ private FusekiServer.Builder serverBuilderWithShiro(String filename) {
168168 AuthEnv .get ().unregisterUsernamePassword (server .serverURL ());
169169 }
170170
171- // try the ping (proxy for admin operations)
171+ // try the ping (proxy for admin operations as admin user)
172+ Pattern startOfDateTimePattern = Pattern .compile ("[0-9]{4}-.*" );
172173 {
173174 Authenticator authenticator = AuthLib .authenticator ("admin" , "pw" );
174175 HttpClient httpClient = HttpEnv .httpClientBuilder ().authenticator (authenticator ).build ();
175- HttpOp .httpGetString (httpClient , server .serverURL ()+"$/ping" );
176+ String pingResultString = HttpOp .httpGetString (httpClient , server .serverURL ()+"$/ping" );
177+ assertTrue (startOfDateTimePattern .matcher (pingResultString ).find (),
178+ "admin user should be able to ping: " + pingResultString );
179+ AuthEnv .get ().unregisterUsernamePassword (server .serverURL ());
180+ }
181+ // try the ping (proxy for operations as user1 user without access)
182+ {
183+ // check that PingResult is still unauthorized
184+ HttpClient httpClientAnon = HttpEnv .httpClientBuilder ().build ();
185+ HttpException httpEx = assertThrows (HttpException .class , ()->HttpOp .httpGetString (httpClientAnon , server .serverURL ()+"$/ping" ));
186+ assertEquals (401 , httpEx .getStatusCode (), "Expect HTTP 401 if not logged in" );
187+ Authenticator authenticator = AuthLib .authenticator ("user1" , "passwd1" );
188+ HttpClient httpClient = HttpEnv .httpClientBuilder ().authenticator (authenticator ).build ();
189+ String pingResultString = HttpOp .httpGetString (httpClient , server .serverURL ()+"$/ping" );
190+ assertTrue (startOfDateTimePattern .matcher (pingResultString ).find (),
191+ "user1 user should not be able to ping: " + pingResultString );
192+ }
193+
194+
195+ {
196+ // Bad password
197+ AuthEnv .get ().registerUsernamePassword (server .serverURL (), "user1" , "passwd2" );
198+ HttpException httpEx = assertThrows (HttpException .class , ()->attemptByLocalhost (server , dsname ));
199+ assertEquals (401 , httpEx .getStatusCode (), "Expected HTTP 401" );
200+ AuthEnv .get ().unregisterUsernamePassword (server .serverURL ());
201+ }
202+
203+ } finally {
204+ server .stop ();
205+ }
206+ }
207+
208+ @ Test public void access_userPassword_group () {
209+ String dsname = "/ds" ;
210+ DatasetGraph dsg = DatasetGraphFactory .createTxnMem ();
211+ FusekiServer server = serverBuilderWithShiro ("testing/Shiro/shiro_user_group_password.ini" )
212+ .add (dsname , dsg )
213+ .enablePing (true )
214+ .build ();
215+ server .start ();
216+
217+ String URL = server .datasetURL (dsname );
218+
219+ try {
220+ // No user-password
221+ {
222+ HttpException httpEx = assertThrows (HttpException .class , ()->attemptByLocalhost (server , dsname ));
223+ assertEquals (401 , httpEx .getStatusCode (), "Expected HTTP 401" );
224+ }
225+
226+ // user-password via authenticator: localhost
227+ {
228+ Authenticator authenticator = AuthLib .authenticator ("user1" , "passwd1" );
229+ HttpClient httpClient = HttpEnv .httpClientBuilder ().authenticator (authenticator ).build ();
230+ attemptByLocalhost (server , httpClient , dsname );
231+ // and a SPARQL query
232+ QueryExecHTTP .service (URL ).httpClient (httpClient ).query ("ASK{}" );
233+ }
234+
235+ // user-password via registration
236+ {
237+ AuthEnv .get ().registerUsernamePassword (server .serverURL (), "user1" , "passwd1" );
238+ attemptByLocalhost (server , dsname );
176239 AuthEnv .get ().unregisterUsernamePassword (server .serverURL ());
177240 }
178241
242+ // try the ping (proxy for admin operations as admin user)
243+ Pattern startOfDateTimePattern = Pattern .compile ("[0-9]{4}-.*" );
244+ {
245+ Authenticator authenticator = AuthLib .authenticator ("admin" , "pw" );
246+ HttpClient httpClient = HttpEnv .httpClientBuilder ().authenticator (authenticator ).build ();
247+ String pingResultString = HttpOp .httpGetString (httpClient , server .serverURL ()+"$/ping" );
248+ assertTrue (startOfDateTimePattern .matcher (pingResultString ).find (),
249+ "admin user should be able to ping: " + pingResultString );
250+ AuthEnv .get ().unregisterUsernamePassword (server .serverURL ());
251+ }
252+ // try the ping (proxy for operations as user1 user without access)
253+ {
254+ // check that PingResult is still unauthorized
255+ HttpClient httpClientAnon = HttpEnv .httpClientBuilder ().build ();
256+ HttpException httpEx = assertThrows (HttpException .class , ()->HttpOp .httpGetString (httpClientAnon , server .serverURL ()+"$/ping" ));
257+ assertEquals (401 , httpEx .getStatusCode (), "Expect HTTP 401 if not logged in" );
258+ Authenticator authenticator = AuthLib .authenticator ("user1" , "passwd1" );
259+ HttpClient httpClient = HttpEnv .httpClientBuilder ().authenticator (authenticator ).build ();
260+ // check again that the user is logged in and can access ds
261+ HttpOp .httpGetString (httpClient , server .datasetURL (dsname ));
262+ System .out .println (server .serverURL ()+ "$/ping" );
263+ //String pingResultString = HttpOp.httpGetString(httpClient, server.serverURL()+"$/ping");
264+ //assertEquals(pingResultString, "OK", "PingResult: " + pingResultString);
265+
266+ // String pingResultString = HttpOp.httpGetString(httpClient, server.serverURL()+"$/ping");
267+ // assertEquals(pingResultString, "OK", "PingResult: " + pingResultString);
268+ HttpException httpEx2 = assertThrows (HttpException .class , ()->HttpOp .httpGetString (httpClient , server .serverURL ()+"$/ping" ));
269+ assertEquals (403 , httpEx2 .getStatusCode (), "Expect HTTP 403 if not logged in" + httpEx2 .getResponse () + httpEx2 .getMessage () + httpEx2 .getStatusLine () + httpEx2 .getStatusCode ());
270+
271+ // assertFalse(startOfDateTimePattern.matcher(pingResultString).find(),
272+ // "user1 user should not be able to ping: " + pingResultString);
273+ }
179274 {
180275 // Bad password
181276 AuthEnv .get ().registerUsernamePassword (server .serverURL (), "user1" , "passwd2" );
277+ // attemptByLocalhost(server, dsname);
182278 HttpException httpEx = assertThrows (HttpException .class , ()->attemptByLocalhost (server , dsname ));
183279 assertEquals (401 , httpEx .getStatusCode (), "Expected HTTP 401" );
184280 AuthEnv .get ().unregisterUsernamePassword (server .serverURL ());
@@ -189,6 +285,7 @@ private FusekiServer.Builder serverBuilderWithShiro(String filename) {
189285 }
190286 }
191287
288+
192289 @ Test public void shiroByCommandLine () {
193290 String dsname = "/ds" ;
194291 FusekiModule fmod = FMod_Shiro .create ();
0 commit comments