github.com/adecaro/fabric-ca@v2.0.0-alpha+incompatible/lib/server/db/util/util.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package util
     8  
     9  import (
    10  	"fmt"
    11  	"path/filepath"
    12  	"regexp"
    13  	"strconv"
    14  	"strings"
    15  
    16  	"github.com/hyperledger/fabric-ca/lib/caerrors"
    17  )
    18  
    19  var (
    20  	dbURLRegex = regexp.MustCompile("(Datasource:\\s*)?(\\S+):(\\S+)@|(Datasource:.*\\s)?(user=\\S+).*\\s(password=\\S+)|(Datasource:.*\\s)?(password=\\S+).*\\s(user=\\S+)")
    21  )
    22  
    23  // Levels contains the levels of identities, affiliations, and certificates
    24  type Levels struct {
    25  	Identity    int
    26  	Affiliation int
    27  	Certificate int
    28  	Credential  int
    29  	RAInfo      int
    30  	Nonce       int
    31  }
    32  
    33  // GetDBName gets database name from connection string
    34  func GetDBName(datasource string) string {
    35  	var dbName string
    36  	datasource = strings.ToLower(datasource)
    37  
    38  	re := regexp.MustCompile(`(?:\/([^\/?]+))|(?:dbname=([^\s]+))`)
    39  	getName := re.FindStringSubmatch(datasource)
    40  	if getName != nil {
    41  		dbName = getName[1]
    42  		if dbName == "" {
    43  			dbName = getName[2]
    44  		}
    45  	}
    46  
    47  	return dbName
    48  }
    49  
    50  // MaskDBCred hides DB credentials in connection string
    51  func MaskDBCred(str string) string {
    52  	matches := dbURLRegex.FindStringSubmatch(str)
    53  
    54  	// If there is a match, there should be three entries: 1 for
    55  	// the match and 9 for submatches (see dbURLRegex regular expression)
    56  	if len(matches) == 10 {
    57  		matchIdxs := dbURLRegex.FindStringSubmatchIndex(str)
    58  		substr := str[matchIdxs[0]:matchIdxs[1]]
    59  		for idx := 1; idx < len(matches); idx++ {
    60  			if matches[idx] != "" {
    61  				if strings.Index(matches[idx], "user=") == 0 {
    62  					substr = strings.Replace(substr, matches[idx], "user=****", 1)
    63  				} else if strings.Index(matches[idx], "password=") == 0 {
    64  					substr = strings.Replace(substr, matches[idx], "password=****", 1)
    65  				} else {
    66  					substr = strings.Replace(substr, matches[idx], "****", 1)
    67  				}
    68  			}
    69  		}
    70  		str = str[:matchIdxs[0]] + substr + str[matchIdxs[1]:len(str)]
    71  	}
    72  	return str
    73  }
    74  
    75  // GetCADataSource returns a datasource with a unqiue database name
    76  func GetCADataSource(dbtype, datasource string, cacount int) string {
    77  	if dbtype == "sqlite3" {
    78  		ext := filepath.Ext(datasource)
    79  		dbName := strings.TrimSuffix(filepath.Base(datasource), ext)
    80  		datasource = fmt.Sprintf("%s_ca%d%s", dbName, cacount, ext)
    81  	} else {
    82  		dbName := getDBName(datasource)
    83  		datasource = strings.Replace(datasource, dbName, fmt.Sprintf("%s_ca%d", dbName, cacount), 1)
    84  	}
    85  	return datasource
    86  }
    87  
    88  // getDBName gets database name from connection string
    89  func getDBName(datasource string) string {
    90  	var dbName string
    91  	datasource = strings.ToLower(datasource)
    92  
    93  	re := regexp.MustCompile(`(?:\/([^\/?]+))|(?:dbname=([^\s]+))`)
    94  	getName := re.FindStringSubmatch(datasource)
    95  	if getName != nil {
    96  		dbName = getName[1]
    97  		if dbName == "" {
    98  			dbName = getName[2]
    99  		}
   100  	}
   101  
   102  	return dbName
   103  }
   104  
   105  // GetError wraps error passed in with context
   106  func GetError(err error, getType string) error {
   107  	if err.Error() == "sql: no rows in result set" {
   108  		return caerrors.NewHTTPErr(404, caerrors.ErrDBGet, "Failed to get %s: %s", getType, err)
   109  	}
   110  	return caerrors.NewHTTPErr(504, caerrors.ErrConnectingDB, "Failed to process database request: %s", err)
   111  }
   112  
   113  // IsGetError returns true of if the error is for is a database get error (not found)
   114  func IsGetError(err error) bool {
   115  	return strings.Contains(caerrors.Print(err), strconv.Itoa(caerrors.ErrDBGet))
   116  }