Browse Source

feat(datasources): allow updating of tls certs

The tls files are stored as a json blob in the
SecureJsonData field. To update one file, the
json has to be fetched from the db first and
then updated with the cert file that has been
changed.

Also, a change to the dto with flags that are
used in the frontend to show if a file has
been uploaded. For example, if tlsClientKeySet
is set to true then means a file for the
client key is saved in the db. This is to
avoid sending any private data to the frontend.
Daniel Lee 9 years ago
parent
commit
2893b25a05
2 changed files with 61 additions and 6 deletions
  1. 53 6
      pkg/api/datasources.go
  2. 8 0
      pkg/api/dtos/models.go

+ 53 - 6
pkg/api/datasources.go

@@ -104,17 +104,56 @@ func AddDataSource(c *middleware.Context, cmd m.AddDataSourceCommand) {
 	c.JSON(200, util.DynMap{"message": "Datasource added", "id": cmd.Result.Id})
 }
 
-func UpdateDataSource(c *middleware.Context, cmd m.UpdateDataSourceCommand) {
+func UpdateDataSource(c *middleware.Context, cmd m.UpdateDataSourceCommand) Response {
 	cmd.OrgId = c.OrgId
 	cmd.Id = c.ParamsInt64(":id")
 
-	err := bus.Dispatch(&cmd)
+	err := fillWithSecureJsonData(&cmd)
 	if err != nil {
-		c.JsonApiErr(500, "Failed to update datasource", err)
-		return
+		return ApiError(500, "Failed to update datasource", err)
+	}
+
+	err = bus.Dispatch(&cmd)
+	if err != nil {
+		return ApiError(500, "Failed to update datasource", err)
 	}
 
-	c.JsonOK("Datasource updated")
+	return Json(200, "Datasource updated")
+}
+
+func fillWithSecureJsonData(cmd *m.UpdateDataSourceCommand) error {
+	if len(cmd.SecureJsonData) == 0 {
+		return nil
+	}
+
+	ds, err := getRawDataSourceById(cmd.Id, cmd.OrgId)
+
+	if err != nil {
+		return err
+	}
+	secureJsonData := ds.SecureJsonData.Decrypt()
+
+	for k, v := range secureJsonData {
+
+		if _, ok := cmd.SecureJsonData[k]; !ok {
+			cmd.SecureJsonData[k] = v
+		}
+	}
+
+	return nil
+}
+
+func getRawDataSourceById(id int64, orgId int64) (*m.DataSource, error) {
+	query := m.GetDataSourceByIdQuery{
+		Id:    id,
+		OrgId: orgId,
+	}
+
+	if err := bus.Dispatch(&query); err != nil {
+		return nil, err
+	}
+
+	return query.Result, nil
 }
 
 // Get /api/datasources/name/:name
@@ -152,7 +191,7 @@ func GetDataSourceIdByName(c *middleware.Context) Response {
 }
 
 func convertModelToDtos(ds *m.DataSource) dtos.DataSource {
-	return dtos.DataSource{
+	dto := dtos.DataSource{
 		Id:                ds.Id,
 		OrgId:             ds.OrgId,
 		Name:              ds.Name,
@@ -169,4 +208,12 @@ func convertModelToDtos(ds *m.DataSource) dtos.DataSource {
 		IsDefault:         ds.IsDefault,
 		JsonData:          ds.JsonData,
 	}
+
+	if len(ds.SecureJsonData) > 0 {
+		dto.TLSAuth.CACertSet = len(ds.SecureJsonData["tlsCACert"]) > 0
+		dto.TLSAuth.ClientCertSet = len(ds.SecureJsonData["tlsClientCert"]) > 0
+		dto.TLSAuth.ClientKeySet = len(ds.SecureJsonData["tlsClientKey"]) > 0
+	}
+
+	return dto
 }

+ 8 - 0
pkg/api/dtos/models.go

@@ -81,6 +81,14 @@ type DataSource struct {
 	IsDefault         bool              `json:"isDefault"`
 	JsonData          *simplejson.Json  `json:"jsonData,omitempty"`
 	SecureJsonData    map[string]string `json:"secureJsonData,omitempty"`
+	TLSAuth           TLSAuth           `json:"tlsAuth,omitempty"`
+}
+
+// TLSAuth is used to show if TLS certs have been uploaded already
+type TLSAuth struct {
+	CACertSet     bool `json:"tlsCACertSet"`
+	ClientCertSet bool `json:"tlsClientCertSet"`
+	ClientKeySet  bool `json:"tlsClientKeySet"`
 }
 
 type DataSourceList []DataSource