| 107 | } |
| 108 | |
| 109 | func Parse(schema string) (*AuthMeta, error) { |
| 110 | var meta AuthMeta |
| 111 | authInfoIdx := strings.LastIndex(schema, AuthMetaHeader) |
| 112 | if authInfoIdx == -1 { |
| 113 | return nil, nil |
| 114 | } |
| 115 | authInfo := schema[authInfoIdx:] |
| 116 | err := json.Unmarshal([]byte(authInfo[len(AuthMetaHeader):]), &meta) |
| 117 | if err == nil { |
| 118 | if err := meta.validate(); err != nil { |
| 119 | return nil, err |
| 120 | } |
| 121 | |
| 122 | if algoErr := meta.initSigningMethod(); algoErr != nil { |
| 123 | return nil, algoErr |
| 124 | } |
| 125 | |
| 126 | if meta.JWKUrl != "" { |
| 127 | meta.JWKUrls = append(meta.JWKUrls, meta.JWKUrl) |
| 128 | meta.JWKUrl = "" |
| 129 | } |
| 130 | |
| 131 | if len(meta.JWKUrls) != 0 { |
| 132 | meta.expiryTime = make([]time.Time, len(meta.JWKUrls)) |
| 133 | meta.jwkSet = make([]*jose.JSONWebKeySet, len(meta.JWKUrls)) |
| 134 | } |
| 135 | return &meta, nil |
| 136 | } |
| 137 | |
| 138 | fmt.Println("Falling back to parsing `Dgraph.Authorization` in old format." + |
| 139 | " Please check the updated syntax at https://graphql.dgraph.io/authorization/") |
| 140 | // Note: This is the old format for passing authorization information and this code |
| 141 | // is there to maintain backward compatibility. It may be removed in future release. |
| 142 | |
| 143 | // This regex matches authorization information present in the last line of the schema. |
| 144 | // Format: # Dgraph.Authorization <HTTP header> <Claim namespace> <Algorithm> "<verification key>" |
| 145 | // Example: # Dgraph.Authorization X-Test-Auth https://xyz.io/jwt/claims HS256 "secretkey" |
| 146 | // On successful regex match the index for the following strings will be returned. |
| 147 | // [0][0]:[0][1] : # Dgraph.Authorization X-Test-Auth https://xyz.io/jwt/claims HS256 "secretkey" |
| 148 | // [0][2]:[0][3] : Authorization, [0][4]:[0][5] : X-Test-Auth, |
| 149 | // [0][6]:[0][7] : https://xyz.io/jwt/claims, |
| 150 | // [0][8]:[0][9] : HS256, [0][10]:[0][11] : secretkey |
| 151 | authMetaRegex, err := |
| 152 | regexp.Compile(`^#[\s]([^\s]+)[\s]+([^\s]+)[\s]+([^\s]+)[\s]+([^\s]+)[\s]+"([^\"]+)"`) |
| 153 | if err != nil { |
| 154 | return nil, gqlerror.Errorf("JWT parsing failed: %v", err) |
| 155 | } |
| 156 | |
| 157 | // authInfo with be like `Dgraph.Authorization ...`, we append prefix `# ` to authinfo |
| 158 | // to make it work with the regex matching algorithm. |
| 159 | authInfo = "# " + authInfo |
| 160 | idx := authMetaRegex.FindAllStringSubmatchIndex(authInfo, -1) |
| 161 | if len(idx) != 1 || len(idx[0]) != 12 || |
| 162 | !strings.HasPrefix(authInfo, authInfo[idx[0][0]:idx[0][1]]) { |
| 163 | return nil, gqlerror.Errorf("Invalid `Dgraph.Authorization` format: %s", authInfo) |
| 164 | } |
| 165 | |
| 166 | meta.Header = authInfo[idx[0][4]:idx[0][5]] |