// NewBasicAuthHandler handles basic HTTP auth against the provided user resource func NewBasicAuthHandler(users *resource.Resource) func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if u, p, ok := r.BasicAuth(); ok { // Lookup the user by its id ctx := r.Context() user, err := users.Get(ctx, u) if user != nil && err == resource.ErrUnauthorized { // Ignore unauthorized errors set by ourselves err = nil } if err != nil { // If user resource storage handler returned an error, respond with an error if err == resource.ErrNotFound { http.Error(w, "Invalid credential", http.StatusForbidden) } else { http.Error(w, err.Error(), http.StatusInternalServerError) } return } if schema.VerifyPassword(user.Payload["password"], []byte(p)) { // Store the auth user into the context for later use r = r.WithContext(NewContextWithUser(ctx, user)) next.ServeHTTP(w, r) return } } // Stop the middleware chain and return a 401 HTTP error w.Header().Set("WWW-Authenticate", `Basic realm="API"`) http.Error(w, "Please provide proper credentials", http.StatusUnauthorized) }) } }
// NewJWTHandler parse and validates JWT token if present and store it in the net/context func NewJWTHandler(users *resource.Resource, jwtKeyFunc jwt.Keyfunc) func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { token, err := request.ParseFromRequest(r, request.OAuth2Extractor, jwtKeyFunc) if err == request.ErrNoTokenInRequest { // If no token is found, let REST Layer hooks decide if the resource is public or not next.ServeHTTP(w, r) return } if err != nil || !token.Valid { // Here you may want to return JSON error http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return } claims := token.Claims.(jwt.MapClaims) userID, ok := claims["user_id"].(string) if !ok || userID == "" { // The provided token is malformed, user_id claim is missing http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } // Lookup the user by its id ctx := r.Context() user, err := users.Get(ctx, userID) if user != nil && err == resource.ErrUnauthorized { // Ignore unauthorized errors set by ourselves (see AuthResourceHook) err = nil } if err != nil { // If user resource storage handler returned an error, respond with an error if err == resource.ErrNotFound { http.Error(w, "Invalid credential", http.StatusForbidden) } else { http.Error(w, err.Error(), http.StatusInternalServerError) } return } // Store it into the request's context ctx = NewContextWithUser(ctx, user) r = r.WithContext(ctx) // If xlog is setup, store the user as logger field xlog.FromContext(ctx).SetField("user_id", user.ID) next.ServeHTTP(w, r) }) } }
func (t types) getGetQuery(idx resource.Index, r *resource.Resource) *graphql.Field { return &graphql.Field{ Description: fmt.Sprintf("Get %s by id", r.Name()), Type: t.getObjectType(idx, r), Args: graphql.FieldConfigArgument{ "id": &graphql.ArgumentConfig{ Type: graphql.String, }, }, Resolve: func(p graphql.ResolveParams) (interface{}, error) { id, ok := p.Args["id"].(string) if !ok { return nil, nil } item, err := r.Get(p.Context, id) if err != nil { return nil, err } return item.Payload, nil }, } }
func getSubFieldResolver(parentField string, r *resource.Resource, f schema.Field) graphql.FieldResolveFn { s, serialize := f.Validator.(schema.FieldSerializer) return func(p graphql.ResolveParams) (data interface{}, err error) { parent, ok := p.Source.(map[string]interface{}) if !ok { return nil, nil } var item *resource.Item // Get sub field resource item, err = r.Get(p.Context, parent[parentField]) if err != nil { return nil, err } data = item.Payload if f.Handler != nil { data, err = f.Handler(p.Context, data, p.Args) } if err == nil && serialize { data, err = s.Serialize(data) } return data, err } }