Procházet zdrojové kódy

fix(api): Added error handling to create and update org http apis and sql update handlers, now checks for org name taken scenarios and returns correct http error code and message, fixes #2686

Torkel Ödegaard před 10 roky
rodič
revize
daf64421f2

+ 7 - 1
pkg/api/org.go

@@ -41,11 +41,14 @@ func getOrgHelper(orgId int64) Response {
 // POST /api/orgs
 func CreateOrg(c *middleware.Context, cmd m.CreateOrgCommand) Response {
 	if !c.IsSignedIn || (!setting.AllowUserOrgCreate && !c.IsGrafanaAdmin) {
-		return ApiError(401, "Access denied", nil)
+		return ApiError(403, "Access denied", nil)
 	}
 
 	cmd.UserId = c.UserId
 	if err := bus.Dispatch(&cmd); err != nil {
+		if err == m.ErrOrgNameTaken {
+			return ApiError(400, "Organization name taken", err)
+		}
 		return ApiError(500, "Failed to create organization", err)
 	}
 
@@ -71,6 +74,9 @@ func UpdateOrg(c *middleware.Context, cmd m.UpdateOrgCommand) Response {
 
 func updateOrgHelper(cmd m.UpdateOrgCommand) Response {
 	if err := bus.Dispatch(&cmd); err != nil {
+		if err == m.ErrOrgNameTaken {
+			return ApiError(400, "Organization name taken", err)
+		}
 		return ApiError(500, "Failed to update organization", err)
 	}
 

+ 2 - 1
pkg/models/org.go

@@ -7,7 +7,8 @@ import (
 
 // Typed errors
 var (
-	ErrOrgNotFound = errors.New("Organization not found")
+	ErrOrgNotFound  = errors.New("Organization not found")
+	ErrOrgNameTaken = errors.New("Organization name is taken")
 )
 
 type Org struct {

+ 28 - 0
pkg/services/sqlstore/org.go

@@ -62,9 +62,31 @@ func GetOrgByName(query *m.GetOrgByNameQuery) error {
 	return nil
 }
 
+func isOrgNameTaken(name string, existingId int64, sess *session) (bool, error) {
+	// check if org name is taken
+	var org m.Org
+	exists, err := sess.Where("name=?", name).Get(&org)
+
+	if err != nil {
+		return false, nil
+	}
+
+	if exists && existingId != org.Id {
+		return true, nil
+	}
+
+	return false, nil
+}
+
 func CreateOrg(cmd *m.CreateOrgCommand) error {
 	return inTransaction2(func(sess *session) error {
 
+		if isNameTaken, err := isOrgNameTaken(cmd.Name, 0, sess); err != nil {
+			return err
+		} else if isNameTaken {
+			return m.ErrOrgNameTaken
+		}
+
 		org := m.Org{
 			Name:    cmd.Name,
 			Created: time.Now(),
@@ -99,6 +121,12 @@ func CreateOrg(cmd *m.CreateOrgCommand) error {
 func UpdateOrg(cmd *m.UpdateOrgCommand) error {
 	return inTransaction2(func(sess *session) error {
 
+		if isNameTaken, err := isOrgNameTaken(cmd.Name, cmd.OrgId, sess); err != nil {
+			return err
+		} else if isNameTaken {
+			return m.ErrOrgNameTaken
+		}
+
 		org := m.Org{
 			Name:    cmd.Name,
 			Updated: time.Now(),

+ 12 - 14
public/app/features/org/partials/newOrg.html

@@ -10,20 +10,18 @@
 		<h2 style="margin-top: 30px;">Add Organization</h2>
 
 		<form name="form">
-			<div>
-				<div class="tight-form">
-					<ul class="tight-form-list">
-						<li class="tight-form-item" style="width: 100px;">
-							<strong>Org. name</strong>
-						</li>
-						<li>
-							<input type="text" ng-model="newOrg.name" required class="input-xxlarge tight-form-input last" placeholder="organization name">
-						</li>
-						<li>
-						</li>
-					</ul>
-					<div class="clearfix"></div>
-				</div>
+			<div class="tight-form last">
+				<ul class="tight-form-list">
+					<li class="tight-form-item" style="width: 100px;">
+						<strong>Org. name</strong>
+					</li>
+					<li>
+						<input type="text" ng-model="newOrg.name" required class="input-xxlarge tight-form-input last" placeholder="organization name">
+					</li>
+					<li>
+					</li>
+				</ul>
+				<div class="clearfix"></div>
 			</div>
 			<br>
 			<button class="btn btn-success pull-right" ng-click="createOrg()">Create</button>