Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(GraphQL): Maintain backward compatibility for Dgraph.Authorization in schema. #6014

Merged
merged 2 commits into from
Jul 16, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 42 additions & 4 deletions graphql/authorization/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@ import (
"encoding/json"
"fmt"
"net/http"
"regexp"
"strings"

"github.com/vektah/gqlparser/v2/gqlerror"

"github.com/dgrijalva/jwt-go/v4"
"github.com/pkg/errors"
"google.golang.org/grpc/metadata"
Expand Down Expand Up @@ -87,12 +90,47 @@ func Parse(schema string) (AuthMeta, error) {
authInfo := schema[authInfoIdx:]

err := json.Unmarshal([]byte(authInfo[len(AuthMetaHeader):]), &meta)
if err == nil {
return meta, meta.validate()
}

fmt.Println("Falling back to parsing `Dgraph.Authorization` in old format." +
" Please check the updated syntax at https://graphql.dgraph.io/authorization/")
// Note: This is the old format for passing authorization information and this code
// is there to maintain backward compatibility. It may be removed in future release.

// This regex matches authorization information present in the last line of the schema.
// Format: # Dgraph.Authorization <HTTP header> <Claim namespace> <Algorithm> "<verification key>"
// Example: # Dgraph.Authorization X-Test-Auth https://xyz.io/jwt/claims HS256 "secretkey"
// On successful regex match the index for the following strings will be returned.
// [0][0]:[0][1] : # Dgraph.Authorization X-Test-Auth https://xyz.io/jwt/claims HS256 "secretkey"
// [0][2]:[0][3] : Authorization, [0][4]:[0][5] : X-Test-Auth,
// [0][6]:[0][7] : https://xyz.io/jwt/claims,
// [0][8]:[0][9] : HS256, [0][10]:[0][11] : secretkey
authMetaRegex, err :=
regexp.Compile(`^#[\s]([^\s]+)[\s]+([^\s]+)[\s]+([^\s]+)[\s]+([^\s]+)[\s]+"([^\"]+)"`)
if err != nil {
return meta, fmt.Errorf("Unable to parse Dgraph.Authorization. " +
"It may be that you are using the pre-release syntax. " +
"Please check the correct syntax at https://graphql.dgraph.io/authorization/")
return meta, gqlerror.Errorf("JWT parsing failed: %v", err)
}

idx := authMetaRegex.FindAllStringSubmatchIndex(authInfo, -1)
if len(idx) != 1 || len(idx[0]) != 12 ||
!strings.HasPrefix(authInfo, authInfo[idx[0][0]:idx[0][1]]) {
return meta, gqlerror.Errorf("Invalid `Dgraph.Authorization` format: %s", authInfo)
}

meta.Header = authInfo[idx[0][4]:idx[0][5]]
meta.Namespace = authInfo[idx[0][6]:idx[0][7]]
meta.Algo = authInfo[idx[0][8]:idx[0][9]]
meta.VerificationKey = authInfo[idx[0][10]:idx[0][11]]
if meta.Algo == HMAC256 {
return meta, nil
}
if meta.Algo != RSA256 {
return meta, errors.Errorf(
"invalid jwt algorithm: found %s, but supported options are HS256 or RS256", meta.Algo)
}
return meta, meta.validate()
return meta, nil
}

func ParseAuthMeta(schema string) error {
Expand Down
21 changes: 18 additions & 3 deletions graphql/schema/wrappers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -980,11 +980,26 @@ func TestParseSecrets(t *testing.T) {
# Dgraph.Authorization X-Test-Dgraph https://dgraph.io/jwt/claims HS256 "key"
# Dgraph.Secret STRIPE_API_KEY "stripe-api-key-value"
`,
map[string]string{"GITHUB_API_TOKEN": "some-super-secret-token",
"STRIPE_API_KEY": "stripe-api-key-value"},
"X-Test-Dgraph",
nil,
},
{
"Dgraph.Authorization old format error",
`
type User {
id: ID!
name: String!
}

# Dgraph.Secret "GITHUB_API_TOKEN" "some-super-secret-token"
# Dgraph.Authorization X-Test-Dgraph https://dgraph.io/jwt/claims "key"
# Dgraph.Secret STRIPE_API_KEY "stripe-api-key-value"
`,
nil,
"",
errors.New("Unable to parse Dgraph.Authorization. " +
"It may be that you are using the pre-release syntax. " +
"Please check the correct syntax at https://graphql.dgraph.io/authorization/"),
errors.New("input: Invalid `Dgraph.Authorization` format: # Dgraph.Authorization X-Test-Dgraph https://dgraph.io/jwt/claims \"key\""),
},
{
"should throw an error if multiple authorization values are specified",
Expand Down