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) gatewayFromMetadata(md metadata.MD) (gtw *gateway.Gateway, err error) { gatewayID, err := api.IDFromMetadata(md) if err != nil { return nil, err } token, _ := api.TokenFromMetadata(md) if !viper.GetBool("router.skip-verify-gateway-token") { if token == "" { return nil, errors.NewErrPermissionDenied("No gateway token supplied") } if r.router.TokenKeyProvider == nil { return nil, errors.NewErrInternal("No token provider configured") } claims, err := claims.FromToken(r.router.TokenKeyProvider, token) if err != nil { return nil, errors.NewErrPermissionDenied(fmt.Sprintf("Gateway token invalid: %s", err.Error())) } if claims.Type != "gateway" || claims.Subject != gatewayID { return nil, errors.NewErrPermissionDenied("Gateway token not consistent") } } gtw = r.router.getGateway(gatewayID) gtw.SetToken(token) return gtw, nil }