Commit 6d6af092 by Torkel Ödegaard

feat(invite): handling of existing org user case when inviting, #2353

parent ab549717
package api package api
import ( import (
"fmt"
"github.com/grafana/grafana/pkg/api/dtos" "github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/events" "github.com/grafana/grafana/pkg/events"
...@@ -43,6 +45,9 @@ func AddOrgInvite(c *middleware.Context, inviteDto dtos.AddInviteForm) Response ...@@ -43,6 +45,9 @@ func AddOrgInvite(c *middleware.Context, inviteDto dtos.AddInviteForm) Response
// user exists, add org role // user exists, add org role
createOrgUserCmd := m.AddOrgUserCommand{OrgId: c.OrgId, UserId: userQuery.Result.Id, Role: inviteDto.Role} createOrgUserCmd := m.AddOrgUserCommand{OrgId: c.OrgId, UserId: userQuery.Result.Id, Role: inviteDto.Role}
if err := bus.Dispatch(&createOrgUserCmd); err != nil { if err := bus.Dispatch(&createOrgUserCmd); err != nil {
if err == m.ErrOrgUserAlreadyAdded {
return ApiError(412, fmt.Sprintf("User %s is already added to organization", inviteDto.Email), err)
}
return ApiError(500, "Error while trying to create org user", err) return ApiError(500, "Error while trying to create org user", err)
} else { } else {
return ApiSuccess("Existing Grafana user added to org " + c.OrgName) return ApiSuccess("Existing Grafana user added to org " + c.OrgName)
...@@ -80,9 +85,10 @@ func AddOrgInvite(c *middleware.Context, inviteDto dtos.AddInviteForm) Response ...@@ -80,9 +85,10 @@ func AddOrgInvite(c *middleware.Context, inviteDto dtos.AddInviteForm) Response
if err := bus.Dispatch(&emailCmd); err != nil { if err := bus.Dispatch(&emailCmd); err != nil {
return ApiError(500, "Failed to send email invite", err) return ApiError(500, "Failed to send email invite", err)
} }
return ApiSuccess(fmt.Sprintf("Sent invite to %s", inviteDto.Email))
} }
return ApiSuccess("ok, done!") return ApiSuccess(fmt.Sprintf("Created invite for %s", inviteDto.Email))
} }
func RevokeInvite(c *middleware.Context) Response { func RevokeInvite(c *middleware.Context) Response {
......
...@@ -7,9 +7,10 @@ import ( ...@@ -7,9 +7,10 @@ import (
// Typed errors // Typed errors
var ( var (
ErrInvalidRoleType = errors.New("Invalid role type") ErrInvalidRoleType = errors.New("Invalid role type")
ErrLastOrgAdmin = errors.New("Cannot remove last organization admin") ErrLastOrgAdmin = errors.New("Cannot remove last organization admin")
ErrOrgUserNotFound = errors.New("Cannot find the organization user") ErrOrgUserNotFound = errors.New("Cannot find the organization user")
ErrOrgUserAlreadyAdded = errors.New("User is already added to organization")
) )
type RoleType string type RoleType string
......
...@@ -19,6 +19,12 @@ func init() { ...@@ -19,6 +19,12 @@ func init() {
func AddOrgUser(cmd *m.AddOrgUserCommand) error { func AddOrgUser(cmd *m.AddOrgUserCommand) error {
return inTransaction(func(sess *xorm.Session) error { return inTransaction(func(sess *xorm.Session) error {
// check if user exists
if res, err := sess.Query("SELECT 1 from org_user WHERE org_id=? and user_id=?", cmd.OrgId, cmd.UserId); err != nil {
return err
} else if len(res) == 1 {
return m.ErrOrgUserAlreadyAdded
}
entity := m.OrgUser{ entity := m.OrgUser{
OrgId: cmd.OrgId, OrgId: cmd.OrgId,
......
...@@ -7,7 +7,7 @@ function (angular, _) { ...@@ -7,7 +7,7 @@ function (angular, _) {
var module = angular.module('grafana.controllers'); var module = angular.module('grafana.controllers');
module.controller('UserInviteCtrl', function($scope, backendSrv, $q) { module.controller('UserInviteCtrl', function($scope, backendSrv) {
$scope.invites = [ $scope.invites = [
{name: '', email: '', role: 'Editor'}, {name: '', email: '', role: 'Editor'},
...@@ -26,17 +26,23 @@ function (angular, _) { ...@@ -26,17 +26,23 @@ function (angular, _) {
$scope.sendInvites = function() { $scope.sendInvites = function() {
if (!$scope.inviteForm.$valid) { return; } if (!$scope.inviteForm.$valid) { return; }
$scope.sendSingleInvite(0);
};
var promises = _.map($scope.invites, function(invite) { $scope.sendSingleInvite = function(index) {
invite.skipEmails = $scope.options.skipEmails; var invite = $scope.invites[index];
return backendSrv.post('/api/org/invites', invite); invite.skipEmails = $scope.options.skipEmails;
});
$q.all(promises).then(function() { return backendSrv.post('/api/org/invites', invite).finally(function() {
$scope.invitesSent(); index += 1;
});
$scope.dismiss(); if (index === $scope.invites.length) {
$scope.invitesSent();
$scope.dismiss();
} else {
$scope.sendSingleInvite(index);
}
});
}; };
}); });
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment