You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2015/07/17 22:38:29 UTC

[2/2] incubator-tinkerpop git commit: Move the Credentials DSL to gremlin-groovy.

Move the Credentials DSL to gremlin-groovy.

In this way, the DSL does not need to be "installed" in the console.  If it had stayed on the server the user would have had to ":install gremlin-server" which is kinda weird (especially for just one little class).  Perhaps this is the way to go for future DSLs that we might want to support - kinda fits here in a way. Plus there is the added bonus that the DSL undergoes testing in the GroovyEnvironmentSuite which means it gets validated against all the graphs out there that run that suite.


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

Branch: refs/heads/auth
Commit: 221c7721b9e58f7995bd7953c0f6013e46a6958d
Parents: 10792dc
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Fri Jul 17 16:36:21 2015 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Fri Jul 17 16:36:21 2015 -0400

----------------------------------------------------------------------
 .../gremlin/groovy/GroovyEnvironmentSuite.java  |   2 +
 .../dsl/credential/CredentialGraphTest.java     | 110 ++++++++++++++++
 gremlin-groovy/pom.xml                          |   5 +
 .../plugin/dsl/credential/CredentialGraph.java  | 120 ++++++++++++++++++
 .../CredentialGraphGremlinPlugin.java           |  53 ++++++++
 .../dsl/credential/CredentialGraphTokens.java   |  31 +++++
 ...inkerpop.gremlin.groovy.plugin.GremlinPlugin |   3 +-
 gremlin-server/pom.xml                          |   5 -
 .../server/auth/SimpleAuthenticator.java        |   6 +-
 .../auth/groovy/plugin/CredentialGraph.java     | 124 -------------------
 .../plugin/CredentialGraphGremlinPlugin.java    |  53 --------
 .../groovy/plugin/CredentialGraphTokens.java    |  31 -----
 ...inkerpop.gremlin.groovy.plugin.GremlinPlugin |   1 -
 .../auth/groovy/plugin/CredentialGraphTest.java | 117 -----------------
 14 files changed, 326 insertions(+), 335 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/221c7721/gremlin-groovy-test/src/main/java/org/apache/tinkerpop/gremlin/groovy/GroovyEnvironmentSuite.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy-test/src/main/java/org/apache/tinkerpop/gremlin/groovy/GroovyEnvironmentSuite.java b/gremlin-groovy-test/src/main/java/org/apache/tinkerpop/gremlin/groovy/GroovyEnvironmentSuite.java
index 2fb9e8e..a32e170 100644
--- a/gremlin-groovy-test/src/main/java/org/apache/tinkerpop/gremlin/groovy/GroovyEnvironmentSuite.java
+++ b/gremlin-groovy-test/src/main/java/org/apache/tinkerpop/gremlin/groovy/GroovyEnvironmentSuite.java
@@ -28,6 +28,7 @@ import org.apache.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngineSandb
 import org.apache.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngineTinkerPopSandboxTest;
 import org.apache.tinkerpop.gremlin.groovy.loaders.SugarLoader;
 import org.apache.tinkerpop.gremlin.groovy.loaders.SugarLoaderTest;
+import org.apache.tinkerpop.gremlin.groovy.plugin.dsl.credential.CredentialGraphTest;
 import org.apache.tinkerpop.gremlin.groovy.util.SugarTestHelper;
 import org.apache.tinkerpop.gremlin.process.traversal.TraversalEngine;
 import org.apache.tinkerpop.gremlin.structure.Graph;
