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 }
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) }
// 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 } }
// 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 } }
// 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 }