| 
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -165,9 +165,6 @@ func checkForAuthHeader(header http.Header) (string, bool) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// Context passed to each resolve execution
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				type ResolveContext struct {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // ID generated for the context so the gql extension can route data to it
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  ID uuid.UUID
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // Channels for the gql extension to route data to this context
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  Chans map[uuid.UUID]chan Signal
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -184,13 +181,15 @@ type ResolveContext struct {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  Ext *GQLExt
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // ID of the user that made this request
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // TODO: figure out auth
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  User NodeID
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // Key for the user that made this request, to sign resolver requests
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  // TODO: figure out some way to use a generated key so that the server can't impersonate the user afterwards
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  Key *ecdsa.PrivateKey
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				const GQL_RESOLVER_CHAN_SIZE = 10
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				func NewResolveContext(ctx *Context, server *Node, gql_ext *GQLExt, r *http.Request) (*ResolveContext, error) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  username, _, ok := r.BasicAuth()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  username, key_bytes, ok := r.BasicAuth()
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if ok == false {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return nil, fmt.Errorf("GQL_REQUEST_ERR: no auth header included in request header")
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
			
			 | 
			 | 
			
				@ -200,14 +199,24 @@ func NewResolveContext(ctx *Context, server *Node, gql_ext *GQLExt, r *http.Requ
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return nil, fmt.Errorf("GQL_REQUEST_ERR: failed to parse ID from auth username: %s", username)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  key, err := x509.ParseECPrivateKey([]byte(key_bytes))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if err != nil {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return nil, fmt.Errorf("GQL_REQUEST_ERR: failed to parse ecdsa key from auth password: %s", key_bytes)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  key_id := KeyID(&key.PublicKey)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  if auth_id != key_id {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    return nil, fmt.Errorf("GQL_REQUEST_ERR: key_id(%s) != auth_id(%s)", auth_id, key_id)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  return &ResolveContext{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Ext: gql_ext,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    ID: uuid.New(),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Chans: map[uuid.UUID]chan Signal{},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Context: ctx,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    GQLContext: ctx.Extensions[Hash(GQLExtType)].Data.(*GQLExtContext),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Server: server,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    User: auth_id,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    User: key_id,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    Key: key,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  }, nil
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -1050,7 +1059,7 @@ func (ext *GQLExt) Process(ctx *Context, source NodeID, node *Node, signal Signa
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    } else {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      ctx.Log.Logf("gql", "received error signal response %s with no mapped resolver", sig.UUID)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				      ctx.Log.Logf("gql", "received error signal response %+v with no mapped resolver", sig)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				  } else if signal.Type() == ReadResultSignalType {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    sig := signal.(ReadResultSignal)
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |