diff --git a/opentech/apply/funds/tests/factories/models.py b/opentech/apply/funds/tests/factories/models.py
index 591854e893a1154f4ea875c92297eef859825c3f..c90f97426cdc0a8523c58fa11d480234451e3d93 100644
--- a/opentech/apply/funds/tests/factories/models.py
+++ b/opentech/apply/funds/tests/factories/models.py
@@ -202,6 +202,9 @@ class ApplicationSubmissionFactory(factory.DjangoModelFactory):
             status='draft_proposal',
             workflow_name='double',
         )
+        rejected = factory.Trait(
+            status='rejected'
+        )
 
     form_fields = blocks.CustomFormFieldsFactory
     form_data = factory.SubFactory(
diff --git a/opentech/apply/funds/workflow.py b/opentech/apply/funds/workflow.py
index f46140ebb47abb717ab5d8358dc76815cae8e514..59291fdd156d891b95978928a870023f76645915 100644
--- a/opentech/apply/funds/workflow.py
+++ b/opentech/apply/funds/workflow.py
@@ -79,32 +79,52 @@ class Stage:
         return self.name
 
 
-class Permission:
+class BasePermissions:
     def can_edit(self, user: 'User') -> bool:
+        if user.is_apply_staff:
+            return self.can_staff_edit(user)
+
+        if user.is_applicant:
+            return self.can_applicant_edit(user)
+
+    def can_staff_edit(self, user: 'User') -> bool:
+        return False
+
+    def can_applicant_edit(self, user: 'User') -> bool:
         return False
 
+    def can_review(self, user: 'User') -> bool:
+        if user.is_apply_staff:
+            return self.can_staff_review(user)
+
+        if user.is_reviewer:
+            return self.can_reviewer_review(user)
+
     def can_staff_review(self, user: 'User') -> bool:
         return False
 
     def can_reviewer_review(self, user: 'User') -> bool:
         return False
 
-    def can_review(self, user: 'User') -> bool:
-        return self.can_staff_review(user) or self.can_reviewer_review(user)
+
+class NoPermissions(BasePermissions):
+    pass
 
 
-class StaffReviewPermission(Permission):
+class DefaultPermissions(BasePermissions):
+    # Other Permissions should inherit from this class
+    # Staff can review at any time
     def can_staff_review(self, user: 'User') -> bool:
-        return user.is_apply_staff
+        return True
 
 
-class ReviewerReviewPermission(Permission):
+class ReviewerReviewPermissions(DefaultPermissions):
     def can_reviewer_review(self, user: 'User') -> bool:
-        return user.is_reviewer
+        return True
 
 
-class CanEditPermission(Permission):
-    def can_edit(self, user: 'User') -> bool:
+class CanEditPermissions(DefaultPermissions):
+    def can_applicant_edit(self, user: 'User') -> bool:
         return True
 
 
@@ -126,7 +146,7 @@ SingleStageDefinition = {
         },
         'display': 'Under Discussion',
         'stage': Request,
-        'permissions': Permission(),
+        'permissions': DefaultPermissions(),
         'step': 0,
     },
     'more_info': {
@@ -135,7 +155,7 @@ SingleStageDefinition = {
         },
         'display': 'More information required',
         'stage': Request,
-        'permissions': CanEditPermission(),
+        'permissions': CanEditPermissions(),
         'step': 0,
     },
     'internal_review': {
@@ -144,7 +164,7 @@ SingleStageDefinition = {
         },
         'display': 'Internal Review',
         'stage': Request,
-        'permissions': StaffReviewPermission(),
+        'permissions': DefaultPermissions(),
         'step': 1,
     },
     'post_review_discussion': {
@@ -155,7 +175,7 @@ SingleStageDefinition = {
         },
         'display': 'Under Discussion',
         'stage': Request,
-        'permissions': Permission(),
+        'permissions': DefaultPermissions(),
         'step': 2,
     },
     'post_review_more_info': {
@@ -164,20 +184,20 @@ SingleStageDefinition = {
         },
         'display': 'More information required',
         'stage': Request,
-        'permissions': CanEditPermission(),
+        'permissions': CanEditPermissions(),
         'step': 2,
     },
 
     'accepted': {
         'display': 'Accepted',
         'stage': Request,
-        'permissions': Permission(),
+        'permissions': NoPermissions(),
         'step': 3,
     },
     'rejected': {
         'display': 'Rejected',
         'stage': Request,
-        'permissions': Permission(),
+        'permissions': NoPermissions(),
         'step': 3,
     },
 }
@@ -192,7 +212,7 @@ DoubleStageDefinition = {
         },
         'display': 'Under Discussion',
         'stage': Concept,
-        'permissions': Permission(),
+        'permissions': DefaultPermissions(),
         'step': 0,
     },
     'concept_more_info': {
@@ -201,7 +221,7 @@ DoubleStageDefinition = {
         },
         'display': 'More information required',
         'stage': Concept,
-        'permissions': CanEditPermission(),
+        'permissions': CanEditPermissions(),
         'step': 0,
     },
     'concept_internal_review': {
@@ -210,7 +230,7 @@ DoubleStageDefinition = {
         },
         'display': 'Internal Review',
         'stage': Concept,
-        'permissions': StaffReviewPermission(),
+        'permissions': DefaultPermissions(),
         'step': 1,
     },
     'concept_review_discussion': {
@@ -221,7 +241,7 @@ DoubleStageDefinition = {
         },
         'display': 'Under Discussion',
         'stage': Concept,
-        'permissions': Permission(),
+        'permissions': DefaultPermissions(),
         'step': 2,
     },
     'concept_review_more_info': {
@@ -230,7 +250,7 @@ DoubleStageDefinition = {
         },
         'display': 'More information required',
         'stage': Concept,
-        'permissions': CanEditPermission(),
+        'permissions': CanEditPermissions(),
         'step': 2,
     },
     'invited_to_proposal': {
@@ -244,13 +264,13 @@ DoubleStageDefinition = {
             },
         },
         'stage': Concept,
