From b5ba55bff198553ee98f14ab15354b7392339806 Mon Sep 17 00:00:00 2001 From: Eddie Webb Date: Sun, 27 Sep 2015 09:24:22 -0400 Subject: [PATCH] Fixes #7 - just tracking as 2 distinct key types for now, actual expiration job has noted complexiities in #8 --- README.md | 16 ++ .../stash/ssh/ao/EnterpriseKeyRepository.java | 5 +- .../ssh/ao/EnterpriseKeyRepositoryImpl.java | 49 +++--- .../lmig/forge/stash/ssh/ao/SshKeyEntity.java | 23 +++ .../ssh/keys/EnterpriseSshKeyServiceImpl.java | 6 +- .../keys/EnterpriseSshKeyManagerImplTest.java | 9 +- .../ao/EnterpriseSshKeyRepositoryTest.java | 140 ++++++++++++------ 7 files changed, 169 insertions(+), 79 deletions(-) diff --git a/README.md b/README.md index 4a8224a..c4cd28e 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,29 @@ Layers additional controls over -Stash's- Bitbucket's SSH key features that enfo ## Features - Block unamed keys being added directly to Projects or Repositories + All keys must be created for specific users, and inherit their access. - Blocks upload of existing keys and generates new RSA 2048 bit keys for the user. + User can download public and private key pair, and regenerate as needed. Special users designated by a Group may add keys directly, this supports the current Bamboo<>Stash integration which generates user keys when repositories are created in bamboo. This Group should only be grnated to admins or system accounts that provision pipelines. - Enforces Key expiration policy + To mitigate risk, all user keys are expired after 90 days, and users are notified to re-generate +## Rules +### Key Types +The system recognize 2 key types. (See KeyType enum) +- USER: A key generated by the plugin on user behalf via UI or API. +- BAMBOO: A key presented to stash by a user in the configured 'authorizedGroup'. This group is intended to allow a system ID used in pipeline provisioning to establish a link between Bamboo and Stash. + +### Key Limits +Both USER and BAMBOO types allow only a single active Key per user. + +### Key Rotation +USER and BAMBOO keys allow separate rotation requirements. + + ## License Copyright 2015 Liberty Mutual Insurance diff --git a/src/main/java/com/lmig/forge/stash/ssh/ao/EnterpriseKeyRepository.java b/src/main/java/com/lmig/forge/stash/ssh/ao/EnterpriseKeyRepository.java index d320b8b..a4c105a 100644 --- a/src/main/java/com/lmig/forge/stash/ssh/ao/EnterpriseKeyRepository.java +++ b/src/main/java/com/lmig/forge/stash/ssh/ao/EnterpriseKeyRepository.java @@ -21,6 +21,7 @@ import com.atlassian.stash.ssh.api.SshKey; import com.atlassian.stash.user.StashUser; +import com.lmig.forge.stash.ssh.ao.SshKeyEntity.KeyType; public interface EnterpriseKeyRepository { @@ -28,11 +29,13 @@ public interface EnterpriseKeyRepository { boolean isValidKeyForUser(StashUser user, String text); - List listOfExpiredKeyIds(Date oldestValidDate); + List listOfExpiredKeys(Date oldestValidDate, KeyType keyType); void updateRecordWithKeyId(SshKeyEntity newRecord, SshKey newKey); void removeRecord(SshKeyEntity key); + void saveExternallyGeneratedKeyDetails(SshKey key, StashUser stashUser, KeyType bamboo); + } diff --git a/src/main/java/com/lmig/forge/stash/ssh/ao/EnterpriseKeyRepositoryImpl.java b/src/main/java/com/lmig/forge/stash/ssh/ao/EnterpriseKeyRepositoryImpl.java index dcaa6ab..478041c 100644 --- a/src/main/java/com/lmig/forge/stash/ssh/ao/EnterpriseKeyRepositoryImpl.java +++ b/src/main/java/com/lmig/forge/stash/ssh/ao/EnterpriseKeyRepositoryImpl.java @@ -16,7 +16,6 @@ package com.lmig.forge.stash.ssh.ao; -import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -31,6 +30,7 @@ import com.atlassian.stash.ssh.api.SshKey; import com.atlassian.stash.user.StashUser; import com.google.common.collect.Lists; +import com.lmig.forge.stash.ssh.ao.SshKeyEntity.KeyType; public class EnterpriseKeyRepositoryImpl implements EnterpriseKeyRepository { @@ -44,23 +44,35 @@ public EnterpriseKeyRepositoryImpl(ActiveObjects ao) { } @Override - public SshKeyEntity createOrUpdateUserKey(StashUser user, String text, String label) { - - SshKeyEntity key = findSingleKey(user); + public SshKeyEntity createOrUpdateUserKey(StashUser user, String text, String label) { + SshKeyEntity key = findSingleKey(user,KeyType.USER); if(null != key){ key.setText(text); key.setLabel(label); key.setCreatedDate(new Date()); key.save(); }else{ - key = ao.create(SshKeyEntity.class, new DBParam("USERID", user.getId()), new DBParam("TEXT", text),new DBParam("LABEL",label),new DBParam("CREATED", new Date())); + key = ao.create(SshKeyEntity.class, new DBParam("TYPE", SshKeyEntity.KeyType.USER), new DBParam("USERID", user.getId()), new DBParam("TEXT", text),new DBParam("LABEL",label),new DBParam("CREATED", new Date())); } - return key; - + return key; } + - private SshKeyEntity findSingleKey(StashUser user) { - SshKeyEntity[] keys = ao.find(SshKeyEntity.class, Query.select().where("USERID = ?", user.getId())); + @Override + public void saveExternallyGeneratedKeyDetails(SshKey key, StashUser user, KeyType keyType) { + SshKeyEntity entity = findSingleKey(user, KeyType.BAMBOO); + if(null != entity){ + entity.setText(key.getText()); + entity.setLabel(key.getLabel()); + entity.setCreatedDate(new Date()); + entity.save(); + }else{ + entity = ao.create(SshKeyEntity.class, new DBParam("TYPE",keyType), new DBParam("USERID", user.getId()), new DBParam("TEXT", key.getText()),new DBParam("LABEL",key.getLabel()),new DBParam("CREATED", new Date())); + } + } + + private SshKeyEntity findSingleKey(StashUser user, KeyType keyType) { + SshKeyEntity[] keys = ao.find(SshKeyEntity.class, Query.select().where("USERID = ? AND TYPE = ?", user.getId(), keyType)); if( null != keys && keys.length == 1 ){ SshKeyEntity key = keys[0]; return key; @@ -71,7 +83,7 @@ private SshKeyEntity findSingleKey(StashUser user) { @Override public boolean isValidKeyForUser(StashUser user, String text) { - SshKeyEntity key = findSingleKey(user); + SshKeyEntity key = findSingleKey(user, KeyType.USER); if(null != key){ return key.getText().equals(text); } @@ -80,20 +92,8 @@ public boolean isValidKeyForUser(StashUser user, String text) { } @Override - public List listOfExpiredKeyIds(Date oldestValidDate) { - final List expiredIds = new ArrayList(); - - //using ao.stream returns valid OID but all other fields absent. -// ao.stream(SshKeyEntity.class, Query.select().where("CREATED < ?",cal.getTime()),new EntityStreamCallback(){ -// -// @Override -// public void onRowRead(SshKeyEntity t) { -// log.debug("Reading row: " + t.getID() + "," + t.getLabel() + "," + t.getKeyId()); -// expiredIds.add(t.getKeyId()); -// } -// -// }); - SshKeyEntity[] results = ao.find(SshKeyEntity.class, Query.select().where("CREATED < ?",oldestValidDate)); + public List listOfExpiredKeys(Date oldestValidDate, KeyType keyType) { + SshKeyEntity[] results = ao.find(SshKeyEntity.class, Query.select().where("CREATED < ? and TYPE = ?",oldestValidDate,keyType)); return Lists.newArrayList(results); } @@ -116,6 +116,7 @@ public void removeRecord(SshKeyEntity key) { //SshKeyEntity[] recordToDelete = ao.find(SshKeyEntity.class, Query.select().where("KEYID = ?",stashKeyId)); ao.delete(key); } + } \ No newline at end of file diff --git a/src/main/java/com/lmig/forge/stash/ssh/ao/SshKeyEntity.java b/src/main/java/com/lmig/forge/stash/ssh/ao/SshKeyEntity.java index 40a3f04..77118df 100644 --- a/src/main/java/com/lmig/forge/stash/ssh/ao/SshKeyEntity.java +++ b/src/main/java/com/lmig/forge/stash/ssh/ao/SshKeyEntity.java @@ -43,6 +43,9 @@ public interface SshKeyEntity extends Entity{ @NotNull @Mutator("CREATED") Date getCreatedDate(); + @NotNull + @Mutator("TYPE") + KeyType getKeyType(); @Accessor("KEYID") @@ -55,5 +58,25 @@ public interface SshKeyEntity extends Entity{ void setUserId(Integer id); @Accessor("CREATED") void setCreatedDate(Date created); + @Accessor("TYPE") + void setKeyType(KeyType type); + public static enum KeyType{ + USER("USER","Generated by plugin on behalf of user."),BAMBOO("BAMBOO","Generated on bamboo's die and intercepted by plugin"); + + private final String name; + private final String description; + KeyType(String name, String description){ + this.name = name; + this.description = description; + } + public String getName() { + return name; + } + public String getDescription() { + return description; + } + + + } } diff --git a/src/main/java/com/lmig/forge/stash/ssh/keys/EnterpriseSshKeyServiceImpl.java b/src/main/java/com/lmig/forge/stash/ssh/keys/EnterpriseSshKeyServiceImpl.java index b81a7b4..f446cf4 100644 --- a/src/main/java/com/lmig/forge/stash/ssh/keys/EnterpriseSshKeyServiceImpl.java +++ b/src/main/java/com/lmig/forge/stash/ssh/keys/EnterpriseSshKeyServiceImpl.java @@ -28,6 +28,7 @@ import com.atlassian.stash.user.UserService; import com.lmig.forge.stash.ssh.ao.EnterpriseKeyRepository; import com.lmig.forge.stash.ssh.ao.SshKeyEntity; +import com.lmig.forge.stash.ssh.ao.SshKeyEntity.KeyType; import com.lmig.forge.stash.ssh.config.PluginSettingsService; import com.lmig.forge.stash.ssh.crypto.SshKeyPairGenerator; import com.lmig.forge.stash.ssh.notifications.NotificationService; @@ -60,6 +61,7 @@ public boolean isKeyValidForUser(SshKey key, StashUser stashUser) { //allow bamboo <> stash keys for system accounts in special group. String userGroup = pluginSettingsService.getAuthorizedGroup(); if( userGroup != null && userService.existsGroup(userGroup) && userService.isUserInGroup(stashUser, userGroup)){ + enterpriseKeyRepository.saveExternallyGeneratedKeyDetails(key,stashUser,SshKeyEntity.KeyType.BAMBOO); return true; }else{ //otherwise user must have gone through our wrapper @@ -90,13 +92,15 @@ public KeyPairResourceModel generateNewKeyPairFor(StashUser user) { enterpriseKeyRepository.updateRecordWithKeyId(newRecord, newKey); return result; } + + @Override public void replaceExpiredKeysAndNotifyUsers() { DateTime dateTime = new DateTime(); //cal.add(Calendar.MINUTE, -1); //live demo in UI. - List expiredStashKeys = enterpriseKeyRepository.listOfExpiredKeyIds( dateTime.minusDays(pluginSettingsService.getDaysAllowedForUserKeys()).toDate()); + List expiredStashKeys = enterpriseKeyRepository.listOfExpiredKeys( dateTime.minusDays(pluginSettingsService.getDaysAllowedForUserKeys()).toDate(), KeyType.USER); for (SshKeyEntity keyRecord : expiredStashKeys) { diff --git a/src/test/java/ut/com/lmig/forge/stash/ssh/keys/EnterpriseSshKeyManagerImplTest.java b/src/test/java/ut/com/lmig/forge/stash/ssh/keys/EnterpriseSshKeyManagerImplTest.java index b571ae2..2e12551 100644 --- a/src/test/java/ut/com/lmig/forge/stash/ssh/keys/EnterpriseSshKeyManagerImplTest.java +++ b/src/test/java/ut/com/lmig/forge/stash/ssh/keys/EnterpriseSshKeyManagerImplTest.java @@ -20,15 +20,11 @@ import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; - -import java.util.Calendar; - import net.java.ao.DBParam; import net.java.ao.EntityManager; import net.java.ao.test.jdbc.Data; @@ -52,6 +48,7 @@ import com.lmig.forge.stash.ssh.ao.EnterpriseKeyRepository; import com.lmig.forge.stash.ssh.ao.EnterpriseKeyRepositoryImpl; import com.lmig.forge.stash.ssh.ao.SshKeyEntity; +import com.lmig.forge.stash.ssh.ao.SshKeyEntity.KeyType; import com.lmig.forge.stash.ssh.config.PluginSettingsService; import com.lmig.forge.stash.ssh.keys.EnterpriseSshKeyService; import com.lmig.forge.stash.ssh.keys.EnterpriseSshKeyServiceImpl; @@ -201,11 +198,11 @@ public void update(EntityManager em) throws Exception { // create a pre-expired key in DB for scheduler DateTime now = new DateTime(); expiredKey = em.create(SshKeyEntity.class, new DBParam("USERID", EXPIRED_USER_ID), new DBParam("KEYID", - EXPIRED_STASH_KEY_ID), new DBParam("TEXT", APPROVED_PUBLIC_KEY_ONE), new DBParam("LABEL", "COMPROMISED"), + EXPIRED_STASH_KEY_ID), new DBParam("TEXT", APPROVED_PUBLIC_KEY_ONE), new DBParam("LABEL", "COMPROMISED"), new DBParam("TYPE", KeyType.USER), new DBParam("CREATED", now.minusDays(DAYS_ALLOWED+1).toDate())); validKey = em.create(SshKeyEntity.class, new DBParam("USERID", VALID_USER_ID), new DBParam("KEYID", - VALID_STASH_KEY_ID), new DBParam("TEXT", APPROVED_PUBLIC_KEY_ONE), new DBParam("LABEL", "VALID"), + VALID_STASH_KEY_ID), new DBParam("TEXT", APPROVED_PUBLIC_KEY_ONE), new DBParam("LABEL", "VALID"), new DBParam("TYPE", KeyType.USER), new DBParam("CREATED", now.minusDays(DAYS_ALLOWED-1).toDate())); } diff --git a/src/test/java/ut/com/lmig/forge/stash/ssh/keys/ao/EnterpriseSshKeyRepositoryTest.java b/src/test/java/ut/com/lmig/forge/stash/ssh/keys/ao/EnterpriseSshKeyRepositoryTest.java index 9c30f7f..4f395d1 100644 --- a/src/test/java/ut/com/lmig/forge/stash/ssh/keys/ao/EnterpriseSshKeyRepositoryTest.java +++ b/src/test/java/ut/com/lmig/forge/stash/ssh/keys/ao/EnterpriseSshKeyRepositoryTest.java @@ -22,9 +22,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; +import java.util.List; import net.java.ao.DBParam; import net.java.ao.EntityManager; @@ -35,6 +33,7 @@ import net.java.ao.test.jdbc.NonTransactional; import net.java.ao.test.junit.ActiveObjectsJUnitRunner; +import org.joda.time.DateTime; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -46,87 +45,134 @@ import com.lmig.forge.stash.ssh.ao.EnterpriseKeyRepository; import com.lmig.forge.stash.ssh.ao.EnterpriseKeyRepositoryImpl; import com.lmig.forge.stash.ssh.ao.SshKeyEntity; - - +import com.lmig.forge.stash.ssh.ao.SshKeyEntity.KeyType; /** - * Must run all methods that interact with service as @NonTransactional - * or otherwise the multiple layers of transactions cause issues. - * Also http://grepcode.com/file/repo1.maven.org/maven2/net.java.dev.activeobjects/activeobjects-test/0.23.0/net/java/ao/test/jdbc/DynamicJdbcConfiguration.java#DynamicJdbcConfiguration.0jdbcSupplier - * has all the databtase types and connection info needed in maven arguments. + * Must run all methods that interact with service as @NonTransactional or + * otherwise the multiple layers of transactions cause issues. Also + * http://grepcode + * .com/file/repo1.maven.org/maven2/net.java.dev.activeobjects/activeobjects + * -test/0.23.0/net/java/ao/test/jdbc/DynamicJdbcConfiguration.java# + * DynamicJdbcConfiguration.0jdbcSupplier has all the databtase types and + * connection info needed in maven arguments. + * * @author Eddie Webb - * + * */ @RunWith(ActiveObjectsJUnitRunner.class) @Data(EnterpriseSshKeyRepositoryTest.EnterpriseSshKeyRepositoryTestData.class) @Jdbc(net.java.ao.test.jdbc.DynamicJdbcConfiguration.class) public class EnterpriseSshKeyRepositoryTest { - private static final String PUBLIC_KEY_ONE ="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC0O2PpfWd0RuoveFkSLP8DaL2ZekQZJM7gzQFi/cavziK8jnAY+xtNIAF1K7EN64JSM2DTMU7BZUFkJvqqbugzc29A/LOfZ6GzvMhSiR7YR2J/eOkVZbmPPyC1qWDCc5Ne71pEJhU5OdlFd4Hj5XgDzNyMANoYlO+xm1IDzHBxDSrvY++VGrnZG1rJ6aSdxyRCoE7MVtQkLuIMDSVPTVfdqDV4oKlH2bzd4LyA1Jm01+MBmWq2qVcKcF6UYKaUILVreZZZSm2/PBbgQ+H5yzjNeEbvdnAr7bcn+xRdhEM0ZGm/RRDRIvwkTlWJ2y9M3KvnJEKbv/c9ZAlOmbs5K1OhfGL/jCU8h1EslwQ9euFp0wjKUMj5u9ll8QqpNcXxsfUnaN9qc2rrm5FS5t5TFAkbIX5fOTJCPb+seE146ax/cNovzOoJUPvF+qBfvJLQGX2L/4JdPqDQ6FkLbvJy194/K5oWag8w4F9ftYIfd/SOgatPMiKuhOls2zYufm34UBbksc7qxDD12JUiI/q7JNted53tnPVBSDLM5RYtohDq/w4MfyFmA51UeETSLumlwg9kOuqaWBYjr2Esn09EtkQNIhQxxt3w47O0RFghZgJdnP3VORju3v2l0Qfo7A/EbeDGKXQhCl6yeMv82lmUtzOhVN6IAApOwMH7Hmh/z209jw=="; + private static final String PUBLIC_KEY_ONE = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC0O2PpfWd0RuoveFkSLP8DaL2ZekQZJM7gzQFi/cavziK8jnAY+xtNIAF1K7EN64JSM2DTMU7BZUFkJvqqbugzc29A/LOfZ6GzvMhSiR7YR2J/eOkVZbmPPyC1qWDCc5Ne71pEJhU5OdlFd4Hj5XgDzNyMANoYlO+xm1IDzHBxDSrvY++VGrnZG1rJ6aSdxyRCoE7MVtQkLuIMDSVPTVfdqDV4oKlH2bzd4LyA1Jm01+MBmWq2qVcKcF6UYKaUILVreZZZSm2/PBbgQ+H5yzjNeEbvdnAr7bcn+xRdhEM0ZGm/RRDRIvwkTlWJ2y9M3KvnJEKbv/c9ZAlOmbs5K1OhfGL/jCU8h1EslwQ9euFp0wjKUMj5u9ll8QqpNcXxsfUnaN9qc2rrm5FS5t5TFAkbIX5fOTJCPb+seE146ax/cNovzOoJUPvF+qBfvJLQGX2L/4JdPqDQ6FkLbvJy194/K5oWag8w4F9ftYIfd/SOgatPMiKuhOls2zYufm34UBbksc7qxDD12JUiI/q7JNted53tnPVBSDLM5RYtohDq/w4MfyFmA51UeETSLumlwg9kOuqaWBYjr2Esn09EtkQNIhQxxt3w47O0RFghZgJdnP3VORju3v2l0Qfo7A/EbeDGKXQhCl6yeMv82lmUtzOhVN6IAApOwMH7Hmh/z209jw=="; private static final int ADMIN_ID = 1; private static final int USER_ID = 2; + private static final int ADHOC_USER_ID = 3; private static final int STASH_KEY_ID = 100; - - - //gets injected thanks to ActiveObjectsJUnitRunner.class + private static final int DAYS_ALLOWED_FOR_USERS = 90; + private static final int DAYS_ALLOWED_FOR_BAMBOO = 365; + + // gets injected thanks to ActiveObjectsJUnitRunner.class private EntityManager entityManager; - private ActiveObjects ao ; + private ActiveObjects ao; private EnterpriseKeyRepository keyRepo; - + @Before - public void setup(){ + public void setup() { ao = new TestActiveObjects(entityManager); keyRepo = new EnterpriseKeyRepositoryImpl(ao); } - + @Test @NonTransactional - public void aKeyCanBeSaved(){ + public void aKeyCanBeSaved() { StashUser user = mock(StashUser.class); - when(user.getId()).thenReturn(USER_ID); + when(user.getId()).thenReturn(ADHOC_USER_ID); String comment = "No Comment123"; - + keyRepo.createOrUpdateUserKey(user, PUBLIC_KEY_ONE, comment); - - SshKeyEntity[] createdRecords = ao.find(SshKeyEntity.class,Query.select().where("USERID = ?",USER_ID)); + + SshKeyEntity[] createdRecords = ao.find(SshKeyEntity.class, Query.select().where("USERID = ?", ADHOC_USER_ID)); assertThat(createdRecords.length, is(1)); - assertThat(createdRecords[0].getLabel(),is(comment)); - assertThat(createdRecords[0].getText(),is(PUBLIC_KEY_ONE)); + assertThat(createdRecords[0].getLabel(), is(comment)); + assertThat(createdRecords[0].getText(), is(PUBLIC_KEY_ONE)); } - - + @Test @NonTransactional - public void theStashKeyIdOfExistingRecordCanBeUPdated(){ - assertThat(EnterpriseSshKeyRepositoryTestData.expiredKey.getID(),notNullValue()); + public void theStashKeyIdOfExistingRecordCanBeUPdated() { + assertThat(EnterpriseSshKeyRepositoryTestData.expiredUserKey.getID(), notNullValue()); SshKey key = mock(SshKey.class); when(key.getId()).thenReturn(STASH_KEY_ID); - keyRepo.updateRecordWithKeyId(EnterpriseSshKeyRepositoryTestData.expiredKey, key); + keyRepo.updateRecordWithKeyId(EnterpriseSshKeyRepositoryTestData.expiredUserKey, key); + + SshKeyEntity[] createdRecords = ao.find(SshKeyEntity.class, Query.select().where("USERID = ? and TYPE = ?", ADMIN_ID,KeyType.USER)); + assertThat(createdRecords.length, is(1)); // if not found, issue with + // test data class + assertThat(createdRecords[0].getKeyId(), is(STASH_KEY_ID)); // if not + // found, + // issue + // with + // update + // call + } + + @Test + @NonTransactional + public void listOfExpiredKeysRespectsUserKeyType() { + DateTime now = new DateTime(); + List keys = keyRepo.listOfExpiredKeys(now.minusDays(DAYS_ALLOWED_FOR_USERS).toDate(), KeyType.USER); - SshKeyEntity[] createdRecords = ao.find(SshKeyEntity.class,Query.select().where("USERID = ?",ADMIN_ID)); - assertThat(createdRecords.length, is(1)); //if not found, issue with test data class - assertThat(createdRecords[0].getKeyId(),is(STASH_KEY_ID)); //if not found, issue with update call + assertThat(keys.size(),is(1)); + assertThat("Expiry query returned keytype not requested",keys.get(0).getKeyType(),is(KeyType.USER)); + assertThat("Expired Key does not match expected",keys.get(0).getID(),is(EnterpriseSshKeyRepositoryTestData.expiredUserKey.getID())); } - - public static class EnterpriseSshKeyRepositoryTestData implements DatabaseUpdater - { - private static SshKeyEntity expiredKey; + @Test + @NonTransactional + public void listOfExpiredKeysRespectsBambooKeyType() { + DateTime now = new DateTime(); + List keys = keyRepo.listOfExpiredKeys(now.minusDays(DAYS_ALLOWED_FOR_BAMBOO).toDate(), KeyType.BAMBOO); + assertThat(keys.size(),is(1)); + assertThat("Expiry query returned keytype not requested",keys.get(0).getKeyType(),is(KeyType.BAMBOO)); + assertThat("Expired Key does not match expected",keys.get(0).getID(),is(EnterpriseSshKeyRepositoryTestData.expiredBambooKey.getID())); + } + + public static class EnterpriseSshKeyRepositoryTestData implements DatabaseUpdater { + private static SshKeyEntity expiredUserKey; + private static SshKeyEntity expiredBambooKey; + private static SshKeyEntity validUserKey; + private static SshKeyEntity validBambooKey; + @Override - public void update(EntityManager em) throws Exception - { + public void update(EntityManager em) throws Exception { em.migrate(SshKeyEntity.class); + + + DateTime now = new DateTime(); + // create a pre-expired user key in DB + expiredUserKey = em.create(SshKeyEntity.class, new DBParam("TYPE", KeyType.USER), new DBParam("USERID", + ADMIN_ID), new DBParam("TEXT", PUBLIC_KEY_ONE), new DBParam("LABEL", "COMPROMISED"), new DBParam( + "CREATED", now.minusDays(DAYS_ALLOWED_FOR_USERS + 1).toDate())); + + // create a pre-expired bamboo key + expiredBambooKey = em.create(SshKeyEntity.class, new DBParam("USERID", ADMIN_ID), new DBParam("TEXT", + PUBLIC_KEY_ONE), new DBParam("LABEL", "BAMBOO"), new DBParam("TYPE", KeyType.BAMBOO), new DBParam( + "CREATED", now.minusDays(DAYS_ALLOWED_FOR_BAMBOO + 1).toDate())); - //create a pre-expired key in DB for scheduler - Date today = new Date(); - Calendar cal = new GregorianCalendar(); - cal.setTime(today); - cal.add(Calendar.DAY_OF_YEAR,-91); - expiredKey = em.create(SshKeyEntity.class, new DBParam("USERID", ADMIN_ID), new DBParam("TEXT", PUBLIC_KEY_ONE),new DBParam("LABEL","COMPROMISED"),new DBParam("CREATED", cal.getTime())); - + // create a non-expired user key in DB + validUserKey = em.create(SshKeyEntity.class, new DBParam("TYPE", KeyType.USER), new DBParam("USERID", + USER_ID), new DBParam("TEXT", PUBLIC_KEY_ONE), new DBParam("LABEL", "COMPROMISED"), new DBParam( + "CREATED", now.minusDays(DAYS_ALLOWED_FOR_USERS - 1).toDate())); + + // create a babmoo key that is older then user limit, but valid to bamboo limit + validBambooKey = em.create(SshKeyEntity.class, new DBParam("USERID", USER_ID), new DBParam("TEXT", + PUBLIC_KEY_ONE), new DBParam("LABEL", "BAMBOO"), new DBParam("TYPE", KeyType.BAMBOO), new DBParam( + "CREATED", now.minusDays(DAYS_ALLOWED_FOR_BAMBOO - 1).toDate())); + } - + } }