@@ -52,6 +53,7 @@ public class GroovyEnvironmentSuite extends AbstractGremlinSuite {
      * as needed to enforce tests upon implementations.
      */
     private static final Class<?>[] allTests = new Class<?>[]{
+            CredentialGraphTest.class,
             GremlinGroovyScriptEngineOverGraphTest.class,
             GremlinGroovyScriptEngineSandboxCustomTest.class,
             GremlinGroovyScriptEngineSandboxedStandardTest.class,

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/221c7721/gremlin-groovy-test/src/main/java/org/apache/tinkerpop/gremlin/groovy/plugin/dsl/credential/CredentialGraphTest.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy-test/src/main/java/org/apache/tinkerpop/gremlin/groovy/plugin/dsl/credential/CredentialGraphTest.java b/gremlin-groovy-test/src/main/java/org/apache/tinkerpop/gremlin/groovy/plugin/dsl/credential/CredentialGraphTest.java
new file mode 100644
index 0000000..93feb4b
--- /dev/null
+++ b/gremlin-groovy-test/src/main/java/org/apache/tinkerpop/gremlin/groovy/plugin/dsl/credential/CredentialGraphTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.plugin.dsl.credential;
+
+import org.apache.tinkerpop.gremlin.AbstractGremlinTest;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.hamcrest.MatcherAssert;
+import org.junit.Test;
+
+import static org.apache.tinkerpop.gremlin.groovy.plugin.dsl.credential.CredentialGraph.*;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class CredentialGraphTest extends AbstractGremlinTest {
+
+    @Test
+    public void shouldCreateUser() {
+        final Vertex v = credentials(graph).createUser("stephen", "secret");
+        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() {
+        MatcherAssert.assertThat(graph.vertices().hasNext(), is(false));
+        credentials(graph).createUser("stephen", "secret");
+        MatcherAssert.assertThat(graph.vertices().hasNext(), is(true));
+
+        assertEquals(1, credentials(graph).removeUser("stephen"));
+        MatcherAssert.assertThat(graph.vertices().hasNext(), is(false));
+    }
+
+    @Test
+    public void shouldNotRemoveUser() {
+        MatcherAssert.assertThat(graph.vertices().hasNext(), is(false));
+        credentials(graph).createUser("stephen", "secret");
+        MatcherAssert.assertThat(graph.vertices().hasNext(), is(true));
+
+        assertEquals(0, credentials(graph).removeUser("stephanie"));
+        MatcherAssert.assertThat(graph.vertices().hasNext(), is(true));
+    }
+
+    @Test
+    public void shouldFindUser() {
+        MatcherAssert.assertThat(graph.vertices().hasNext(), is(false));
+        credentials(graph).createUser("marko", "secret");
+        final Vertex stephen = credentials(graph).createUser("stephen", "secret");
+        credentials(graph).createUser("daniel", "secret");
+        MatcherAssert.assertThat(graph.vertices().hasNext(), is(true));
+
+        assertEquals(stephen, credentials(graph).findUser("stephen"));
+    }
+
+    @Test
+    public void shouldNotFindUser() {
+        MatcherAssert.assertThat(graph.vertices().hasNext(), is(false));
+        credentials(graph).createUser("marko", "secret");
+        credentials(graph).createUser("stephen", "secret");
+        credentials(graph).createUser("daniel", "secret");
+        MatcherAssert.assertThat(graph.vertices().hasNext(), is(true));
+
+        assertNull(credentials(graph).findUser("stephanie"));
+    }
+
+    @Test
+    public void shouldCountUsers() {
+        MatcherAssert.assertThat(graph.vertices().hasNext(), is(false));
+        credentials(graph).createUser("marko", "secret");
+        credentials(graph).createUser("stephen", "secret");
+        credentials(graph).createUser("daniel", "secret");
+        MatcherAssert.assertThat(graph.vertices().hasNext(), is(true));
+
+        assertEquals(3, credentials(graph).countUsers());
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void shouldThrowIfFindingMultipleUsers() {
+        MatcherAssert.assertThat(graph.vertices().hasNext(), is(false));
+        credentials(graph).createUser("stephen", "secret");
+        credentials(graph).createUser("stephen", "secret");
+        MatcherAssert.assertThat(graph.vertices().hasNext(), is(true));
+
+        assertNull(credentials(graph).findUser("stephen"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/221c7721/gremlin-groovy/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-groovy/pom.xml b/gremlin-groovy/pom.xml
index 7fe90d3..69b5e0c 100644
--- a/gremlin-groovy/pom.xml
+++ b/gremlin-groovy/pom.xml
@@ -66,6 +66,11 @@ limitations under the License.
             <version>3.3.1</version>
         </dependency>
         <dependency>
+            <groupId>org.mindrot</groupId>
+            <artifactId>jbcrypt</artifactId>
+            <version>0.3m</version>
+        </dependency>
+        <dependency>
             <groupId>org.apache.tinkerpop</groupId>
             <artifactId>gremlin-test</artifactId>
             <version>${project.version}</version>

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/221c7721/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/plugin/dsl/credential/CredentialGraph.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/plugin/dsl/credential/CredentialGraph.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/plugin/dsl/credential/CredentialGraph.java
new file mode 100644
index 0000000..a766f46
--- /dev/null
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/plugin/dsl/credential/CredentialGraph.java
@@ -0,0 +1,120 @@
+/*
+ * 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.plugin.dsl.credential;
+
+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.T;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.mindrot.jbcrypt.BCrypt;
+
+import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.drop;
+
+/**
+ * A DSL for managing a "credentials graph" used by Gremlin Server for simple authentication functions.  If the
+ * {@link Graph} is transactional, new transactions will be started for each method call.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class CredentialGraph {
+
+    private final Graph graph;
+    private final GraphTraversalSource g;
+    private final boolean supportsTransactions;
+
+    public CredentialGraph(final Graph graph) {
+        this.graph = graph;
+        g = graph.traversal();
+        supportsTransactions = graph.features().graph().supportsTransactions();
+    }
+
+    /**
+     * Finds a user by username and return {@code null} if one could not be found.
+     *
+     * @throws IllegalStateException if there is more than one user with a particular username.
+     */
+    public Vertex findUser(final String username) {
+        if (supportsTransactions) g.tx().rollback();
+        final GraphTraversal<Vertex,Vertex> t = g.V().has(CredentialGraphTokens.PROPERTY_USERNAME, username);
+        final Vertex v = t.hasNext() ? t.next() : null;
+        if (t.hasNext()) throw new IllegalStateException(String.format("Multiple users with username %s", username));
+        return v;
+    }
+
+    /**
+     * Creates a new user.
+     *
+     * @return the newly created user vertex
+     */
+    public Vertex createUser(final String username, final String password) {
+        if (findUser(username) != null) throw new IllegalStateException("User with this name already exists");
+        if (supportsTransactions) graph.tx().rollback();
+
+        try {
+            final Vertex v =  graph.addVertex(T.label, CredentialGraphTokens.VERTEX_LABEL_USER,
+                                              CredentialGraphTokens.PROPERTY_USERNAME, username,
+                                              CredentialGraphTokens.PROPERTY_PASSWORD, BCrypt.hashpw(password, BCrypt.gensalt()));
+            if (supportsTransactions) graph.tx().commit();
+            return v;
+        } catch (Exception ex) {
+            if (supportsTransactions) graph.tx().rollback();
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * Removes a user by name.
+     *
+     * @return the number of users removed (which should be one or zero)
+     */
+    public long removeUser(final String username) {
+        if (supportsTransactions) graph.tx().rollback();
+        try {
+            final long count = g.V().has(CredentialGraphTokens.PROPERTY_USERNAME, username).sideEffect(drop()).count().next();
+            if (supportsTransactions) graph.tx().commit();
+            return count;
+        } catch (Exception ex) {
+            if (supportsTransactions) graph.tx().rollback();
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * Get a count of the number of users in the database.
+     */
+    public long countUsers() {
+        if (supportsTransactions) graph.tx().rollback();
+        return g.V().hasLabel(CredentialGraphTokens.VERTEX_LABEL_USER).count().next();
+    }
+
+    @Override
+    public String toString() {
+        return "CredentialGraph{" +
+                "graph=" + graph +
+                '}';
+    }
+
+    /**
+     * Wrap up any {@link Graph} instance in the {@code CredentialGraph} DSL.
+     */
+    public static CredentialGraph credentials(final Graph graph) {
+        return new CredentialGraph(graph);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/221c7721/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/plugin/dsl/credential/CredentialGraphGremlinPlugin.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/plugin/dsl/credential/CredentialGraphGremlinPlugin.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/plugin/dsl/credential/CredentialGraphGremlinPlugin.java
new file mode 100644
index 0000000..9bf7880
--- /dev/null
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/plugin/dsl/credential/CredentialGraphGremlinPlugin.java
@@ -0,0 +1,53 @@
+/*
+ * 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.plugin.dsl.credential;
+
+import org.apache.tinkerpop.gremlin.groovy.plugin.AbstractGremlinPlugin;
+import org.apache.tinkerpop.gremlin.groovy.plugin.IllegalEnvironmentException;
+import org.apache.tinkerpop.gremlin.groovy.plugin.PluginAcceptor;
+import org.apache.tinkerpop.gremlin.groovy.plugin.PluginInitializationException;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class CredentialGraphGremlinPlugin extends AbstractGremlinPlugin {
+
+    private static final Set<String> IMPORTS = new HashSet<String>() {{
+        add(IMPORT_SPACE + CredentialGraph.class.getName());
+        add(IMPORT_STATIC_SPACE + CredentialGraph.class.getName() + DOT_STAR);
+    }};
+
+    @Override
+    public String getName() {
+        return "tinkerpop.credentials";
+    }
+
+    @Override
+    public void pluginTo(final PluginAcceptor pluginAcceptor) throws PluginInitializationException, IllegalEnvironmentException {
+        pluginAcceptor.addImports(IMPORTS);
+    }
+
+    @Override
+    public void afterPluginTo(final PluginAcceptor pluginAcceptor) throws IllegalEnvironmentException, PluginInitializationException {
+
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/221c7721/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/plugin/dsl/credential/CredentialGraphTokens.java
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/plugin/dsl/credential/CredentialGraphTokens.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/plugin/dsl/credential/CredentialGraphTokens.java
new file mode 100644
index 0000000..0cb2543
--- /dev/null
+++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/plugin/dsl/credential/CredentialGraphTokens.java
@@ -0,0 +1,31 @@
+/*
+ * 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.plugin.dsl.credential;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public final class CredentialGraphTokens {
+    public static final String PROPERTY_USERNAME = "username";
+    public static final String PROPERTY_PASSWORD = "password";
+
+    public static final String VERTEX_LABEL_USER = "user";
+
+    private CredentialGraphTokens() {}
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/221c7721/gremlin-groovy/src/main/resources/META-INF/services/org.apache.tinkerpop.gremlin.groovy.plugin.GremlinPlugin
----------------------------------------------------------------------
diff --git a/gremlin-groovy/src/main/resources/META-INF/services/org.apache.tinkerpop.gremlin.groovy.plugin.GremlinPlugin b/gremlin-groovy/src/main/resources/META-INF/services/org.apache.tinkerpop.gremlin.groovy.plugin.GremlinPlugin
index 75f65ae..79f20cd 100644
--- a/gremlin-groovy/src/main/resources/META-INF/services/org.apache.tinkerpop.gremlin.groovy.plugin.GremlinPlugin
+++ b/gremlin-groovy/src/main/resources/META-INF/services/org.apache.tinkerpop.gremlin.groovy.plugin.GremlinPlugin
@@ -1 +1,2 @@
-org.apache.tinkerpop.gremlin.groovy.plugin.SugarGremlinPlugin
\ No newline at end of file
+org.apache.tinkerpop.gremlin.groovy.plugin.SugarGremlinPlugin
+org.apache.tinkerpop.gremlin.groovy.plugin.dsl.credential.CredentialGraphGremlinPlugin
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/221c7721/gremlin-server/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-server/pom.xml b/gremlin-server/pom.xml
index 3ea7d08..9a9a110 100644
--- a/gremlin-server/pom.xml
+++ b/gremlin-server/pom.xml
@@ -46,11 +46,6 @@ limitations under the License.
             <artifactId>commons-collections</artifactId>
             <version>3.2.1</version>
         </dependency>
-        <dependency>
-            <groupId>org.mindrot</groupId>
-            <artifactId>jbcrypt</artifactId>
-            <version>0.3m</version>
-        </dependency>
         <!-- METRICS -->
         <dependency>
             <groupId>com.codahale.metrics</groupId>

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/221c7721/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/SimpleAuthenticator.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/SimpleAuthenticator.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/SimpleAuthenticator.java
index 17da264..123e95b 100644
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/SimpleAuthenticator.java
+++ b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/SimpleAuthenticator.java
@@ -18,7 +18,7 @@
  */
 package org.apache.tinkerpop.gremlin.server.auth;
 
-import org.apache.tinkerpop.gremlin.server.auth.groovy.plugin.CredentialGraph;
+import org.apache.tinkerpop.gremlin.groovy.plugin.dsl.credential.CredentialGraph;
 import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.io.IoCore;
@@ -33,8 +33,8 @@ import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.Map;
 
-import static org.apache.tinkerpop.gremlin.server.auth.groovy.plugin.CredentialGraphTokens.PROPERTY_PASSWORD;
-import static org.apache.tinkerpop.gremlin.server.auth.groovy.plugin.CredentialGraphTokens.PROPERTY_USERNAME;
+import static org.apache.tinkerpop.gremlin.groovy.plugin.dsl.credential.CredentialGraphTokens.PROPERTY_PASSWORD;
+import static org.apache.tinkerpop.gremlin.groovy.plugin.dsl.credential.CredentialGraphTokens.PROPERTY_USERNAME;
 
 /**
  * @author Stephen Mallette (http://stephen.genoprime.com)

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/221c7721/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/groovy/plugin/CredentialGraph.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/groovy/plugin/CredentialGraph.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/groovy/plugin/CredentialGraph.java
deleted file mode 100644
index d5d8b65..0000000
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/groovy/plugin/CredentialGraph.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * 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.server.auth.groovy.plugin;
-
-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.T;
-import org.apache.tinkerpop.gremlin.structure.Vertex;
-import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
-import org.mindrot.jbcrypt.BCrypt;
-
-import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.drop;
-import static org.apache.tinkerpop.gremlin.server.auth.groovy.plugin.CredentialGraphTokens.PROPERTY_PASSWORD;
-import static org.apache.tinkerpop.gremlin.server.auth.groovy.plugin.CredentialGraphTokens.PROPERTY_USERNAME;
-import static org.apache.tinkerpop.gremlin.server.auth.groovy.plugin.CredentialGraphTokens.VERTEX_LABEL_USER;
-
-/**
- * A DSL for managing a "credentials graph" used by Gremlin Server for simple authentication functions.  If the
- * {@link Graph} is transactional, new transactions will be started for each method call.
- *
- * @author Stephen Mallette (http://stephen.genoprime.com)
- */
-public class CredentialGraph {
-
-    private final Graph graph;
-    private final GraphTraversalSource g;
-    private final boolean supportsTransactions;
-
-    public CredentialGraph(final Graph graph) {
-        this.graph = graph;
-        g = graph.traversal();
-        supportsTransactions = graph.features().graph().supportsTransactions();
-    }
-
-    /**
-     * Finds a user by username and return {@code null} if one could not be found.
-     *
-     * @throws IllegalStateException if there is more than one user with a particular username.
-     */
-    public Vertex findUser(final String username) {
-        if (supportsTransactions) g.tx().rollback();
-        final GraphTraversal<Vertex,Vertex> t = g.V().has(PROPERTY_USERNAME, username);
-        final Vertex v = t.hasNext() ? t.next() : null;
-        if (t.hasNext()) throw new IllegalStateException(String.format("Multiple users with username %s", username));
-        return v;
-    }
-
-    /**
-     * Creates a new user.
-     *
-     * @return the newly created user vertex
-     */
-    public Vertex createUser(final String username, final String password) {
-        if (findUser(username) != null) throw new IllegalStateException("User with this name already exists");
-        if (supportsTransactions) graph.tx().rollback();
-
-        try {
-            final Vertex v =  graph.addVertex(T.label, VERTEX_LABEL_USER,
-                                              PROPERTY_USERNAME, username,
-                                              PROPERTY_PASSWORD, BCrypt.hashpw(password, BCrypt.gensalt()));
-            if (supportsTransactions) graph.tx().commit();
-            return v;
-        } catch (Exception ex) {
-            if (supportsTransactions) graph.tx().rollback();
-            throw new RuntimeException(ex);
-        }
-    }
-
-    /**
-     * Removes a user by name.
-     *
-     * @return the number of users removed (which should be one or zero)
-     */
-    public long removeUser(final String username) {
-        if (supportsTransactions) graph.tx().rollback();
-        try {
-            final long count = g.V().has(PROPERTY_USERNAME, username).sideEffect(drop()).count().next();
-            if (supportsTransactions) graph.tx().commit();
-            return count;
-        } catch (Exception ex) {
-            if (supportsTransactions) graph.tx().rollback();
-            throw new RuntimeException(ex);
-        }
-    }
-
-    /**
-     * Get a count of the number of users in the database.
-     */
-    public long countUsers() {
-        if (supportsTransactions) graph.tx().rollback();
-        return g.V().hasLabel(VERTEX_LABEL_USER).count().next();
-    }
-
-    @Override
-    public String toString() {
-        return "CredentialGraph{" +
-                "graph=" + graph +
-                '}';
-    }
-
-    /**
-     * Wrap up any {@link Graph} instance in the {@code CredentialGraph} DSL.
-     */
-    public static CredentialGraph credentials(final Graph graph) {
-        return new CredentialGraph(graph);
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/221c7721/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/groovy/plugin/CredentialGraphGremlinPlugin.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/groovy/plugin/CredentialGraphGremlinPlugin.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/groovy/plugin/CredentialGraphGremlinPlugin.java
deleted file mode 100644
index 2d719f0..0000000
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/groovy/plugin/CredentialGraphGremlinPlugin.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.server.auth.groovy.plugin;
-
-import org.apache.tinkerpop.gremlin.groovy.plugin.AbstractGremlinPlugin;
-import org.apache.tinkerpop.gremlin.groovy.plugin.IllegalEnvironmentException;
-import org.apache.tinkerpop.gremlin.groovy.plugin.PluginAcceptor;
-import org.apache.tinkerpop.gremlin.groovy.plugin.PluginInitializationException;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * @author Stephen Mallette (http://stephen.genoprime.com)
- */
-public class CredentialGraphGremlinPlugin extends AbstractGremlinPlugin {
-
-    private static final Set<String> IMPORTS = new HashSet<String>() {{
-        add(IMPORT_SPACE + CredentialGraph.class.getName());
-        add(IMPORT_STATIC_SPACE + CredentialGraph.class.getName() + DOT_STAR);
-    }};
-
-    @Override
-    public String getName() {
-        return "tinkerpop.server.credentials";
-    }
-
-    @Override
-    public void pluginTo(final PluginAcceptor pluginAcceptor) throws PluginInitializationException, IllegalEnvironmentException {
-        pluginAcceptor.addImports(IMPORTS);
-    }
-
-    @Override
-    public void afterPluginTo(final PluginAcceptor pluginAcceptor) throws IllegalEnvironmentException, PluginInitializationException {
-
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/221c7721/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/groovy/plugin/CredentialGraphTokens.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/groovy/plugin/CredentialGraphTokens.java b/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/groovy/plugin/CredentialGraphTokens.java
deleted file mode 100644
index 4e3aa13..0000000
--- a/gremlin-server/src/main/java/org/apache/tinkerpop/gremlin/server/auth/groovy/plugin/CredentialGraphTokens.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.server.auth.groovy.plugin;
-
-/**
- * @author Stephen Mallette (http://stephen.genoprime.com)
- */
-public final class CredentialGraphTokens {
-    public static final String PROPERTY_USERNAME = "username";
-    public static final String PROPERTY_PASSWORD = "password";
-
-    public static final String VERTEX_LABEL_USER = "user";
-
-    private CredentialGraphTokens() {}
-}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/221c7721/gremlin-server/src/main/resources/META-INF/services/org.apache.tinkerpop.gremlin.groovy.plugin.GremlinPlugin
----------------------------------------------------------------------
diff --git a/gremlin-server/src/main/resources/META-INF/services/org.apache.tinkerpop.gremlin.groovy.plugin.GremlinPlugin b/gremlin-server/src/main/resources/META-INF/services/org.apache.tinkerpop.gremlin.groovy.plugin.GremlinPlugin
deleted file mode 100644
index 681bac1..0000000
--- a/gremlin-server/src/main/resources/META-INF/services/org.apache.tinkerpop.gremlin.groovy.plugin.GremlinPlugin
+++ /dev/null
@@ -1 +0,0 @@
-org.apache.tinkerpop.gremlin.server.auth.groovy.plugin.CredentialGraphGremlinPlugin
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/221c7721/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/auth/groovy/plugin/CredentialGraphTest.java
----------------------------------------------------------------------
diff --git a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/auth/groovy/plugin/CredentialGraphTest.java b/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/auth/groovy/plugin/CredentialGraphTest.java
deleted file mode 100644
index e8d5b9c..0000000
--- a/gremlin-server/src/test/java/org/apache/tinkerpop/gremlin/server/auth/groovy/plugin/CredentialGraphTest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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.server.auth.groovy.plugin;
-
-import org.apache.tinkerpop.gremlin.structure.Vertex;
-import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.apache.tinkerpop.gremlin.server.auth.groovy.plugin.CredentialGraph.*;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.greaterThan;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNull;
-
-/**
- * @author Stephen Mallette (http://stephen.genoprime.com)
- */
-public class CredentialGraphTest {
-    private TinkerGraph graph;
-
-    @Before
-    public void setup() {
-        graph = TinkerGraph.open();
-        graph.createIndex("username", Vertex.class);
-    }
-
-    @Test
-    public void shouldCreateUser() {
-        final Vertex v = credentials(graph).createUser("stephen", "secret");
-        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() {
-        assertThat(graph.vertices().hasNext(), is(false));
-        credentials(graph).createUser("stephen", "secret");
-        assertThat(graph.vertices().hasNext(), is(true));
-
-        assertEquals(1, credentials(graph).removeUser("stephen"));
-        assertThat(graph.vertices().hasNext(), is(false));
-    }
-
-    @Test
-    public void shouldNotRemoveUser() {
-        assertThat(graph.vertices().hasNext(), is(false));
-        credentials(graph).createUser("stephen", "secret");
-        assertThat(graph.vertices().hasNext(), is(true));
-
-        assertEquals(0, credentials(graph).removeUser("stephanie"));
-        assertThat(graph.vertices().hasNext(), is(true));
-    }
-
-    @Test
-    public void shouldFindUser() {
-        assertThat(graph.vertices().hasNext(), is(false));
-        credentials(graph).createUser("marko", "secret");
-        final Vertex stephen = credentials(graph).createUser("stephen", "secret");
-        credentials(graph).createUser("daniel", "secret");
-        assertThat(graph.vertices().hasNext(), is(true));
-
-        assertEquals(stephen, credentials(graph).findUser("stephen"));
-    }
-
-    @Test
-    public void shouldNotFindUser() {
-        assertThat(graph.vertices().hasNext(), is(false));
-        credentials(graph).createUser("marko", "secret");
-        credentials(graph).createUser("stephen", "secret");
-        credentials(graph).createUser("daniel", "secret");
-        assertThat(graph.vertices().hasNext(), is(true));
-
-        assertNull(credentials(graph).findUser("stephanie"));
-    }
-
-    @Test
-    public void shouldCountUsers() {
-        assertThat(graph.vertices().hasNext(), is(false));
-        credentials(graph).createUser("marko", "secret");
-        credentials(graph).createUser("stephen", "secret");
-        credentials(graph).createUser("daniel", "secret");
-        assertThat(graph.vertices().hasNext(), is(true));
-
-        assertEquals(3, credentials(graph).countUsers());
-    }
-
-    @Test(expected = IllegalStateException.class)
-    public void shouldThrowIfFindingMultipleUsers() {
-        assertThat(graph.vertices().hasNext(), is(false));
-        credentials(graph).createUser("stephen", "secret");
-        credentials(graph).createUser("stephen", "secret");
-        assertThat(graph.vertices().hasNext(), is(true));
-
-        assertNull(credentials(graph).findUser("stephen"));
-    }
-}