]> WPIA git - gigi.git/commitdiff
ADD: user group management (with testcase)
authorFelix Dörre <felix@dogcraft.de>
Thu, 11 Sep 2014 20:31:48 +0000 (22:31 +0200)
committerFelix Dörre <felix@dogcraft.de>
Thu, 11 Sep 2014 20:38:11 +0000 (22:38 +0200)
src/org/cacert/gigi/dbObjects/Group.java [new file with mode: 0644]
src/org/cacert/gigi/dbObjects/User.java
tests/org/cacert/gigi/TestUserGroupMembership.java [new file with mode: 0644]

diff --git a/src/org/cacert/gigi/dbObjects/Group.java b/src/org/cacert/gigi/dbObjects/Group.java
new file mode 100644 (file)
index 0000000..bdce278
--- /dev/null
@@ -0,0 +1,57 @@
+package org.cacert.gigi.dbObjects;
+
+import java.util.HashMap;
+
+public class Group {
+
+    private static HashMap<String, Group> cache = new HashMap<>();
+
+    private final String dbName;
+
+    private Group(String name) {
+        dbName = name;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((dbName == null) ? 0 : dbName.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        Group other = (Group) obj;
+        if (dbName == null) {
+            if (other.dbName != null) {
+                return false;
+            }
+        } else if ( !dbName.equals(other.dbName)) {
+            return false;
+        }
+        return true;
+    }
+
+    public static synchronized Group getByString(String name) {
+        Group g = cache.get(name);
+        if (g == null) {
+            g = new Group(name);
+            cache.put(name, g);
+        }
+        return g;
+    }
+
+    public String getDatabaseName() {
+        return dbName;
+    }
+}
index bc927fa9849bd647033fe8a50dfdf2baa7a4f645..c07db48cb298fd5b7cf5da2470da3dcf6e494386 100644 (file)
@@ -5,7 +5,10 @@ import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.Calendar;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.Calendar;
+import java.util.Collections;
+import java.util.HashSet;
 import java.util.Locale;
 import java.util.Locale;
+import java.util.Set;
 
 import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.database.DatabaseConnection;
 
 import org.cacert.gigi.GigiApiException;
 import org.cacert.gigi.database.DatabaseConnection;
@@ -28,6 +31,8 @@ public class User implements IdCachable {
 
     private Locale locale;
 
 
     private Locale locale;
 
+    private Set<Group> groups = new HashSet<>();
+
     private User(int id) {
         this.id = id;
         updateName(id);
     private User(int id) {
         this.id = id;
         updateName(id);
@@ -50,6 +55,13 @@ public class User implements IdCachable {
                 }
             }
             rs.close();
                 }
             }
             rs.close();
+            PreparedStatement psg = DatabaseConnection.getInstance().prepare("SELECT permission FROM user_groups WHERE user=? AND deleted is NULL");
+            psg.setInt(1, id);
+            ResultSet rs2 = psg.executeQuery();
+            while (rs2.next()) {
+                groups.add(Group.getByString(rs2.getString(1)));
+            }
+            rs2.close();
         } catch (SQLException e) {
             e.printStackTrace();
         }
         } catch (SQLException e) {
             e.printStackTrace();
         }
@@ -504,6 +516,40 @@ public class User implements IdCachable {
         update.executeUpdate();
     }
 
         update.executeUpdate();
     }
 
