tinkerpop-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From spmalle...@apache.org
Subject [1/3] tinkerpop git commit: TINKERPOP-1903 Migrated Credential DSL to annotation processor
Date Thu, 19 Apr 2018 16:42:34 GMT
Repository: tinkerpop
Updated Branches:
  refs/heads/master 937915e30 -> bbe04dc2d


TINKERPOP-1903 Migrated Credential DSL to annotation processor

The old CredentialGraph approach to the Credential DSL has been deprecated in favor of the
preferred method for DSL development which was published long after the original DSL was developed.


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/bad59e50
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/bad59e50
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/bad59e50

Branch: refs/heads/master
Commit: bad59e50256604939394ec1bace299587db24422
Parents: d63638b
Author: Stephen Mallette <spmva@genoprime.com>
Authored: Thu Apr 5 11:51:49 2018 -0400
Committer: Stephen Mallette <spmva@genoprime.com>
Committed: Mon Apr 16 08:26:11 2018 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |   1 +
 .../src/reference/gremlin-applications.asciidoc |  31 ++--
 docs/src/upgrade/release-3.3.x.asciidoc         |  27 ++++
 .../jsr223/dsl/credential/CredentialGraph.java  |   2 +
 .../CredentialGraphGremlinPlugin.java           |   6 +-
 .../dsl/credential/CredentialTraversalDsl.java  |  74 ++++++++++
 .../CredentialTraversalSourceDsl.java           |  79 ++++++++++
 .../dsl/credential/CredentialGraphTest.java     |   4 +
 .../credential/CredentialTraversalDslTest.java  | 143 +++++++++++++++++++
 9 files changed, 354 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/bad59e50/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index a3512ec..45ac72c 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -26,6 +26,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 This release also includes changes from <<release-3-2-9, 3.2.9>>.
 
 * Coerced `BulkSet` to `g:List` in GraphSON 3.0.
+* Deprecated `CredentialsGraph` DSL in favor of `CredentialsTraversalDsl` which uses the
recommended method for Gremlin DSL development.
 
 [[release-3-3-2]]
 === TinkerPop 3.3.2 (Release Date: April 2, 2018)

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/bad59e50/docs/src/reference/gremlin-applications.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/gremlin-applications.asciidoc b/docs/src/reference/gremlin-applications.asciidoc
index 53a1642..f87499d 100644
--- a/docs/src/reference/gremlin-applications.asciidoc
+++ b/docs/src/reference/gremlin-applications.asciidoc
@@ -1351,9 +1351,9 @@ the `Graph`, consider specifying a unique constraint as well.
 
 To aid with the management of a credentials graph, Gremlin Server provides a Gremlin Console
plugin which can be
 used to add and remove users so as to ensure that the schema is adhered to, thus ensuring
compatibility with Gremlin
- Server.  In addition, as it is a plugin, it works naturally in the Gremlin Console as an
extension of its
- capabilities (though one could use it programmatically, if desired).  This plugin is distributed
with the Gremlin
- Console so it does not have to be "installed".  It does however need to be activated:
+Server. In addition, as it is a plugin, it works naturally in the Gremlin Console as an extension
of its
+capabilities (though one could use it programmatically, if desired). This plugin is distributed
with the Gremlin
+Console so it does not have to be "installed". It does however need to be activated:
 
 [source,groovy]
 gremlin> :plugin use tinkerpop.credentials
@@ -1365,15 +1365,22 @@ Please see the example usage as follows:
 ----
 graph = TinkerGraph.open()
 graph.createIndex("username",Vertex.class)
-credentials = credentials(graph)
-credentials.createUser("stephen","password")
-credentials.createUser("daniel","better-password")
-credentials.createUser("marko","rainbow-dash")
-credentials.findUser("marko").properties()
-credentials.countUsers()
-credentials.removeUser("daniel")
-credentials.countUsers()
-----
+credentials = graph.traversal(CredentialTraversalSource.class)
+credentials.user("stephen","password")
+credentials.user("daniel","better-password")
+credentials.user("marko","rainbow-dash")
+credentials.users("marko").valueMap()
+credentials.users().count()
+credentials.users("daniel").drop()
+credentials.users().count()
+----
+
+NOTE: The Credentials DSL is built using TinkerPop's DSL Annotation Processor described <<gremlin-java-dsl,here>>.
+
+IMPORTANT: In the above example, an empty in-memory TinkerGraph was used for demonstrating
the API of the DSL.
+Obviously, this data will not be retained and usable with Gremlin Server. It would be important
to configure
+TinkerGraph to persist that data or to manually persist it (e.g. write the graph data to
Gryo) once changes are
+complete. Alternatively, use a persistent graph to hold the credentials and configure Gremlin
Server accordingly.
 
 [[krb5authenticator]]
 ===== Kerberos Authentication

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/bad59e50/docs/src/upgrade/release-3.3.x.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/upgrade/release-3.3.x.asciidoc b/docs/src/upgrade/release-3.3.x.asciidoc
index 9ff7b4d..79b7ef5 100644
--- a/docs/src/upgrade/release-3.3.x.asciidoc
+++ b/docs/src/upgrade/release-3.3.x.asciidoc
@@ -23,6 +23,33 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 
 == TinkerPop 3.3.2
 
