mirror of
https://github.com/healthchecks/healthchecks.git
synced 2025-04-17 18:22:33 +00:00
Specify the read-write/read-only flag when inviting a team member.
This commit is contained in:
parent
adb004b333
commit
d73de68f70
6 changed files with 67 additions and 10 deletions
|
@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
|
|||
- Less verbose output in the `senddeletionnotices` command
|
||||
- Host a read-only dashboard (from github.com/healthchecks/dashboard/)
|
||||
- LINE Notify integration (#412)
|
||||
- Read-only team members
|
||||
|
||||
## Bug Fixes
|
||||
- Handle excessively long email addresses in the signup form
|
||||
|
|
|
@ -99,6 +99,7 @@ class ChangeEmailForm(forms.Form):
|
|||
|
||||
class InviteTeamMemberForm(forms.Form):
|
||||
email = LowercaseEmailField(max_length=254)
|
||||
rw = forms.BooleanField(required=False)
|
||||
|
||||
|
||||
class RemoveTeamMemberForm(forms.Form):
|
||||
|
|
|
@ -318,14 +318,14 @@ class Project(models.Model):
|
|||
used = q.distinct().count()
|
||||
return used < self.owner_profile.team_limit
|
||||
|
||||
def invite(self, user):
|
||||
def invite(self, user, rw):
|
||||
if Member.objects.filter(user=user, project=self).exists():
|
||||
return False
|
||||
|
||||
if self.owner_id == user.id:
|
||||
return False
|
||||
|
||||
Member.objects.create(user=user, project=self)
|
||||
Member.objects.create(user=user, project=self, rw=rw)
|
||||
checks_url = reverse("hc-checks", args=[self.code])
|
||||
user.profile.send_instant_login_link(self, redirect_url=checks_url)
|
||||
return True
|
||||
|
|
|
@ -65,7 +65,7 @@ class ProjectTestCase(BaseTestCase):
|
|||
def test_it_adds_team_member(self):
|
||||
self.client.login(username="alice@example.org", password="password")
|
||||
|
||||
form = {"invite_team_member": "1", "email": "frank@example.org"}
|
||||
form = {"invite_team_member": "1", "email": "frank@example.org", "rw": "1"}
|
||||
r = self.client.post(self.url, form)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
|
@ -76,6 +76,9 @@ class ProjectTestCase(BaseTestCase):
|
|||
project=self.project, user__email="frank@example.org"
|
||||
)
|
||||
|
||||
# The read-write flag should be set
|
||||
self.assertTrue(member.rw)
|
||||
|
||||
# The new user should not have their own project
|
||||
self.assertFalse(member.user.project_set.exists())
|
||||
|
||||
|
@ -86,6 +89,20 @@ class ProjectTestCase(BaseTestCase):
|
|||
)
|
||||
self.assertHTMLEqual(mail.outbox[0].subject, subj)
|
||||
|
||||
def test_it_adds_readonly_team_member(self):
|
||||
self.client.login(username="alice@example.org", password="password")
|
||||
|
||||
form = {"invite_team_member": "1", "email": "frank@example.org"}
|
||||
r = self.client.post(self.url, form)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
|
||||
member = Member.objects.get(
|
||||
project=self.project, user__email="frank@example.org"
|
||||
)
|
||||
|
||||
# The new user should not have their own project
|
||||
self.assertFalse(member.rw)
|
||||
|
||||
def test_it_adds_member_from_another_team(self):
|
||||
# With team limit at zero, we should not be able to invite any new users
|
||||
self.profile.team_limit = 0
|
||||
|
|
|
@ -306,7 +306,7 @@ def project(request, code):
|
|||
except User.DoesNotExist:
|
||||
user = _make_user(email, with_project=False)
|
||||
|
||||
if project.invite(user):
|
||||
if project.invite(user, rw=form.cleaned_data["rw"]):
|
||||
ctx["team_member_invited"] = email
|
||||
ctx["team_status"] = "success"
|
||||
else:
|
||||
|
|
|
@ -162,15 +162,21 @@
|
|||
<td>Owner</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
{% for user in project.team %}
|
||||
{% for m in project.member_set.all %}
|
||||
<tr>
|
||||
<td class="email">{{ user.email }}</td>
|
||||
<td>Member</td>
|
||||
<td class="email">{{ m.user.email }}</td>
|
||||
<td>
|
||||
{% if m.rw %}
|
||||
Member
|
||||
{% else %}
|
||||
Read-only
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if is_owner %}
|
||||
<a
|
||||
href="#"
|
||||
data-email="{{ user.email }}"
|
||||
data-email="{{ m.user.email }}"
|
||||
class="pull-right member-remove">Remove</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
|
@ -378,9 +384,10 @@
|
|||
<li>Team Members can create and manage Checks and Integrations</li>
|
||||
<li>Only the project owner (you) can view and edit billing settings</li>
|
||||
</ul>
|
||||
<br />
|
||||
<div class="form-group">
|
||||
<label for="itm-email" class="col-sm-2 control-label">Email</label>
|
||||
<div class="col-sm-9">
|
||||
<label for="itm-email" class="col-sm-3 control-label">Email</label>
|
||||
<div class="col-sm-8">
|
||||
<input
|
||||
type="email"
|
||||
class="form-control"
|
||||
|
@ -390,6 +397,37 @@
|
|||
placeholder="friend@example.org">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">Access Level</label>
|
||||
|
||||
<div class="col-sm-8">
|
||||
<label class="radio-container">
|
||||
<input
|
||||
type="radio"
|
||||
name="rw"
|
||||
value="1"
|
||||
checked>
|
||||
<span class="radiomark"></span>
|
||||
Team Member
|
||||
</label>
|
||||
<label class="radio-container">
|
||||
<input
|
||||
type="radio"
|
||||
name="rw"
|
||||
value="">
|
||||
<span class="radiomark"></span>
|
||||
Read-only
|
||||
<span class="help-block">
|
||||
Cannot modify checks or integrations.
|
||||
Cannot access project's API keys.
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
|
||||
|
|
Loading…
Add table
Reference in a new issue