Compare commits
6 Commits
v0.14.17
...
hydra-comp
Author | SHA1 | Date | |
---|---|---|---|
88ba105b70 | |||
12d51559bf | |||
788f0459fb | |||
b37171c19f | |||
7557a4c29c | |||
dd4accfdd2 |
@ -139,7 +139,7 @@ func newSuperGraph(conf *Config, db *sql.DB, dbinfo *psql.DBInfo) (*SuperGraph,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(conf.SecretKey) != 0 {
|
||||
if conf.SecretKey != "" {
|
||||
sk := sha256.Sum256([]byte(conf.SecretKey))
|
||||
conf.SecretKey = ""
|
||||
sg.encKey = sk
|
||||
|
@ -82,7 +82,7 @@ func (sg *SuperGraph) buildMultiStmt(query, vars []byte) ([]stmt, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if len(sg.conf.RolesQuery) == 0 {
|
||||
if sg.conf.RolesQuery == "" {
|
||||
return nil, errors.New("roles_query not defined")
|
||||
}
|
||||
|
||||
@ -133,7 +133,7 @@ func (sg *SuperGraph) renderUserQuery(md psql.Metadata, stmts []stmt) (string, e
|
||||
io.WriteString(w, `SELECT "_sg_auth_info"."role", (CASE "_sg_auth_info"."role" `)
|
||||
|
||||
for _, s := range stmts {
|
||||
if len(s.role.Match) == 0 &&
|
||||
if s.role.Match == "" &&
|
||||
s.role.Name != "user" && s.role.Name != "anon" {
|
||||
continue
|
||||
}
|
||||
@ -150,7 +150,7 @@ func (sg *SuperGraph) renderUserQuery(md psql.Metadata, stmts []stmt) (string, e
|
||||
|
||||
io.WriteString(w, `(SELECT (CASE`)
|
||||
for _, s := range stmts {
|
||||
if len(s.role.Match) == 0 {
|
||||
if s.role.Match == "" {
|
||||
continue
|
||||
}
|
||||
io.WriteString(w, ` WHEN `)
|
||||
|
@ -152,7 +152,7 @@ type Delete struct {
|
||||
|
||||
// AddRoleTable function is a helper function to make it easy to add per-table
|
||||
// row-level config
|
||||
func (c *Config) AddRoleTable(role string, table string, conf interface{}) error {
|
||||
func (c *Config) AddRoleTable(role, table string, conf interface{}) error {
|
||||
var r *Role
|
||||
|
||||
for i := range c.Roles {
|
||||
|
@ -305,7 +305,7 @@ func (c *scontext) resolveSQL() ([]byte, *stmt, error) {
|
||||
err = row.Scan(&root)
|
||||
}
|
||||
|
||||
if len(role) == 0 {
|
||||
if role == "" {
|
||||
c.res.role = c.role
|
||||
} else {
|
||||
c.res.role = role
|
||||
|
@ -146,7 +146,7 @@ func (al *List) Load() ([]Item, error) {
|
||||
return parse(string(b), al.filepath)
|
||||
}
|
||||
|
||||
func parse(b string, filename string) ([]Item, error) {
|
||||
func parse(b, filename string) ([]Item, error) {
|
||||
var items []Item
|
||||
|
||||
var s scanner.Scanner
|
||||
|
@ -14,7 +14,7 @@ func TestGQLName1(t *testing.T) {
|
||||
|
||||
name := QueryName(q)
|
||||
|
||||
if len(name) != 0 {
|
||||
if name != "" {
|
||||
t.Fatal("Name should be empty, not ", name)
|
||||
}
|
||||
}
|
||||
|
@ -774,7 +774,7 @@ func (c *compilerContext) renderBaseSelect(sel *qcode.Select, ti *DBTableInfo, r
|
||||
case ti.IsSingular:
|
||||
io.WriteString(c.w, ` LIMIT ('1') :: integer`)
|
||||
|
||||
case len(sel.Paging.Limit) != 0:
|
||||
case sel.Paging.Limit != "":
|
||||
//fmt.Fprintf(w, ` LIMIT ('%s') :: integer`, c.sel.Paging.Limit)
|
||||
io.WriteString(c.w, ` LIMIT ('`)
|
||||
io.WriteString(c.w, sel.Paging.Limit)
|
||||
@ -787,7 +787,7 @@ func (c *compilerContext) renderBaseSelect(sel *qcode.Select, ti *DBTableInfo, r
|
||||
io.WriteString(c.w, ` LIMIT ('20') :: integer`)
|
||||
}
|
||||
|
||||
if len(sel.Paging.Offset) != 0 {
|
||||
if sel.Paging.Offset != "" {
|
||||
//fmt.Fprintf(w, ` OFFSET ('%s') :: integer`, c.sel.Paging.Offset)
|
||||
io.WriteString(c.w, ` OFFSET ('`)
|
||||
io.WriteString(c.w, sel.Paging.Offset)
|
||||
@ -1011,11 +1011,8 @@ func (c *compilerContext) renderExp(ex *qcode.Exp, ti *DBTableInfo, skipNested b
|
||||
return err
|
||||
}
|
||||
|
||||
} else {
|
||||
//fmt.Fprintf(w, `(("%s"."%s") `, c.sel.Name, val.Col)
|
||||
if err := c.renderOp(val, ti); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := c.renderOp(val, ti); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
//qcode.FreeExp(val)
|
||||
@ -1077,7 +1074,7 @@ func (c *compilerContext) renderOp(ex *qcode.Exp, ti *DBTableInfo) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(ex.Col) != 0 {
|
||||
if ex.Col != "" {
|
||||
if col, ok = ti.ColMap[ex.Col]; !ok {
|
||||
return fmt.Errorf("no column '%s' found ", ex.Col)
|
||||
}
|
||||
@ -1317,7 +1314,7 @@ func funcPrefixLen(fm map[string]*DBFunction, fn string) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func hasBit(n uint32, pos uint32) bool {
|
||||
func hasBit(n, pos uint32) bool {
|
||||
val := n & (1 << pos)
|
||||
return (val > 0)
|
||||
}
|
||||
|
@ -381,25 +381,25 @@ func withFragment3(t *testing.T) {
|
||||
compileGQLToPSQL(t, gql, nil, "anon")
|
||||
}
|
||||
|
||||
func withInlineFragment(t *testing.T) {
|
||||
gql := `
|
||||
query {
|
||||
users {
|
||||
... on users {
|
||||
id
|
||||
email
|
||||
}
|
||||
created_at
|
||||
... on user {
|
||||
first_name
|
||||
last_name
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
// func withInlineFragment(t *testing.T) {
|
||||
// gql := `
|
||||
// query {
|
||||
// users {
|
||||
// ... on users {
|
||||
// id
|
||||
// email
|
||||
// }
|
||||
// created_at
|
||||
// ... on user {
|
||||
// first_name
|
||||
// last_name
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// `
|
||||
|
||||
compileGQLToPSQL(t, gql, nil, "anon")
|
||||
}
|
||||
// compileGQLToPSQL(t, gql, nil, "anon")
|
||||
// }
|
||||
|
||||
func withCursor(t *testing.T) {
|
||||
gql := `query {
|
||||
|
@ -328,7 +328,7 @@ func (s *DBSchema) secondDegreeRels(t DBTable, cols []DBColumn) error {
|
||||
for i := range cols {
|
||||
c := cols[i]
|
||||
|
||||
if len(c.FKeyTable) == 0 {
|
||||
if c.FKeyTable == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -121,12 +121,10 @@ func (c *compilerContext) renderUpdateStmt(w io.Writer, qc *qcode.QCode, item re
|
||||
}
|
||||
io.WriteString(w, `)`)
|
||||
|
||||
} else {
|
||||
if qc.Selects[0].Where != nil {
|
||||
io.WriteString(w, `WHERE `)
|
||||
if err := c.renderWhere(&qc.Selects[0], ti); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if qc.Selects[0].Where != nil {
|
||||
io.WriteString(w, `WHERE `)
|
||||
if err := c.renderWhere(&qc.Selects[0], ti); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,8 +141,7 @@ func (l *lexer) current() (Pos, Pos) {
|
||||
func (l *lexer) emit(t itemType) {
|
||||
l.items = append(l.items, item{t, l.start, l.pos, l.line})
|
||||
// Some items contain text internally. If so, count their newlines.
|
||||
switch t {
|
||||
case itemStringVal:
|
||||
if t == itemStringVal {
|
||||
for i := l.start; i < l.pos; i++ {
|
||||
if l.input[i] == '\n' {
|
||||
l.line++
|
||||
@ -404,15 +403,15 @@ func isAlphaNumeric(r rune) bool {
|
||||
return r == '_' || unicode.IsLetter(r) || unicode.IsDigit(r)
|
||||
}
|
||||
|
||||
func equals(b []byte, s Pos, e Pos, val []byte) bool {
|
||||
func equals(b []byte, s, e Pos, val []byte) bool {
|
||||
return bytes.EqualFold(b[s:e], val)
|
||||
}
|
||||
|
||||
func contains(b []byte, s Pos, e Pos, chars string) bool {
|
||||
func contains(b []byte, s, e Pos, chars string) bool {
|
||||
return bytes.ContainsAny(b[s:e], chars)
|
||||
}
|
||||
|
||||
func lowercase(b []byte, s Pos, e Pos) {
|
||||
func lowercase(b []byte, s, e Pos) {
|
||||
for i := s; i < e; i++ {
|
||||
if b[i] >= 'A' && b[i] <= 'Z' {
|
||||
b[i] = ('a' + (b[i] - 'A'))
|
||||
|
@ -440,8 +440,6 @@ func (p *Parser) parseFragmentFields(st *Stack, fields []Field) ([]Field, error)
|
||||
}
|
||||
ff := fr.Fields
|
||||
|
||||
parent := &fields[pid]
|
||||
|
||||
n := int32(len(fields))
|
||||
fields = append(fields, ff...)
|
||||
|
||||
@ -454,9 +452,8 @@ func (p *Parser) parseFragmentFields(st *Stack, fields []Field) ([]Field, error)
|
||||
// previous field.
|
||||
if f.ParentID == -1 {
|
||||
f.ParentID = pid
|
||||
|
||||
if f.ParentID != -1 {
|
||||
parent.Children = append(parent.Children, f.ID)
|
||||
fields[pid].Children = append(fields[pid].Children, f.ID)
|
||||
}
|
||||
// Update all the other parents id's by our new place in this new array
|
||||
} else {
|
||||
@ -574,10 +571,8 @@ func (p *Parser) parseList() (*Node, error) {
|
||||
}
|
||||
if ty == 0 {
|
||||
ty = node.Type
|
||||
} else {
|
||||
if ty != node.Type {
|
||||
return nil, errors.New("All values in a list must be of the same type")
|
||||
}
|
||||
} else if ty != node.Type {
|
||||
return nil, errors.New("All values in a list must be of the same type")
|
||||
}
|
||||
node.Parent = parent
|
||||
nodes = append(nodes, node)
|
||||
|
@ -386,7 +386,7 @@ func (com *Compiler) compileQuery(qc *QCode, op *Operation, role string) error {
|
||||
s.Type = STUnion
|
||||
}
|
||||
|
||||
if len(field.Alias) != 0 {
|
||||
if field.Alias != "" {
|
||||
s.FieldName = field.Alias
|
||||
} else {
|
||||
s.FieldName = s.Name
|
||||
@ -481,6 +481,7 @@ func (com *Compiler) compileQuery(qc *QCode, op *Operation, role string) error {
|
||||
}
|
||||
|
||||
qc.Selects = selects[:id]
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -628,14 +629,12 @@ func (com *Compiler) compileArgNode(st *util.Stack, node *Node, usePool bool) (*
|
||||
}
|
||||
|
||||
// Objects inside a list
|
||||
if len(node.Name) == 0 {
|
||||
if node.Name == "" {
|
||||
pushChildren(st, node.exp, node)
|
||||
continue
|
||||
|
||||
} else {
|
||||
if _, ok := com.bl[node.Name]; ok {
|
||||
continue
|
||||
}
|
||||
} else if _, ok := com.bl[node.Name]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
ex, err := newExp(st, node, usePool)
|
||||
@ -1049,7 +1048,7 @@ func setWhereColName(ex *Exp, node *Node) {
|
||||
if n.Type != NodeObj {
|
||||
continue
|
||||
}
|
||||
if len(n.Name) != 0 {
|
||||
if n.Name != "" {
|
||||
k := n.Name
|
||||
if k == "and" || k == "or" || k == "not" ||
|
||||
k == "_and" || k == "_or" || k == "_not" {
|
||||
|
@ -75,7 +75,7 @@ func (sg *SuperGraph) initPrepared() error {
|
||||
h.SetSeed(sg.hashSeed)
|
||||
|
||||
for _, v := range list {
|
||||
if len(v.Query) == 0 {
|
||||
if v.Query == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -113,7 +113,7 @@ func (sg *SuperGraph) prepareRoleStmt() error {
|
||||
|
||||
io.WriteString(w, `(SELECT (CASE`)
|
||||
for _, role := range sg.conf.Roles {
|
||||
if len(role.Match) == 0 {
|
||||
if role.Match == "" {
|
||||
continue
|
||||
}
|
||||
io.WriteString(w, ` WHEN `)
|
||||
@ -159,7 +159,7 @@ func (sg *SuperGraph) initAllowList() error {
|
||||
}
|
||||
|
||||
// nolint: errcheck
|
||||
func queryID(h *maphash.Hash, name string, role string) uint64 {
|
||||
func queryID(h *maphash.Hash, name, role string) uint64 {
|
||||
h.WriteString(name)
|
||||
h.WriteString(role)
|
||||
v := h.Sum64()
|
||||
|
@ -238,7 +238,7 @@ func (sg *SuperGraph) parentFieldIds(h *maphash.Hash, sel []qcode.Select, skippe
|
||||
return fm, sm
|
||||
}
|
||||
|
||||
func isSkipped(n uint32, pos uint32) bool {
|
||||
func isSkipped(n, pos uint32) bool {
|
||||
return ((n & (1 << pos)) != 0)
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ func (sg *SuperGraph) initRemotes(t Table) error {
|
||||
|
||||
// if no table column specified in the config then
|
||||
// use the primary key of the table as the id
|
||||
if len(idcol) == 0 {
|
||||
if idcol == "" {
|
||||
pcol, err := sg.pc.IDColumn(t.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -3,7 +3,7 @@ package core
|
||||
import "hash/maphash"
|
||||
|
||||
// nolint: errcheck
|
||||
func mkkey(h *maphash.Hash, k1 string, k2 string) uint64 {
|
||||
func mkkey(h *maphash.Hash, k1, k2 string) uint64 {
|
||||
h.WriteString(k1)
|
||||
h.WriteString(k2)
|
||||
v := h.Sum64()
|
||||
|
2
go.mod
2
go.mod
@ -14,6 +14,7 @@ require (
|
||||
github.com/brianvoe/gofakeit/v5 v5.2.0
|
||||
github.com/chirino/graphql v0.0.0-20200430165312-293648399b1a
|
||||
github.com/daaku/go.zipexe v1.0.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/dlclark/regexp2 v1.2.0 // indirect
|
||||
github.com/dop251/goja v0.0.0-20200424152103-d0b8fda54cd0
|
||||
@ -24,6 +25,7 @@ require (
|
||||
github.com/gosimple/slug v1.9.0
|
||||
github.com/jackc/pgtype v1.3.0
|
||||
github.com/jackc/pgx/v4 v4.6.0
|
||||
github.com/lestrrat-go/jwx v1.0.2
|
||||
github.com/mitchellh/mapstructure v1.2.2 // indirect
|
||||
github.com/openzipkin/zipkin-go v0.2.2
|
||||
github.com/pelletier/go-toml v1.7.0 // indirect
|
||||
|
11
go.sum
11
go.sum
@ -229,6 +229,11 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lestrrat-go/iter v0.0.0-20200422075355-fc1769541911 h1:FvnrqecqX4zT0wOIbYK1gNgTm0677INEWiFY8UEYggY=
|
||||
github.com/lestrrat-go/iter v0.0.0-20200422075355-fc1769541911/go.mod h1:zIdgO1mRKhn8l9vrZJZz9TUMMFbQbLeTsbqPDrJ/OJc=
|
||||
github.com/lestrrat-go/jwx v1.0.2 h1:FsbZg/v979RikHWhSu/7BRHh2Z1Z8byPleURRb1Y0XI=
|
||||
github.com/lestrrat-go/jwx v1.0.2/go.mod h1:TPF17WiSFegZo+c20fdpw49QD+/7n4/IsGvEmCSWwT0=
|
||||
github.com/lestrrat-go/pdebug v0.0.0-20200204225717-4d6bd78da58d/go.mod h1:B06CSso/AWxiPejj+fheUINGeBKeeEZNt8w+EoU7+L8=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
|
||||
@ -377,6 +382,7 @@ github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8W
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0=
|
||||
@ -422,6 +428,7 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -442,6 +449,8 @@ golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
|
||||
@ -505,8 +514,10 @@ golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200128220307-520188d60f50 h1:0qnG0gwzB6QPiLDow10WJDdB38c+hQ7ArxO26Qc1boM=
|
||||
golang.org/x/tools v0.0.0-20200128220307-520188d60f50/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200417140056-c07e33ef3290/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
|
||||
|
@ -46,6 +46,8 @@ type Serv struct {
|
||||
SeedFile string `mapstructure:"seed_file"`
|
||||
MigrationsPath string `mapstructure:"migrations_path"`
|
||||
AllowedOrigins []string `mapstructure:"cors_allowed_origins"`
|
||||
AllowedMethods []string `mapstructure:"cors_allowed_methods"`
|
||||
AllowedHeaders []string `mapstructure:"cors_allowed_headers"`
|
||||
DebugCORS bool `mapstructure:"cors_debug"`
|
||||
APIPath string `mapstructure:"api_path"`
|
||||
CacheControl string `mapstructure:"cache_control"`
|
||||
|
@ -155,7 +155,7 @@ func cmdVersion(cmd *cobra.Command, args []string) {
|
||||
}
|
||||
|
||||
func BuildDetails() string {
|
||||
if len(version) == 0 {
|
||||
if version == "" {
|
||||
return `
|
||||
Super Graph (unknown version)
|
||||
For documentation, visit https://supergraph.dev
|
||||
|
@ -80,7 +80,7 @@ func cmdDBSeed(cmd *cobra.Command, args []string) {
|
||||
func graphQLFunc(sg *core.SuperGraph, query string, data interface{}, opt map[string]string) map[string]interface{} {
|
||||
ct := context.Background()
|
||||
|
||||
if v, ok := opt["user_id"]; ok && len(v) != 0 {
|
||||
if v, ok := opt["user_id"]; ok && v != "" {
|
||||
ct = context.WithValue(ct, core.UserIDKey, v)
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@ func (c *csvSource) Values() ([]interface{}, error) {
|
||||
|
||||
for _, v := range c.rows[c.i] {
|
||||
switch {
|
||||
case len(v) == 0:
|
||||
case v == "":
|
||||
vals = append(vals, "")
|
||||
case isDigit(v):
|
||||
var n int
|
||||
@ -243,7 +243,7 @@ func avatarURL(size int) string {
|
||||
return fmt.Sprintf("https://i.pravatar.cc/%d?%d", size, rand.Intn(5000))
|
||||
}
|
||||
|
||||
func imageURL(width int, height int) string {
|
||||
func imageURL(width, height int) string {
|
||||
return fmt.Sprintf("https://picsum.photos/%d/%d?%d", width, height, rand.Intn(5000))
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ func newViper(configPath, configFile string) *viper.Viper {
|
||||
}
|
||||
|
||||
func GetConfigName() string {
|
||||
if len(os.Getenv("GO_ENV")) == 0 {
|
||||
if os.Getenv("GO_ENV") == "" {
|
||||
return "dev"
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,8 @@ func apiV1Handler() http.Handler {
|
||||
if len(conf.AllowedOrigins) != 0 {
|
||||
c := cors.New(cors.Options{
|
||||
AllowedOrigins: conf.AllowedOrigins,
|
||||
AllowedHeaders: conf.AllowedHeaders,
|
||||
AllowedMethods: conf.AllowedMethods,
|
||||
AllowCredentials: true,
|
||||
Debug: conf.DebugCORS,
|
||||
})
|
||||
@ -105,7 +107,7 @@ func apiV1(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
if len(conf.CacheControl) != 0 && res.Operation() == core.OpQuery {
|
||||
if conf.CacheControl != "" && res.Operation() == core.OpQuery {
|
||||
w.Header().Set("Cache-Control", conf.CacheControl)
|
||||
}
|
||||
//nolint: errcheck
|
||||
|
@ -33,6 +33,7 @@ type Auth struct {
|
||||
PubKeyFile string `mapstructure:"public_key_file"`
|
||||
PubKeyType string `mapstructure:"public_key_type"`
|
||||
Audience string `mapstructure:"audience"`
|
||||
JWKSURL string `mapstructure:"jwks_url"`
|
||||
}
|
||||
|
||||
Header struct {
|
||||
@ -47,17 +48,17 @@ func SimpleHandler(ac *Auth, next http.Handler) (http.HandlerFunc, error) {
|
||||
ctx := r.Context()
|
||||
|
||||
userIDProvider := r.Header.Get("X-User-ID-Provider")
|
||||
if len(userIDProvider) != 0 {
|
||||
if userIDProvider != "" {
|
||||
ctx = context.WithValue(ctx, core.UserIDProviderKey, userIDProvider)
|
||||
}
|
||||
|
||||
userID := r.Header.Get("X-User-ID")
|
||||
if len(userID) != 0 {
|
||||
if userID != "" {
|
||||
ctx = context.WithValue(ctx, core.UserIDKey, userID)
|
||||
}
|
||||
|
||||
userRole := r.Header.Get("X-User-Role")
|
||||
if len(userRole) != 0 {
|
||||
if userRole != "" {
|
||||
ctx = context.WithValue(ctx, core.UserRoleKey, userRole)
|
||||
}
|
||||
|
||||
@ -68,11 +69,11 @@ func SimpleHandler(ac *Auth, next http.Handler) (http.HandlerFunc, error) {
|
||||
func HeaderHandler(ac *Auth, next http.Handler) (http.HandlerFunc, error) {
|
||||
hdr := ac.Header
|
||||
|
||||
if len(hdr.Name) == 0 {
|
||||
if hdr.Name == "" {
|
||||
return nil, fmt.Errorf("auth '%s': no header.name defined", ac.Name)
|
||||
}
|
||||
|
||||
if !hdr.Exists && len(hdr.Value) == 0 {
|
||||
if !hdr.Exists && hdr.Value == "" {
|
||||
return nil, fmt.Errorf("auth '%s': no header.value defined", ac.Name)
|
||||
}
|
||||
|
||||
@ -82,7 +83,7 @@ func HeaderHandler(ac *Auth, next http.Handler) (http.HandlerFunc, error) {
|
||||
|
||||
switch {
|
||||
case hdr.Exists:
|
||||
fo1 = (len(value) == 0)
|
||||
fo1 = (value == "")
|
||||
|
||||
default:
|
||||
fo1 = (value != hdr.Value)
|
||||
|
@ -3,12 +3,17 @@ package auth
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/lestrrat-go/jwx/jwk"
|
||||
|
||||
jwt "github.com/dgrijalva/jwt-go"
|
||||
"github.com/dosco/super-graph/core"
|
||||
)
|
||||
@ -28,6 +33,30 @@ type firebasePKCache struct {
|
||||
|
||||
var firebasePublicKeys firebasePKCache
|
||||
|
||||
type standardClaims struct {
|
||||
jwt.StandardClaims
|
||||
Audience []string `json:"aud,omitempty"`
|
||||
}
|
||||
|
||||
func (c *standardClaims) MatchAudience(audience string) bool {
|
||||
matchLegacy := c.StandardClaims.Audience == audience
|
||||
if matchLegacy {
|
||||
return true
|
||||
}
|
||||
|
||||
if c.Audience == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, tokenAudience := range c.Audience {
|
||||
if audience == tokenAudience {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func JwtHandler(ac *Auth, next http.Handler) (http.HandlerFunc, error) {
|
||||
var key interface{}
|
||||
var jwtProvider int
|
||||
@ -42,12 +71,13 @@ func JwtHandler(ac *Auth, next http.Handler) (http.HandlerFunc, error) {
|
||||
|
||||
secret := ac.JWT.Secret
|
||||
publicKeyFile := ac.JWT.PubKeyFile
|
||||
jwksURL := ac.JWT.JWKSURL
|
||||
|
||||
switch {
|
||||
case len(secret) != 0:
|
||||
case secret != "":
|
||||
key = []byte(secret)
|
||||
|
||||
case len(publicKeyFile) != 0:
|
||||
case publicKeyFile != "":
|
||||
kd, err := ioutil.ReadFile(publicKeyFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -74,7 +104,7 @@ func JwtHandler(ac *Auth, next http.Handler) (http.HandlerFunc, error) {
|
||||
|
||||
var tok string
|
||||
|
||||
if len(cookie) != 0 {
|
||||
if cookie != "" {
|
||||
ck, err := r.Cookie(cookie)
|
||||
if err != nil {
|
||||
next.ServeHTTP(w, r)
|
||||
@ -94,22 +124,26 @@ func JwtHandler(ac *Auth, next http.Handler) (http.HandlerFunc, error) {
|
||||
if jwtProvider == jwtFirebase {
|
||||
keyFunc = firebaseKeyFunction
|
||||
} else {
|
||||
keyFunc = func(token *jwt.Token) (interface{}, error) {
|
||||
return key, nil
|
||||
if jwksURL != "" {
|
||||
keyFunc = createJWKSKeyFetchFunc(jwksURL)
|
||||
} else {
|
||||
keyFunc = func(token *jwt.Token) (interface{}, error) {
|
||||
return key, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
token, err := jwt.ParseWithClaims(tok, &jwt.StandardClaims{}, keyFunc)
|
||||
|
||||
token, err := jwt.ParseWithClaims(tok, &standardClaims{}, keyFunc)
|
||||
if err != nil {
|
||||
log.Printf("[ERR] %s", err)
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
if claims, ok := token.Claims.(*jwt.StandardClaims); ok {
|
||||
if claims, ok := token.Claims.(*standardClaims); ok {
|
||||
ctx := r.Context()
|
||||
|
||||
if ac.JWT.Audience != "" && claims.Audience != ac.JWT.Audience {
|
||||
if ac.JWT.Audience != "" && !claims.MatchAudience(ac.JWT.Audience) {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
@ -223,3 +257,28 @@ func firebaseKeyFunction(token *jwt.Token) (interface{}, error) {
|
||||
Message: "Error no matching public key for kid supplied in jwt",
|
||||
}
|
||||
}
|
||||
|
||||
func createJWKSKeyFetchFunc(jwksURL string) func(token *jwt.Token) (interface{}, error) {
|
||||
return func(token *jwt.Token) (interface{}, error) {
|
||||
set, err := jwk.FetchHTTP(jwksURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
keyID, ok := token.Header["kid"].(string)
|
||||
if !ok {
|
||||
return nil, errors.New("expecting JWT header to have string kid")
|
||||
}
|
||||
|
||||
if key := set.LookupKeyID(keyID); len(key) == 1 {
|
||||
var rawKey interface{}
|
||||
if err := key[0].Raw(&rawKey); err != nil {
|
||||
return nil, fmt.Errorf("unable to retrieve raw key %q", keyID)
|
||||
}
|
||||
|
||||
return rawKey, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("unable to find key %q", keyID)
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ func railsAuth(ac *Auth) (*rails.Auth, error) {
|
||||
}
|
||||
|
||||
version := ac.Rails.Version
|
||||
if len(version) == 0 {
|
||||
if version == "" {
|
||||
return nil, errors.New("no auth.rails.version defined")
|
||||
}
|
||||
|
||||
|
@ -199,7 +199,7 @@ func (m *Migrator) LoadMigrations(path string) error {
|
||||
for _, v := range strings.Split(upSQL, "\n") {
|
||||
// Only account for regular single line comment, empty line and space/comment combination
|
||||
cleanString := strings.TrimSpace(v)
|
||||
if len(cleanString) != 0 &&
|
||||
if cleanString != "" &&
|
||||
!strings.HasPrefix(cleanString, "--") {
|
||||
containsSQL = true
|
||||
break
|
||||
|
@ -27,7 +27,7 @@ func initWatcher() {
|
||||
}
|
||||
|
||||
var d dir
|
||||
if len(cpath) == 0 || cpath == "./" {
|
||||
if cpath == "" || cpath == "./" {
|
||||
d = Dir("./config", ReExec)
|
||||
} else {
|
||||
d = Dir(cpath, ReExec)
|
||||
@ -52,11 +52,11 @@ func startHTTP() {
|
||||
hp := strings.SplitN(conf.HostPort, ":", 2)
|
||||
|
||||
if len(hp) == 2 {
|
||||
if len(conf.Host) != 0 {
|
||||
if conf.Host != "" {
|
||||
hp[0] = conf.Host
|
||||
}
|
||||
|
||||
if len(conf.Port) != 0 {
|
||||
if conf.Port != "" {
|
||||
hp[1] = conf.Port
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ func startHTTP() {
|
||||
}
|
||||
}
|
||||
|
||||
if len(conf.hostPort) == 0 {
|
||||
if conf.hostPort == "" {
|
||||
conf.hostPort = defaultHP
|
||||
}
|
||||
|
||||
@ -123,7 +123,7 @@ func routeHandler() (http.Handler, error) {
|
||||
return mux, nil
|
||||
}
|
||||
|
||||
if len(conf.APIPath) != 0 {
|
||||
if conf.APIPath != "" {
|
||||
apiRoute = path.Join("/", conf.APIPath, "/v1/graphql")
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user