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 }