mirror of
https://github.com/mainflux/mainflux.git
synced 2025-05-02 22:17:10 +08:00

* adding certificate issuing Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * adding cert endpoint Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * update envs Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * update envs Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * move certs creation to sdk Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * move certs creation to sdk Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * move certs creation to sdk Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * fix env vars Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add comment Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * update sdk Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * fix vars Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add volumes Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * fix merge config for int Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * remove env Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * fix error handling Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add cert test, change receiver to pointer Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add docs Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * fix var naming Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * correct error naming Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * adding certs service Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add certs Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add certs Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * change func receiever Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add default cert issue method Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add config Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * small fix Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * remove some testing code Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add cert issue Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add vault api client Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * additional endpoints Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add swagger for certs Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * remove certs from provision Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * clean provision from certs Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add list certificates endpoint Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add vault api in vendor Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add certs Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add revoke, fix bugs Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * fix sdk for certs Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * minor changes, add env, doc Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * minor changes, add env, doc Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * minor changes, add env, doc Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * small changes Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * remove CA for signing from provision Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add docker file for certs Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * fix mock sdk Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add line Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * fix RevokeCert Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * renam ENV Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * remove tests temporarily Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * fix naming Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * renam vars Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add cli for issue cert Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add cli for issue cert Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add cli for issue cert Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add cli for issue cert Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * remove not needed envs Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * fix linter errors, add cli Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * fix linter errors, add cli, var rename Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * fix reviews, add viewcert, fix view all certs Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * remove view cert, as it will be retrieved from PKI Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * change endpoints Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add default env val Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * remove some errors Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * refactor, make wrapper lib for vault Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * refactor, make wrapper lib for vault Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * refactor, make wrapper lib for vault Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * fix revoking Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * refactor, make wrapper lib for vault Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * update vendor Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * fix comment Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * add comments Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * remove unused Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * remove unused field Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * update vendor Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * refactor pki Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * refactor pki Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * refactor pki, update vendor Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * refactor pki Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * fix comment Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * minor fix Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * remove methods, use fields Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * fix comments and package desc Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com> * fix comments and package desc Signed-off-by: Mirko Teodorovic <mirko.teodorovic@gmail.com>
222 lines
5.3 KiB
Go
222 lines
5.3 KiB
Go
package sqlx
|
|
|
|
import (
|
|
"bytes"
|
|
"database/sql/driver"
|
|
"errors"
|
|
"reflect"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/jmoiron/sqlx/reflectx"
|
|
)
|
|
|
|
// Bindvar types supported by Rebind, BindMap and BindStruct.
|
|
const (
|
|
UNKNOWN = iota
|
|
QUESTION
|
|
DOLLAR
|
|
NAMED
|
|
AT
|
|
)
|
|
|
|
// BindType returns the bindtype for a given database given a drivername.
|
|
func BindType(driverName string) int {
|
|
switch driverName {
|
|
case "postgres", "pgx", "pq-timeouts", "cloudsqlpostgres", "ql":
|
|
return DOLLAR
|
|
case "mysql":
|
|
return QUESTION
|
|
case "sqlite3":
|
|
return QUESTION
|
|
case "oci8", "ora", "goracle":
|
|
return NAMED
|
|
case "sqlserver":
|
|
return AT
|
|
}
|
|
return UNKNOWN
|
|
}
|
|
|
|
// FIXME: this should be able to be tolerant of escaped ?'s in queries without
|
|
// losing much speed, and should be to avoid confusion.
|
|
|
|
// Rebind a query from the default bindtype (QUESTION) to the target bindtype.
|
|
func Rebind(bindType int, query string) string {
|
|
switch bindType {
|
|
case QUESTION, UNKNOWN:
|
|
return query
|
|
}
|
|
|
|
// Add space enough for 10 params before we have to allocate
|
|
rqb := make([]byte, 0, len(query)+10)
|
|
|
|
var i, j int
|
|
|
|
for i = strings.Index(query, "?"); i != -1; i = strings.Index(query, "?") {
|
|
rqb = append(rqb, query[:i]...)
|
|
|
|
switch bindType {
|
|
case DOLLAR:
|
|
rqb = append(rqb, '$')
|
|
case NAMED:
|
|
rqb = append(rqb, ':', 'a', 'r', 'g')
|
|
case AT:
|
|
rqb = append(rqb, '@', 'p')
|
|
}
|
|
|
|
j++
|
|
rqb = strconv.AppendInt(rqb, int64(j), 10)
|
|
|
|
query = query[i+1:]
|
|
}
|
|
|
|
return string(append(rqb, query...))
|
|
}
|
|
|
|
// Experimental implementation of Rebind which uses a bytes.Buffer. The code is
|
|
// much simpler and should be more resistant to odd unicode, but it is twice as
|
|
// slow. Kept here for benchmarking purposes and to possibly replace Rebind if
|
|
// problems arise with its somewhat naive handling of unicode.
|
|
func rebindBuff(bindType int, query string) string {
|
|
if bindType != DOLLAR {
|
|
return query
|
|
}
|
|
|
|
b := make([]byte, 0, len(query))
|
|
rqb := bytes.NewBuffer(b)
|
|
j := 1
|
|
for _, r := range query {
|
|
if r == '?' {
|
|
rqb.WriteRune('$')
|
|
rqb.WriteString(strconv.Itoa(j))
|
|
j++
|
|
} else {
|
|
rqb.WriteRune(r)
|
|
}
|
|
}
|
|
|
|
return rqb.String()
|
|
}
|
|
|
|
// In expands slice values in args, returning the modified query string
|
|
// and a new arg list that can be executed by a database. The `query` should
|
|
// use the `?` bindVar. The return value uses the `?` bindVar.
|
|
func In(query string, args ...interface{}) (string, []interface{}, error) {
|
|
// argMeta stores reflect.Value and length for slices and
|
|
// the value itself for non-slice arguments
|
|
type argMeta struct {
|
|
v reflect.Value
|
|
i interface{}
|
|
length int
|
|
}
|
|
|
|
var flatArgsCount int
|
|
var anySlices bool
|
|
|
|
meta := make([]argMeta, len(args))
|
|
|
|
for i, arg := range args {
|
|
if a, ok := arg.(driver.Valuer); ok {
|
|
var err error
|
|
arg, err = a.Value()
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
}
|
|
v := reflect.ValueOf(arg)
|
|
t := reflectx.Deref(v.Type())
|
|
|
|
// []byte is a driver.Value type so it should not be expanded
|
|
if t.Kind() == reflect.Slice && t != reflect.TypeOf([]byte{}) {
|
|
meta[i].length = v.Len()
|
|
meta[i].v = v
|
|
|
|
anySlices = true
|
|
flatArgsCount += meta[i].length
|
|
|
|
if meta[i].length == 0 {
|
|
return "", nil, errors.New("empty slice passed to 'in' query")
|
|
}
|
|
} else {
|
|
meta[i].i = arg
|
|
flatArgsCount++
|
|
}
|
|
}
|
|
|
|
// don't do any parsing if there aren't any slices; note that this means
|
|
// some errors that we might have caught below will not be returned.
|
|
if !anySlices {
|
|
return query, args, nil
|
|
}
|
|
|
|
newArgs := make([]interface{}, 0, flatArgsCount)
|
|
buf := make([]byte, 0, len(query)+len(", ?")*flatArgsCount)
|
|
|
|
var arg, offset int
|
|
|
|
for i := strings.IndexByte(query[offset:], '?'); i != -1; i = strings.IndexByte(query[offset:], '?') {
|
|
if arg >= len(meta) {
|
|
// if an argument wasn't passed, lets return an error; this is
|
|
// not actually how database/sql Exec/Query works, but since we are
|
|
// creating an argument list programmatically, we want to be able
|
|
// to catch these programmer errors earlier.
|
|
return "", nil, errors.New("number of bindVars exceeds arguments")
|
|
}
|
|
|
|
argMeta := meta[arg]
|
|
arg++
|
|
|
|
// not a slice, continue.
|
|
// our questionmark will either be written before the next expansion
|
|
// of a slice or after the loop when writing the rest of the query
|
|
if argMeta.length == 0 {
|
|
offset = offset + i + 1
|
|
newArgs = append(newArgs, argMeta.i)
|
|
continue
|
|
}
|
|
|
|
// write everything up to and including our ? character
|
|
buf = append(buf, query[:offset+i+1]...)
|
|
|
|
for si := 1; si < argMeta.length; si++ {
|
|
buf = append(buf, ", ?"...)
|
|
}
|
|
|
|
newArgs = appendReflectSlice(newArgs, argMeta.v, argMeta.length)
|
|
|
|
// slice the query and reset the offset. this avoids some bookkeeping for
|
|
// the write after the loop
|
|
query = query[offset+i+1:]
|
|
offset = 0
|
|
}
|
|
|
|
buf = append(buf, query...)
|
|
|
|
if arg < len(meta) {
|
|
return "", nil, errors.New("number of bindVars less than number arguments")
|
|
}
|
|
|
|
return string(buf), newArgs, nil
|
|
}
|
|
|
|
func appendReflectSlice(args []interface{}, v reflect.Value, vlen int) []interface{} {
|
|
switch val := v.Interface().(type) {
|
|
case []interface{}:
|
|
args = append(args, val...)
|
|
case []int:
|
|
for i := range val {
|
|
args = append(args, val[i])
|
|
}
|
|
case []string:
|
|
for i := range val {
|
|
args = append(args, val[i])
|
|
}
|
|
default:
|
|
for si := 0; si < vlen; si++ {
|
|
args = append(args, v.Index(si).Interface())
|
|
}
|
|
}
|
|
|
|
return args
|
|
}
|