-        'permissions': Permission(),
+        'permissions': NoPermissions(),
         'step': 3,
     },
     'concept_rejected': {
         'display': 'Rejected',
         'stage': Concept,
-        'permissions': Permission(),
+        'permissions': NoPermissions(),
         'step': 3,
     },
     'draft_proposal': {
@@ -259,7 +279,7 @@ DoubleStageDefinition = {
         },
         'display': 'Invited for Proposal',
         'stage': Proposal,
-        'permissions': CanEditPermission(),
+        'permissions': CanEditPermissions(),
         'step': 4,
     },
     'proposal_discussion': {
@@ -270,7 +290,7 @@ DoubleStageDefinition = {
         },
         'display': 'Under Discussion',
         'stage': Proposal,
-        'permissions': Permission(),
+        'permissions': DefaultPermissions(),
         'step': 5,
     },
     'proposal_more_info': {
@@ -279,7 +299,7 @@ DoubleStageDefinition = {
         },
         'display': 'More information required',
         'stage': Proposal,
-        'permissions': CanEditPermission(),
+        'permissions': CanEditPermissions(),
         'step': 5,
     },
     'proposal_internal_review': {
@@ -288,7 +308,7 @@ DoubleStageDefinition = {
         },
         'display': 'Internal Review',
         'stage': Proposal,
-        'permissions': StaffReviewPermission(),
+        'permissions': DefaultPermissions(),
         'step': 6,
     },
     'post_proposal_review_discussion': {
@@ -299,7 +319,7 @@ DoubleStageDefinition = {
         },
         'display': 'Under Discussion',
         'stage': Proposal,
-        'permissions': Permission(),
+        'permissions': DefaultPermissions(),
         'step': 7,
     },
     'post_proposal_review_more_info': {
@@ -308,7 +328,7 @@ DoubleStageDefinition = {
         },
         'display': 'More information required',
         'stage': Proposal,
-        'permissions': CanEditPermission(),
+        'permissions': CanEditPermissions(),
         'step': 7,
     },
     'external_review': {
@@ -317,7 +337,7 @@ DoubleStageDefinition = {
         },
         'display': 'Advisory Council Review',
         'stage': Proposal,
-        'permissions': ReviewerReviewPermission(),
+        'permissions': ReviewerReviewPermissions(),
         'step': 8,
     },
     'post_external_review_discussion': {
@@ -328,7 +348,7 @@ DoubleStageDefinition = {
         },
         'display': 'Under Discussion',
         'stage': Proposal,
-        'permissions': Permission(),
+        'permissions': DefaultPermissions(),
         'step': 9,
     },
     'post_external_review_more_info': {
@@ -337,19 +357,19 @@ DoubleStageDefinition = {
         },
         'display': 'More information required',
         'stage': Proposal,
-        'permissions': CanEditPermission(),
+        'permissions': CanEditPermissions(),
         'step': 9,
     },
     'proposal_accepted': {
         'display': 'Accepted',
         'stage': Proposal,
-        'permissions': Permission(),
+        'permissions': NoPermissions(),
         'step': 10,
     },
     'proposal_rejected': {
         'display': 'Rejected',
         'stage': Proposal,
-        'permissions': Permission(),
+        'permissions': NoPermissions(),
         'step': 10,
     },
 
diff --git a/opentech/apply/review/tests/test_views.py b/opentech/apply/review/tests/test_views.py
index 3ac1e6ab244cbc935459a6afccb74eff8b6f13f8..09b4fefaa5195a26a001c85b9ffa3bbd6b25fc0f 100644
--- a/opentech/apply/review/tests/test_views.py
+++ b/opentech/apply/review/tests/test_views.py
@@ -61,7 +61,7 @@ class StaffReviewFormTestCase(BaseViewTestCase):
         self.assertContains(response, reverse('funds:submissions:detail', kwargs={'pk': submission.id}))
 
     def test_cant_access_wrong_status(self):
-        submission = ApplicationSubmissionFactory()
+        submission = ApplicationSubmissionFactory(rejected=True)
         response = self.get_page(submission, 'form')
         self.assertEqual(response.status_code, 403)
 
@@ -73,8 +73,6 @@ class StaffReviewFormTestCase(BaseViewTestCase):
         self.assertEqual(response.context['title'], 'Update Review draft')
 
     def test_can_edit_draft_review(self):
-        # FIXME fix form generation issue in ReviewFundTypeFactory review_forms()
-        return
         submission = ApplicationSubmissionFactory(status='internal_review')
         ReviewFactory(submission=submission, author=self.user, is_draft=True)
         response = self.post_page(submission, {'data': 'value'}, 'form')
diff --git a/opentech/apply/users/models.py b/opentech/apply/users/models.py
index 62e753ef3dc3fbf270a0873add6ebc4364477ded..63b06aca30a659d95376598cc8f54c59aa440b04 100644
--- a/opentech/apply/users/models.py
+++ b/opentech/apply/users/models.py
@@ -93,6 +93,10 @@ class User(AbstractUser):
     def is_reviewer(self):
         return self.groups.filter(name=REVIEWER_GROUP_NAME).exists()
 
+    @property
+    def is_applicant(self):
+        return not self.groups.exists()
+
     class Meta:
         ordering = ('full_name', 'email')