+*Release Date: NOT OFFICIALLY RELEASED YET*
+
+Please see the link:https://github.com/apache/tinkerpop/blob/3.3.3/CHANGELOG.asciidoc#release-3-3-3[changelog]
for a complete list of all the modifications that are part of this release.
+
+=== Upgrading for Users
+
+==== Credential DSL Changes
+
+The Credential DSL has been modified to work as a standard Java-based Gremlin DSL. The now
deprecated old approach
+used a "graph wrapping" style that was developed long before the
+link:http://tinkerpop.apache.org/docs/current/reference/#gremlin-java-dsl[recommended method]
for building DSLs was
+published. Under this new model, the DSL is initialized via traversal as follows:
+
+[source,java]
+----
+CredentialTraversalSource credentials = graph.traversal(CredentialTraversalSource.class)
+credentials.user("stephen","password").iterate()
+credentials.users("stephen").valueMap().next()
+credentials.users().count().next()
+credentials.users("stephen").drop().iterate()
+----
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-1903[TINKERPOP-1903],
+link:http://tinkerpop.apache.org/docs/3.3.2/reference/#security[Reference Documentation -
Security]
+
+== TinkerPop 3.3.2
+
 *Release Date: April 2, 2018*
 
 Please see the link:https://github.com/apache/tinkerpop/blob/3.3.2/CHANGELOG.asciidoc#release-3-3-2[changelog]
