Beispiel #1
0
func (h *handlerManager) validateTTNAuthAppContext(ctx context.Context, appID string) (context.Context, *claims.Claims, error) {
	md, err := api.MetadataFromContext(ctx)
	if err != nil {
		return ctx, nil, err
	}
	// If token is empty, try to get the access key and convert it into a token
	token, err := api.TokenFromMetadata(md)
	if err != nil || token == "" {
		key, err := api.KeyFromMetadata(md)
		if err != nil {
			return ctx, nil, errors.NewErrInvalidArgument("Metadata", "neither token nor key present")
		}
		token, err := h.handler.Component.ExchangeAppKeyForToken(appID, key)
		if err != nil {
			return ctx, nil, err
		}
		md = metadata.Join(md, metadata.Pairs("token", token))
		ctx = metadata.NewContext(ctx, md)
	}
	claims, err := h.handler.Component.ValidateTTNAuthContext(ctx)
	if err != nil {
		return ctx, nil, err
	}
	if h.clientRate.Limit(claims.Subject) {
		return ctx, claims, grpc.Errorf(codes.ResourceExhausted, "Rate limit for client reached")
	}
	if h.applicationRate.Limit(appID) {
		return ctx, claims, grpc.Errorf(codes.ResourceExhausted, "Rate limit for application reached")
	}
	return ctx, claims, nil
}
Beispiel #2
0
func (r *routerRPC) gatewayFromContext(ctx context.Context) (gtw *gateway.Gateway, err error) {
	md, err := api.MetadataFromContext(ctx)
	if err != nil {
		return nil, err
	}
	return r.gatewayFromMetadata(md)
}
Beispiel #3
0
// GatewayStatus handles gateway status streams
func (s *RouterStreamServer) GatewayStatus(stream Router_GatewayStatusServer) error {
	md, err := api.MetadataFromContext(stream.Context())
	if err != nil {
		return err
	}
	ch, err := s.GatewayStatusChanFunc(md)
	if err != nil {
		return err
	}
	defer func() {
		close(ch)
	}()
	for {
		status, err := stream.Recv()
		if err == io.EOF {
			return stream.SendAndClose(&empty.Empty{})
		}
		if err != nil {
			return err
		}
		if err := status.Validate(); err != nil {
			return errors.Wrap(err, "Invalid Gateway Status")
		}
		ch <- status
	}
}
Beispiel #4
0
// Uplink handles uplink streams
func (s *RouterStreamServer) Uplink(stream Router_UplinkServer) (err error) {
	md, err := api.MetadataFromContext(stream.Context())
	if err != nil {
		return err
	}
	ch, err := s.UplinkChanFunc(md)
	if err != nil {
		return err
	}
	defer func() {
		ctx := s.ctx
		if err != nil {
			ctx = ctx.WithError(err)
		}
		close(ch)
		ctx.Debug("Closed Uplink stream")
	}()
	for {
		uplink, err := stream.Recv()
		if err == io.EOF {
			return stream.SendAndClose(&empty.Empty{})
		}
		if err != nil {
			return err
		}
		if err := uplink.Validate(); err != nil {
			return errors.Wrap(err, "Invalid Uplink")
		}
		ch <- uplink
	}
}
Beispiel #5
0
// Subscribe handles downlink streams
func (s *RouterStreamServer) Subscribe(req *SubscribeRequest, stream Router_SubscribeServer) (err error) {
	md, err := api.MetadataFromContext(stream.Context())
	if err != nil {
		return err
	}
	ch, cancel, err := s.DownlinkChanFunc(md)
	if err != nil {
		return err
	}
	go func() {
		<-stream.Context().Done()
		err = stream.Context().Err()
		cancel()
	}()
	for downlink := range ch {
		if err := stream.Send(downlink); err != nil {
			return err
		}
	}
	return
}