Skip to content

Commit faba21e

Browse files
GH-2426 - Allow specifying the impersonated database user via the clients.
Co-authored-by: Gerrit Meier <[email protected]>
1 parent 0988b4f commit faba21e

File tree

12 files changed

+617
-117
lines changed

12 files changed

+617
-117
lines changed

src/main/java/org/springframework/data/neo4j/core/DefaultNeo4jClient.java

+110-34
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,12 @@ public Result run(Query query) {
165165
// Below are all the implementations (methods and classes) as defined by the contracts of Neo4jClient
166166

167167
@Override
168-
public RunnableSpec query(String cypher) {
168+
public UnboundRunnableSpec query(String cypher) {
169169
return query(() -> cypher);
170170
}
171171

172172
@Override
173-
public RunnableSpec query(Supplier<String> cypherSupplier) {
173+
public UnboundRunnableSpec query(Supplier<String> cypherSupplier) {
174174
return new DefaultRunnableSpec(cypherSupplier);
175175
}
176176

@@ -256,80 +256,63 @@ private UserSelection resolveUser(@Nullable String userName) {
256256
return UserSelectionProvider.getDefaultSelectionProvider().getUserSelection();
257257
}
258258

259-
class DefaultRunnableSpec implements RunnableSpec {
259+
class DefaultRunnableSpec implements UnboundRunnableSpec, RunnableSpecBoundToDatabaseAndUser {
260260

261261
private final RunnableStatement runnableStatement;
262262

263263
private DatabaseSelection databaseSelection;
264264

265-
@Nullable
266-
private UserSelection impersonatedUser;
265+
private UserSelection userSelection;
267266

268267
DefaultRunnableSpec(Supplier<String> cypherSupplier) {
268+
269269
this.databaseSelection = resolveTargetDatabaseName(null);
270-
this.impersonatedUser = resolveUser(null);
270+
this.userSelection = resolveUser(null);
271271
this.runnableStatement = new RunnableStatement(cypherSupplier);
272272
}
273273

274274
@Override
275-
public RunnableSpecTightToDatabase in(String targetDatabase) {
275+
public RunnableSpecBoundToDatabase in(String targetDatabase) {
276276

277277
this.databaseSelection = resolveTargetDatabaseName(targetDatabase);
278-
return this;
278+
return new DefaultRunnableSpecBoundToDatabase();
279279
}
280280

281-
class DefaultOngoingBindSpec<T> implements OngoingBindSpec<T, RunnableSpecTightToDatabase> {
282-
283-
@Nullable private final T value;
284-
285-
DefaultOngoingBindSpec(@Nullable T value) {
286-
this.value = value;
287-
}
288-
289-
@Override
290-
public RunnableSpecTightToDatabase to(String name) {
291-
292-
DefaultRunnableSpec.this.runnableStatement.parameters.add(name, value);
293-
return DefaultRunnableSpec.this;
294-
}
295-
296-
@Override
297-
public RunnableSpecTightToDatabase with(Function<T, Map<String, Object>> binder) {
298-
299-
Assert.notNull(binder, "Binder is required.");
281+
@Override
282+
public RunnableSpecBoundToUser asUser(String asUser) {
300283

301-
return bindAll(binder.apply(value));
302-
}
284+
this.userSelection = resolveUser(asUser);
285+
return new DefaultRunnableSpecBoundToUser();
303286
}
304287

305288
@Override
306-
public <T> OngoingBindSpec<T, RunnableSpecTightToDatabase> bind(T value) {
289+
public <T> OngoingBindSpec<T, RunnableSpec> bind(T value) {
307290
return new DefaultOngoingBindSpec<>(value);
308291
}
309292

310293
@Override
311-
public RunnableSpecTightToDatabase bindAll(Map<String, Object> newParameters) {
294+
public RunnableSpec bindAll(Map<String, Object> newParameters) {
312295
this.runnableStatement.parameters.addAll(newParameters);
313296
return this;
314297
}
315298

316299
@Override
317300
public <T> MappingSpec<T> fetchAs(Class<T> targetClass) {
318301

319-
return new DefaultRecordFetchSpec<>(databaseSelection, impersonatedUser, runnableStatement,
302+
return new DefaultRecordFetchSpec<>(databaseSelection, userSelection, runnableStatement,
320303
new SingleValueMappingFunction<>(conversionService, targetClass));
321304
}
322305

323306
@Override
324307
public RecordFetchSpec<Map<String, Object>> fetch() {
325308

326-
return new DefaultRecordFetchSpec<>(databaseSelection, impersonatedUser, runnableStatement, (t, r) -> r.asMap());
309+
return new DefaultRecordFetchSpec<>(databaseSelection, userSelection, runnableStatement, (t, r) -> r.asMap());
327310
}
328311

329312
@Override
330313
public ResultSummary run() {
331314

332-
try (QueryRunner statementRunner = getQueryRunner(databaseSelection, impersonatedUser)) {
315+
try (QueryRunner statementRunner = getQueryRunner(databaseSelection, userSelection)) {
333316
Result result = runnableStatement.runWith(statementRunner);
334317
return ResultSummaries.process(result.consume());
335318
} catch (RuntimeException e) {
@@ -338,6 +321,99 @@ public ResultSummary run() {
338321
throw new RuntimeException(e);
339322
}
340323
}
324+
325+
class DefaultOngoingBindSpec<T> implements OngoingBindSpec<T, RunnableSpec> {
326+
327+
@Nullable private final T value;
328+
329+
DefaultOngoingBindSpec(@Nullable T value) {
330+
this.value = value;
331+
}
332+
333+
@Override
334+
public RunnableSpec to(String name) {
335+
336+
DefaultRunnableSpec.this.runnableStatement.parameters.add(name, value);
337+
return DefaultRunnableSpec.this;
338+
}
339+
340+
@Override
341+
public RunnableSpec with(Function<T, Map<String, Object>> binder) {
342+
343+
Assert.notNull(binder, "Binder is required.");
344+
345+
return bindAll(binder.apply(value));
346+
}
347+
}
348+
349+
class DefaultRunnableSpecBoundToDatabase implements RunnableSpecBoundToDatabase {
350+
@Override
351+
public RunnableSpecBoundToDatabaseAndUser asUser(String aUser) {
352+
353+
DefaultRunnableSpec.this.userSelection = resolveUser(aUser);
354+
return DefaultRunnableSpec.this;
355+
}
356+
357+
@Override
358+
public <T> MappingSpec<T> fetchAs(Class<T> targetClass) {
359+
return DefaultRunnableSpec.this.fetchAs(targetClass);
360+
}
361+
362+
@Override
363+
public RecordFetchSpec<Map<String, Object>> fetch() {
364+
return DefaultRunnableSpec.this.fetch();
365+
}
366+
367+
@Override
368+
public ResultSummary run() {
369+
return DefaultRunnableSpec.this.run();
370+
}
371+
372+
@Override
373+
public <T> OngoingBindSpec<T, RunnableSpec> bind(T value) {
374+
return DefaultRunnableSpec.this.bind(value);
375+
}
376+
377+
@Override
378+
public RunnableSpec bindAll(Map<String, Object> parameters) {
379+
return DefaultRunnableSpec.this.bindAll(parameters);
380+
}
381+
}
382+
383+
class DefaultRunnableSpecBoundToUser implements RunnableSpecBoundToUser {
384+
385+
@Override
386+
public RunnableSpecBoundToDatabaseAndUser in(String aDatabase) {
387+
388+
DefaultRunnableSpec.this.databaseSelection = resolveTargetDatabaseName(aDatabase);
389+
return DefaultRunnableSpec.this;
390+
}
391+
392+
@Override
393+
public <T> MappingSpec<T> fetchAs(Class<T> targetClass) {
394+
return DefaultRunnableSpec.this.fetchAs(targetClass);
395+
}
396+
397+
@Override
398+
public RecordFetchSpec<Map<String, Object>> fetch() {
399+
return DefaultRunnableSpec.this.fetch();
400+
}
401+
402+
@Override
403+
public ResultSummary run() {
404+
return DefaultRunnableSpec.this.run();
405+
}
406+
407+
@Override
408+
public <T> OngoingBindSpec<T, RunnableSpec> bind(T value) {
409+
return DefaultRunnableSpec.this.bind(value);
410+
}
411+
412+
@Override
413+
public RunnableSpec bindAll(Map<String, Object> parameters) {
414+
return DefaultRunnableSpec.this.bindAll(parameters);
415+
}
416+
}
341417
}
342418

343419
class DefaultRecordFetchSpec<T> implements RecordFetchSpec<T>, MappingSpec<T> {

src/main/java/org/springframework/data/neo4j/core/DefaultReactiveNeo4jClient.java

+103-27
Original file line numberDiff line numberDiff line change
@@ -176,12 +176,12 @@ <T> Flux<T> doInStatementRunnerForFlux(Mono<DatabaseSelection> databaseSelection
176176
}
177177

178178
@Override
179-
public RunnableSpec query(String cypher) {
179+
public UnboundRunnableSpec query(String cypher) {
180180
return query(() -> cypher);
181181
}
182182

183183
@Override
184-
public RunnableSpec query(Supplier<String> cypherSupplier) {
184+
public UnboundRunnableSpec query(Supplier<String> cypherSupplier) {
185185
return new DefaultRunnableSpec(cypherSupplier);
186186
}
187187

@@ -219,7 +219,7 @@ private Mono<UserSelection> resolveUser(@Nullable String userName) {
219219
return ReactiveUserSelectionProvider.getDefaultSelectionProvider().getUserSelection();
220220
}
221221

222-
class DefaultRunnableSpec implements RunnableSpec {
222+
class DefaultRunnableSpec implements UnboundRunnableSpec, RunnableSpecBoundToDatabaseAndUser {
223223

224224
private final Supplier<String> cypherSupplier;
225225

@@ -236,13 +236,50 @@ class DefaultRunnableSpec implements RunnableSpec {
236236
}
237237

238238
@Override
239-
public RunnableSpecTightToDatabase in(String targetDatabase) {
239+
public RunnableSpecBoundToDatabase in(String targetDatabase) {
240240

241241
this.databaseSelection = resolveTargetDatabaseName(targetDatabase);
242+
return new DefaultRunnableSpecBoundToDatabase();
243+
}
244+
245+
@Override
246+
public RunnableSpecBoundToUser asUser(String asUser) {
247+
248+
this.userSelection = resolveUser(asUser);
249+
return new DefaultRunnableSpecBoundToUser();
250+
}
251+
252+
@Override
253+
public <T> Neo4jClient.OngoingBindSpec<T, RunnableSpec> bind(T value) {
254+
return new DefaultOngoingBindSpec<>(value);
255+
}
256+
257+
@Override
258+
public RunnableSpec bindAll(Map<String, Object> newParameters) {
259+
this.parameters.addAll(newParameters);
242260
return this;
243261
}
244262

245-
class DefaultOngoingBindSpec<T> implements Neo4jClient.OngoingBindSpec<T, RunnableSpecTightToDatabase> {
263+
@Override
264+
public <R> MappingSpec<R> fetchAs(Class<R> targetClass) {
265+
266+
return new DefaultRecordFetchSpec<>(databaseSelection, userSelection, cypherSupplier, parameters,
267+
new SingleValueMappingFunction<>(conversionService, targetClass));
268+
}
269+
270+
@Override
271+
public RecordFetchSpec<Map<String, Object>> fetch() {
272+
273+
return new DefaultRecordFetchSpec<>(databaseSelection, userSelection, cypherSupplier, parameters, (t, r) -> r.asMap());
274+
}
275+
276+
@Override
277+
public Mono<ResultSummary> run() {
278+
279+
return new DefaultRecordFetchSpec<>(databaseSelection, userSelection, cypherSupplier, this.parameters, null).run();
280+
}
281+
282+
class DefaultOngoingBindSpec<T> implements Neo4jClient.OngoingBindSpec<T, RunnableSpec> {
246283

247284
@Nullable private final T value;
248285

@@ -251,49 +288,88 @@ class DefaultOngoingBindSpec<T> implements Neo4jClient.OngoingBindSpec<T, Runnab
251288
}
252289

253290
@Override
254-
public RunnableSpecTightToDatabase to(String name) {
291+
public RunnableSpec to(String name) {
255292

256293
DefaultRunnableSpec.this.parameters.add(name, value);
257294
return DefaultRunnableSpec.this;
258295
}
259296

260297
@Override
261-
public RunnableSpecTightToDatabase with(Function<T, Map<String, Object>> binder) {
298+
public RunnableSpec with(Function<T, Map<String, Object>> binder) {
262299

263300
Assert.notNull(binder, "Binder is required.");
264301

265302
return bindAll(binder.apply(value));
266303
}
267304
}
268305

269-
@Override
270-
public <T> Neo4jClient.OngoingBindSpec<T, RunnableSpecTightToDatabase> bind(T value) {
271-
return new DefaultOngoingBindSpec<>(value);
272-
}
306+
class DefaultRunnableSpecBoundToDatabase implements RunnableSpecBoundToDatabase {
307+
@Override
308+
public RunnableSpecBoundToDatabaseAndUser asUser(String aUser) {
273309

274-
@Override
275-
public RunnableSpecTightToDatabase bindAll(Map<String, Object> newParameters) {
276-
this.parameters.addAll(newParameters);
277-
return this;
278-
}
310+
DefaultRunnableSpec.this.userSelection = resolveUser(aUser);
311+
return DefaultRunnableSpec.this;
312+
}
279313

280-
@Override
281-
public <R> MappingSpec<R> fetchAs(Class<R> targetClass) {
314+
@Override
315+
public <T> MappingSpec<T> fetchAs(Class<T> targetClass) {
316+
return DefaultRunnableSpec.this.fetchAs(targetClass);
317+
}
282318

283-
return new DefaultRecordFetchSpec<>(databaseSelection, userSelection, cypherSupplier, parameters,
284-
new SingleValueMappingFunction<>(conversionService, targetClass));
285-
}
319+
@Override
320+
public RecordFetchSpec<Map<String, Object>> fetch() {
321+
return DefaultRunnableSpec.this.fetch();
322+
}
286323

287-
@Override
288-
public RecordFetchSpec<Map<String, Object>> fetch() {
324+
@Override
325+
public Mono<ResultSummary> run() {
326+
return DefaultRunnableSpec.this.run();
327+
}
289328

290-
return new DefaultRecordFetchSpec<>(databaseSelection, userSelection, cypherSupplier, parameters, (t, r) -> r.asMap());
329+
@Override
330+
public <T> Neo4jClient.OngoingBindSpec<T, RunnableSpec> bind(T value) {
331+
return DefaultRunnableSpec.this.bind(value);
332+
}
333+
334+
@Override
335+
public RunnableSpec bindAll(Map<String, Object> newParameters) {
336+
return DefaultRunnableSpec.this.bindAll(newParameters);
337+
}
291338
}
292339

293-
@Override
294-
public Mono<ResultSummary> run() {
340+
class DefaultRunnableSpecBoundToUser implements RunnableSpecBoundToUser {
295341

296-
return new DefaultRecordFetchSpec<>(databaseSelection, userSelection, cypherSupplier, this.parameters, null).run();
342+
@Override
343+
public RunnableSpecBoundToDatabaseAndUser in(String aDatabase) {
344+
345+
DefaultRunnableSpec.this.databaseSelection = resolveTargetDatabaseName(aDatabase);
346+
return DefaultRunnableSpec.this;
347+
}
348+
349+
@Override
350+
public <T> MappingSpec<T> fetchAs(Class<T> targetClass) {
351+
return DefaultRunnableSpec.this.fetchAs(targetClass);
352+
}
353+
354+
@Override
355+
public RecordFetchSpec<Map<String, Object>> fetch() {
356+
return DefaultRunnableSpec.this.fetch();
357+
}
358+
359+
@Override
360+
public Mono<ResultSummary> run() {
361+
return DefaultRunnableSpec.this.run();
362+
}
363+
364+
@Override
365+
public <T> Neo4jClient.OngoingBindSpec<T, RunnableSpec> bind(T value) {
366+
return DefaultRunnableSpec.this.bind(value);
367+
}
368+
369+
@Override
370+
public RunnableSpec bindAll(Map<String, Object> newParameters) {
371+
return DefaultRunnableSpec.this.bindAll(newParameters);
372+
}
297373
}
298374
}
299375

0 commit comments

Comments
 (0)