+    public boolean isInGroup(Group g) {
+        return groups.contains(g);
+    }
+
+    public Set<Group> getGroups() {
+        return Collections.unmodifiableSet(groups);
+    }
+
+    public void grantGroup(User granter, Group toGrant) throws GigiApiException {
+        groups.add(toGrant);
+        try {
+            PreparedStatement ps = DatabaseConnection.getInstance().prepare("INSERT INTO user_groups SET user=?, permission=?, grantedby=?");
+            ps.setInt(1, getId());
+            ps.setString(2, toGrant.getDatabaseName());
+            ps.setInt(3, granter.getId());
+            ps.execute();
+        } catch (SQLException e) {
+            throw new GigiApiException(e);
+        }
+    }
+
+    public void revokeGroup(User revoker, Group toRevoke) throws GigiApiException {
+        groups.remove(toRevoke);
+        try {
+            PreparedStatement ps = DatabaseConnection.getInstance().prepare("UPDATE user_groups SET deleted=CURRENT_TIMESTAMP, revokedby=? WHERE deleted is NULL AND permission=? AND user=?");
+            ps.setInt(1, revoker.getId());
+            ps.setString(2, toRevoke.getDatabaseName());
+            ps.setInt(3, getId());
+            ps.execute();
+        } catch (SQLException e) {
+            throw new GigiApiException(e);
+        }
+    }
+
     private static ObjectCache<User> myCache = new ObjectCache<>();
 
     public static synchronized User getById(int id) {
     private static ObjectCache<User> myCache = new ObjectCache<>();
 
     public static synchronized User getById(int id) {
diff --git a/tests/org/cacert/gigi/TestUserGroupMembership.java b/tests/org/cacert/gigi/TestUserGroupMembership.java
new file mode 100644 (file)
index 0000000..fa67072
--- /dev/null
@@ -0,0 +1,102 @@
+package org.cacert.gigi;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.*;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+
+import org.cacert.gigi.database.DatabaseConnection;
+import org.cacert.gigi.dbObjects.Group;
+import org.cacert.gigi.dbObjects.ObjectCache;
+import org.cacert.gigi.dbObjects.User;
+import org.cacert.gigi.testUtils.ManagedTest;
+import org.junit.Test;
+
+public class TestUserGroupMembership extends ManagedTest {
+
+    private final Group ttpGroup = Group.getByString("ttp-assuer");
+
+    private final Group supporter = Group.getByString("supporter");
+
+    @Test
+    public void testAddObject() throws GigiApiException, SQLException {
+        User u = User.getById(createVerifiedUser("fname", "lname", createUniqueName() + "@example.org", TEST_PASSWORD));
+
+        User granter = User.getById(createVerifiedUser("grFname", "lname", createUniqueName() + "@example.org", TEST_PASSWORD));
+        assertBehavesEmpty(u);
+
+        u.grantGroup(granter, ttpGroup);
+        assertBehavesTtpGroup(u);
+
+        ObjectCache.clearAllCaches();
+        User u2 = User.getById(u.getId());
+
+        assertThat(u2, is(not(sameInstance(u))));
+        assertBehavesTtpGroup(u2);
+
+        ResultSet rs = fetchGroupRowsFor(u);
+
+        assertTrue(rs.next());
+        assertEquals(0, rs.getInt("revokedby"));
+        assertEquals(granter.getId(), rs.getInt("grantedby"));
+        assertEquals(ttpGroup.getDatabaseName(), rs.getString("permission"));
+
+        assertNull(rs.getDate("deleted"));
+        assertNotNull(rs.getDate("granted"));
+
+        assertFalse(rs.next());
+    }
+
+    @Test
+    public void testRemoveObject() throws GigiApiException, SQLException {
+        User u = User.getById(createVerifiedUser("fname", "lname", createUniqueName() + "@example.org", TEST_PASSWORD));
+
+        User granter = User.getById(createVerifiedUser("grFname", "lname", createUniqueName() + "@example.org", TEST_PASSWORD));
+
+        assertBehavesEmpty(u);
+        u.grantGroup(granter, ttpGroup);
+        assertBehavesTtpGroup(u);
+        u.revokeGroup(granter, ttpGroup);
+        assertBehavesEmpty(u);
+
+        ObjectCache.clearAllCaches();
+        User u2 = User.getById(u.getId());
+        assertThat(u2, is(not(sameInstance(u))));
+        assertBehavesEmpty(u);
+
+        ResultSet rs = fetchGroupRowsFor(u);
+        assertTrue(rs.next());
+        assertEquals(granter.getId(), rs.getInt("revokedby"));
+        assertEquals(granter.getId(), rs.getInt("grantedby"));
+        assertEquals(ttpGroup.getDatabaseName(), rs.getString("permission"));
+
+        assertNotNull(rs.getDate("deleted"));
+        assertNotNull(rs.getDate("granted"));
+
+        assertFalse(rs.next());
+    }
+
+    private ResultSet fetchGroupRowsFor(User u) throws SQLException {
+        PreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT * FROM user_groups WHERE user=?");
+        ps.setInt(1, u.getId());
+        ResultSet rs = ps.executeQuery();
+        return rs;
+    }
+
+    private void assertBehavesEmpty(User u) {
+        assertEquals(Collections.emptySet(), u.getGroups());
+        assertFalse(u.isInGroup(ttpGroup));
+        assertFalse(u.isInGroup(supporter));
+    }
+
+    private void assertBehavesTtpGroup(User u) {
+        assertEquals(new HashSet<>(Arrays.asList(ttpGroup)), u.getGroups());
+        assertTrue(u.isInGroup(ttpGroup));
+        assertFalse(u.isInGroup(supporter));
+    }
+}