for a complete list of all the modifications that are part of this release.

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/bad59e50/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraph.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraph.java
b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraph.java
index 9220282..0ae8e00 100644
--- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraph.java
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraph.java
@@ -32,7 +32,9 @@ import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.drop;
  * {@link Graph} is transactional, new transactions will be started for each method call.
  *
  * @author Stephen Mallette (http://stephen.genoprime.com)
+ * @deprecated As of release 3.3.3, replaced by {@link  CredentialTraversalDsl}.
  */
+@Deprecated
 public class CredentialGraph {
 
     private final int BCRYPT_ROUNDS = 4;

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/bad59e50/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraphGremlinPlugin.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraphGremlinPlugin.java
b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraphGremlinPlugin.java
index 7b6bd64..e36dff9 100644
--- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraphGremlinPlugin.java
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraphGremlinPlugin.java
@@ -24,7 +24,8 @@ import org.apache.tinkerpop.gremlin.jsr223.ImportCustomizer;
 import org.apache.tinkerpop.gremlin.structure.Graph;
 
 /**
- * Plugin for the "credentials graph".  This plugin imports the {@link CredentialGraph} to
its environment.
+ * Plugin for the Credentials DSL that helps maintain a list of users and passwords in a
graph for use with Gremlin
+ * Server authentication.
  *
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
@@ -38,6 +39,9 @@ public class CredentialGraphGremlinPlugin extends AbstractGremlinPlugin
{
         try {
             imports = DefaultImportCustomizer.build()
                     .addClassImports(CredentialGraph.class)
+                    .addClassImports(CredentialTraversalDsl.class)
+                    .addClassImports(CredentialTraversal.class)
+                    .addClassImports(CredentialTraversalSource.class)
                     .addMethodImports(CredentialGraph.class.getMethod("credentials", Graph.class))
                     .create();
         } catch (Exception ex) {

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/bad59e50/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalDsl.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalDsl.java
b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalDsl.java
new file mode 100644
index 0000000..e94720a
--- /dev/null
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalDsl.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential;
+
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.GremlinDsl;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.mindrot.jbcrypt.BCrypt;
+
+import java.util.Arrays;
+
+import static org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.CredentialGraphTokens.PROPERTY_PASSWORD;
+import static org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.CredentialGraphTokens.PROPERTY_USERNAME;
+import static org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.CredentialGraphTokens.VERTEX_LABEL_USER;
+
+/**
+ * A DSL for managing a "credentials graph" used by Gremlin Server for simple authentication
functions.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+@GremlinDsl(traversalSource = "org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.CredentialTraversalSourceDsl")
+public interface CredentialTraversalDsl<S,E> extends GraphTraversal.Admin<S,E>
{
+    static final int BCRYPT_ROUNDS = 4;
+
+    /**
+     * Finds all users.
+     */
+    public default GraphTraversal<S, Vertex> users() {
+        return (CredentialTraversal<S, Vertex>) hasLabel(VERTEX_LABEL_USER);
+    }
+
+    /**
+     * Finds users by name.
+     */
+    public default GraphTraversal<S, Vertex> users(final String username, final String...
more) {
+        if (more.length == 0) {
+            return (CredentialTraversal<S, Vertex>) has(VERTEX_LABEL_USER, PROPERTY_USERNAME,
username);
+        }
+
+        final int lastIndex;
+        final String[] usernames = Arrays.copyOf(more, (lastIndex = more.length) + 1);
+        usernames[lastIndex] = username;
+        return (CredentialTraversal<S, Vertex>)has(VERTEX_LABEL_USER, PROPERTY_USERNAME,
P.within(usernames));
+    }
+
+    /**
+     * Creates or updates a user.
+     */
+    public default GraphTraversal<S, Vertex> user(final String username, final String
password) {
+        return has(VERTEX_LABEL_USER, PROPERTY_USERNAME, username).
+               fold().
+               coalesce(__.unfold(),
+                        __.addV(VERTEX_LABEL_USER).property(PROPERTY_USERNAME, username)).
+               property(PROPERTY_PASSWORD, BCrypt.hashpw(password, BCrypt.gensalt(CredentialTraversalDsl.BCRYPT_ROUNDS)));
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/bad59e50/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalSourceDsl.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalSourceDsl.java
b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalSourceDsl.java
new file mode 100644
index 0000000..68b24b2
--- /dev/null
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalSourceDsl.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential;
+
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.mindrot.jbcrypt.BCrypt;
+
+import java.util.Arrays;
+
+import static org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.CredentialGraphTokens.PROPERTY_PASSWORD;
+import static org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.CredentialGraphTokens.PROPERTY_USERNAME;
+import static org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.CredentialGraphTokens.VERTEX_LABEL_USER;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class CredentialTraversalSourceDsl extends GraphTraversalSource {
+    public CredentialTraversalSourceDsl(final Graph graph, final TraversalStrategies traversalStrategies)
{
+        super(graph, traversalStrategies);
+    }
+
+    public CredentialTraversalSourceDsl(final Graph graph) {
+        super(graph);
+    }
+
+    /**
+     * Finds all users.
+     */
+    public GraphTraversal<Vertex, Vertex> users() {
+        return this.clone().V().hasLabel(VERTEX_LABEL_USER);
+    }
+
+    /**
+     * Finds users by name.
+     */
+    public GraphTraversal<Vertex, Vertex> users(final String username, final String...
more) {
+        if (more.length == 0) {
+            return this.clone().V().has(VERTEX_LABEL_USER, PROPERTY_USERNAME, username);
+        }
+
+        final int lastIndex;
+        final String[] usernames = Arrays.copyOf(more, (lastIndex = more.length) + 1);
+        usernames[lastIndex] = username;
+        return this.clone().V().has(VERTEX_LABEL_USER, PROPERTY_USERNAME, P.within(usernames));
+    }
+
+    /**
+     * Creates or updates a user.
+     */
+    public GraphTraversal<Vertex, Vertex> user(final String username, final String
password) {
+        return this.clone().V().
+                has(VERTEX_LABEL_USER, PROPERTY_USERNAME, username).
+                fold().
+                coalesce(__.unfold(),
+                         __.addV(VERTEX_LABEL_USER).property(PROPERTY_USERNAME, username)).
+                property(PROPERTY_PASSWORD, BCrypt.hashpw(password, BCrypt.gensalt(CredentialTraversalDsl.BCRYPT_ROUNDS)));
+    }
+}

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/bad59e50/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraphTest.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraphTest.java
b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraphTest.java
index 3fef17e..7e054ce 100644
--- a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraphTest.java
+++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialGraphTest.java
@@ -33,8 +33,12 @@ import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNull;
 
 /**
+ * These tests cover old functionality prior to the new method for DSL implementation.
+ *
  * @author Stephen Mallette (http://stephen.genoprime.com)
+ * @deprecated As for release 3.3.3, replaced by {@link CredentialTraversalDslTest}.
  */
+@Deprecated
 public class CredentialGraphTest {
 
     @Test

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/bad59e50/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalDslTest.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalDslTest.java
b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalDslTest.java
new file mode 100644
index 0000000..8c5a6bd
--- /dev/null
+++ b/gremlin-groovy/src/test/java/org/apache/tinkerpop/gremlin/groovy/jsr223/dsl/credential/CredentialTraversalDslTest.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential;
+
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
+import org.junit.Test;
+
+import static org.apache.tinkerpop.gremlin.groovy.jsr223.dsl.credential.CredentialGraphTokens.PROPERTY_USERNAME;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class CredentialTraversalDslTest {
+
+    @Test
+    public void shouldCreateUser() {
+        final Graph graph = TinkerGraph.open();
+        final CredentialTraversalSource g = graph.traversal(CredentialTraversalSource.class);
+        final Vertex v = g.user("stephen", "secret").next();
+        assertEquals("stephen", v.value("username"));
+        assertEquals("user", v.label());
+        assertNotEquals("secret", v.value("password"));  // hashed to something
+        assertThat(v.value("password").toString().length(), greaterThan(0));
+    }
+
+    @Test
+    public void shouldRemoveUser() {
+        final Graph graph = TinkerGraph.open();
+        final CredentialTraversalSource g = graph.traversal(CredentialTraversalSource.class);
+        assertThat(graph.vertices().hasNext(), is(false));
+        g.user("stephen", "secret").iterate();
+        assertThat(graph.vertices().hasNext(), is(true));
+
+        g.users("stephen").drop().iterate();
+        assertThat(graph.vertices().hasNext(), is(false));
+    }
+
+    @Test
+    public void shouldNotRemoveUser() {
+        final Graph graph = TinkerGraph.open();
+        final CredentialTraversalSource g = graph.traversal(CredentialTraversalSource.class);
+        assertThat(graph.vertices().hasNext(), is(false));
+        g.user("stephen", "secret").iterate();
+        assertThat(graph.vertices().hasNext(), is(true));
+
+        g.users("stephanie").drop().iterate();
+        assertThat(graph.vertices().hasNext(), is(true));
+    }
+
+    @Test
+    public void shouldFindUser() {
+        final Graph graph = TinkerGraph.open();
+        final CredentialTraversalSource g = graph.traversal(CredentialTraversalSource.class);
+        assertThat(graph.vertices().hasNext(), is(false));
+        g.user("marko", "secret").iterate();
+        final Vertex stephen = g.user("stephen", "secret").next();
+        g.user("daniel", "secret").iterate();
+        assertThat(graph.vertices().hasNext(), is(true));
+
+        assertEquals(stephen, g.users("stephen").next());
+    }
+
+    @Test
+    public void shouldFindSeveralUsers() {
+        final Graph graph = TinkerGraph.open();
+        final CredentialTraversalSource g = graph.traversal(CredentialTraversalSource.class);
+        assertThat(graph.vertices().hasNext(), is(false));
+        g.user("marko", "secret").iterate();
+        g.user("daniel", "secret").iterate();
+        g.user("stephen", "secret").iterate();
+        assertThat(graph.vertices().hasNext(), is(true));
+
+        assertThat(g.users("stephen", "marko").values(PROPERTY_USERNAME).toList(), containsInAnyOrder("stephen",
"marko"));
+    }
+
+    @Test
+    public void shouldNotFindUser() {
+        final Graph graph = TinkerGraph.open();
+        final CredentialTraversalSource g = graph.traversal(CredentialTraversalSource.class);
+        assertThat(graph.vertices().hasNext(), is(false));
+        g.user("marko", "secret").iterate();
+        g.user("daniel", "secret").iterate();
+        g.user("stephen", "secret").iterate();
+        assertThat(graph.vertices().hasNext(), is(true));
+
+        assertThat(g.users("stephanie").hasNext(), is(false));
+    }
+
+    @Test
+    public void shouldCountUsers() {
+        final Graph graph = TinkerGraph.open();
+        final CredentialTraversalSource g = graph.traversal(CredentialTraversalSource.class);
+        assertThat(graph.vertices().hasNext(), is(false));
+        g.user("marko", "secret").iterate();
+        g.user("daniel", "secret").iterate();
+        g.user("stephen", "secret").iterate();
+        assertThat(graph.vertices().hasNext(), is(true));
+
+        assertEquals(3, g.users().count().next().intValue());
+    }
+
+    @Test
+    public void shouldUpdateUser() {
+        final Graph graph = TinkerGraph.open();
+        final CredentialTraversalSource g = graph.traversal(CredentialTraversalSource.class);
+        final Vertex v = g.user("stephen", "secret").next();
+        assertEquals("stephen", v.value("username"));
+        assertEquals("user", v.label());
+        assertNotEquals("secret", v.value("password"));  // hashed to something
+        assertThat(v.value("password").toString().length(), greaterThan(0));
+
+        final String hashOfSecret = v.value("password").toString();
+
+        g.user("stephen", "new-secret").iterate();
+
+        assertNotEquals(hashOfSecret, g.users("stephen").values("password").next());
+        assertEquals(1, g.users("stephen").count().next().intValue());
+    }
+}


Mime
View raw message