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 }
func (h *handlerManager) SetApplication(ctx context.Context, in *pb.Application) (*empty.Empty, error) { if err := in.Validate(); err != nil { return nil, errors.Wrap(err, "Invalid Application") } ctx, claims, err := h.validateTTNAuthAppContext(ctx, in.AppId) if err != nil { return nil, err } if !claims.AppRight(in.AppId, rights.AppSettings) { return nil, errors.NewErrPermissionDenied(`No "settings" rights to application`) } app, err := h.handler.applications.Get(in.AppId) if err != nil { return nil, err } app.StartUpdate() app.Decoder = in.Decoder app.Converter = in.Converter app.Validator = in.Validator app.Encoder = in.Encoder err = h.handler.applications.Set(app) if err != nil { return nil, err } return &empty.Empty{}, nil }
func (h *handlerManager) DeleteDevice(ctx context.Context, in *pb.DeviceIdentifier) (*empty.Empty, error) { if err := in.Validate(); err != nil { return nil, errors.Wrap(err, "Invalid Device Identifier") } ctx, claims, err := h.validateTTNAuthAppContext(ctx, in.AppId) if err != nil { return nil, err } if !claims.AppRight(in.AppId, rights.Devices) { return nil, errors.NewErrPermissionDenied(fmt.Sprintf(`No "devices" rights to application "%s"`, in.AppId)) } if _, err := h.handler.applications.Get(in.AppId); err != nil { return nil, errors.Wrap(err, "Application not registered to this Handler") } dev, err := h.handler.devices.Get(in.AppId, in.DevId) if err != nil { return nil, err } _, err = h.deviceManager.DeleteDevice(ctx, &pb_lorawan.DeviceIdentifier{AppEui: &dev.AppEUI, DevEui: &dev.DevEUI}) if err != nil && errors.GetErrType(errors.FromGRPCError(err)) != errors.NotFound { return nil, errors.Wrap(errors.FromGRPCError(err), "Broker did not delete device") } err = h.handler.devices.Delete(in.AppId, in.DevId) if err != nil { return nil, err } return &empty.Empty{}, nil }
func (n *networkServerManager) SetDevice(ctx context.Context, in *pb_lorawan.Device) (*empty.Empty, error) { dev, err := n.getDevice(ctx, &pb_lorawan.DeviceIdentifier{AppEui: in.AppEui, DevEui: in.DevEui}) if err != nil && errors.GetErrType(err) != errors.NotFound { return nil, err } if err := in.Validate(); err != nil { return nil, errors.Wrap(err, "Invalid Device") } claims, err := n.networkServer.Component.ValidateTTNAuthContext(ctx) if err != nil { return nil, err } if !claims.AppRight(in.AppId, rights.AppSettings) { return nil, errors.NewErrPermissionDenied(fmt.Sprintf("No access to Application %s", dev.AppID)) } if dev == nil { dev = new(device.Device) } else { dev.StartUpdate() } dev.AppID = in.AppId dev.AppEUI = *in.AppEui dev.DevID = in.DevId dev.DevEUI = *in.DevEui dev.FCntUp = in.FCntUp dev.FCntDown = in.FCntDown dev.Options = device.Options{ DisableFCntCheck: in.DisableFCntCheck, Uses32BitFCnt: in.Uses32BitFCnt, ActivationConstraints: in.ActivationConstraints, } if in.NwkSKey != nil && in.DevAddr != nil { dev.DevAddr = *in.DevAddr dev.NwkSKey = *in.NwkSKey } err = n.networkServer.devices.Set(dev) if err != nil { return nil, err } return &empty.Empty{}, nil }
func (h *handlerManager) GetStatus(ctx context.Context, in *pb.StatusRequest) (*pb.Status, error) { if h.handler.Identity.Id != "dev" { claims, err := h.handler.ValidateTTNAuthContext(ctx) if err != nil { return nil, errors.Wrap(err, "No access") } if !claims.ComponentAccess(h.handler.Identity.Id) { return nil, errors.NewErrPermissionDenied(fmt.Sprintf("Claims do not grant access to %s", h.handler.Identity.Id)) } } status := h.handler.GetStatus() if status == nil { return new(pb.Status), nil } return status, nil }
func (h *handlerManager) DeleteApplication(ctx context.Context, in *pb.ApplicationIdentifier) (*empty.Empty, error) { if err := in.Validate(); err != nil { return nil, errors.Wrap(err, "Invalid Application Identifier") } ctx, claims, err := h.validateTTNAuthAppContext(ctx, in.AppId) if err != nil { return nil, err } if !claims.AppRight(in.AppId, rights.AppSettings) { return nil, errors.NewErrPermissionDenied(`No "settings" rights to application`) } _, err = h.handler.applications.Get(in.AppId) if err != nil { return nil, err } // Get and delete all devices for this application devices, err := h.handler.devices.ListForApp(in.AppId) if err != nil { return nil, err } for _, dev := range devices { _, err = h.deviceManager.DeleteDevice(ctx, &pb_lorawan.DeviceIdentifier{AppEui: &dev.AppEUI, DevEui: &dev.DevEUI}) if err != nil { return nil, errors.Wrap(errors.FromGRPCError(err), "Broker did not delete device") } err = h.handler.devices.Delete(dev.AppID, dev.DevID) if err != nil { return nil, err } } // Delete the Application err = h.handler.applications.Delete(in.AppId) if err != nil { return nil, err } token, _ := api.TokenFromContext(ctx) err = h.handler.Discovery.RemoveAppID(in.AppId, token) if err != nil { h.handler.Ctx.WithField("AppID", in.AppId).WithError(errors.FromGRPCError(err)).Warn("Could not unregister Application from Discovery") } return &empty.Empty{}, nil }
// ValidateTTNAuthContext gets a token from the context and validates it func (c *Component) ValidateTTNAuthContext(ctx context.Context) (*claims.Claims, error) { token, err := api.TokenFromContext(ctx) if err != nil { return nil, err } if c.TokenKeyProvider == nil { return nil, errors.NewErrInternal("No token provider configured") } claims, err := claims.FromToken(c.TokenKeyProvider, token) if err != nil { return nil, errors.NewErrPermissionDenied(err.Error()) } return claims, nil }
func (h *handlerManager) RegisterApplication(ctx context.Context, in *pb.ApplicationIdentifier) (*empty.Empty, error) { if err := in.Validate(); err != nil { return nil, errors.Wrap(err, "Invalid Application Identifier") } ctx, claims, err := h.validateTTNAuthAppContext(ctx, in.AppId) if err != nil { return nil, err } if !claims.AppRight(in.AppId, rights.AppSettings) { return nil, errors.NewErrPermissionDenied(`No "settings" rights to application`) } app, err := h.handler.applications.Get(in.AppId) if err != nil && errors.GetErrType(err) != errors.NotFound { return nil, err } if app != nil { return nil, errors.NewErrAlreadyExists("Application") } err = h.handler.applications.Set(&application.Application{ AppID: in.AppId, }) if err != nil { return nil, err } token, _ := api.TokenFromContext(ctx) err = h.handler.Discovery.AddAppID(in.AppId, token) if err != nil { h.handler.Ctx.WithField("AppID", in.AppId).WithError(err).Warn("Could not register Application with Discovery") } _, err = h.handler.ttnBrokerManager.RegisterApplicationHandler(ctx, &pb_broker.ApplicationHandlerRegistration{ AppId: in.AppId, HandlerId: h.handler.Identity.Id, }) if err != nil { h.handler.Ctx.WithField("AppID", in.AppId).WithError(err).Warn("Could not register Application with Broker") } return &empty.Empty{}, nil }
func (n *networkServerManager) getDevice(ctx context.Context, in *pb_lorawan.DeviceIdentifier) (*device.Device, error) { if err := in.Validate(); err != nil { return nil, errors.Wrap(err, "Invalid Device Identifier") } claims, err := n.networkServer.Component.ValidateTTNAuthContext(ctx) if err != nil { return nil, err } if n.clientRate.Limit(claims.Subject) { return nil, grpc.Errorf(codes.ResourceExhausted, "Rate limit for client reached") } dev, err := n.networkServer.devices.Get(*in.AppEui, *in.DevEui) if err != nil { return nil, err } if !claims.AppRight(dev.AppID, rights.AppSettings) { return nil, errors.NewErrPermissionDenied(fmt.Sprintf("No access to Application %s", dev.AppID)) } return dev, nil }
func (b *brokerManager) RegisterApplicationHandler(ctx context.Context, in *pb.ApplicationHandlerRegistration) (*empty.Empty, error) { claims, err := b.broker.Component.ValidateTTNAuthContext(ctx) if err != nil { return nil, err } if err := in.Validate(); err != nil { return nil, errors.Wrap(err, "Invalid Application Handler Registration") } if !claims.AppRight(in.AppId, rights.AppSettings) { return nil, errors.NewErrPermissionDenied("No access to this application") } // Add Handler in local cache handler, err := b.broker.Discovery.Get("handler", in.HandlerId) if err != nil { return nil, errors.NewErrInternal("Could not get Handler Announcement") } handler.Metadata = append(handler.Metadata, &discovery.Metadata{Metadata: &discovery.Metadata_AppId{ AppId: in.AppId, }}) return &empty.Empty{}, nil }
func (h *handlerManager) GetDevicesForApplication(ctx context.Context, in *pb.ApplicationIdentifier) (*pb.DeviceList, error) { if err := in.Validate(); err != nil { return nil, errors.Wrap(err, "Invalid Application Identifier") } ctx, claims, err := h.validateTTNAuthAppContext(ctx, in.AppId) if err != nil { return nil, err } if !claims.AppRight(in.AppId, rights.Devices) { return nil, errors.NewErrPermissionDenied(fmt.Sprintf(`No "devices" rights to application "%s"`, in.AppId)) } if _, err := h.handler.applications.Get(in.AppId); err != nil { return nil, errors.Wrap(err, "Application not registered to this Handler") } devices, err := h.handler.devices.ListForApp(in.AppId) if err != nil { return nil, err } res := &pb.DeviceList{Devices: []*pb.Device{}} for _, dev := range devices { res.Devices = append(res.Devices, &pb.Device{ AppId: dev.AppID, DevId: dev.DevID, Device: &pb.Device_LorawanDevice{LorawanDevice: &pb_lorawan.Device{ AppId: dev.AppID, AppEui: &dev.AppEUI, DevId: dev.DevID, DevEui: &dev.DevEUI, DevAddr: &dev.DevAddr, NwkSKey: &dev.NwkSKey, AppSKey: &dev.AppSKey, AppKey: &dev.AppKey, }}, }) } return res, nil }
func (h *handlerManager) GetApplication(ctx context.Context, in *pb.ApplicationIdentifier) (*pb.Application, error) { if err := in.Validate(); err != nil { return nil, errors.NewErrInvalidArgument("Application Identifier", err.Error()) } ctx, claims, err := h.validateTTNAuthAppContext(ctx, in.AppId) if err != nil { return nil, err } if !claims.AppRight(in.AppId, rights.AppSettings) { return nil, errors.NewErrPermissionDenied(`No "settings" rights to application`) } app, err := h.handler.applications.Get(in.AppId) if err != nil { return nil, err } return &pb.Application{ AppId: app.AppID, Decoder: app.Decoder, Converter: app.Converter, Validator: app.Validator, Encoder: app.Encoder, }, nil }
func (h *handlerManager) GetDevice(ctx context.Context, in *pb.DeviceIdentifier) (*pb.Device, error) { if err := in.Validate(); err != nil { return nil, errors.Wrap(err, "Invalid Device Identifier") } ctx, claims, err := h.validateTTNAuthAppContext(ctx, in.AppId) if err != nil { return nil, err } if !claims.AppRight(in.AppId, rights.Devices) { return nil, errors.NewErrPermissionDenied(fmt.Sprintf(`No "devices" rights to application "%s"`, in.AppId)) } if _, err := h.handler.applications.Get(in.AppId); err != nil { return nil, errors.Wrap(err, "Application not registered to this Handler") } dev, err := h.handler.devices.Get(in.AppId, in.DevId) if err != nil { return nil, err } pbDev := &pb.Device{ AppId: dev.AppID, DevId: dev.DevID, Device: &pb.Device_LorawanDevice{LorawanDevice: &pb_lorawan.Device{ AppId: dev.AppID, AppEui: &dev.AppEUI, DevId: dev.DevID, DevEui: &dev.DevEUI, DevAddr: &dev.DevAddr, NwkSKey: &dev.NwkSKey, AppSKey: &dev.AppSKey, AppKey: &dev.AppKey, DisableFCntCheck: dev.Options.DisableFCntCheck, Uses32BitFCnt: dev.Options.Uses32BitFCnt, ActivationConstraints: dev.Options.ActivationConstraints, }}, } nsDev, err := h.deviceManager.GetDevice(ctx, &pb_lorawan.DeviceIdentifier{ AppEui: &dev.AppEUI, DevEui: &dev.DevEUI, }) if errors.GetErrType(errors.FromGRPCError(err)) == errors.NotFound { // Re-register the device in the Broker (NetworkServer) h.handler.Ctx.WithFields(log.Fields{ "AppID": dev.AppID, "DevID": dev.DevID, "AppEUI": dev.AppEUI, "DevEUI": dev.DevEUI, }).Warn("Re-registering missing device to Broker") nsDev = dev.GetLoRaWAN() _, err = h.deviceManager.SetDevice(ctx, nsDev) if err != nil { return nil, errors.Wrap(errors.FromGRPCError(err), "Could not re-register missing device to Broker") } } else if err != nil { return pbDev, errors.Wrap(errors.FromGRPCError(err), "Broker did not return device") } pbDev.GetLorawanDevice().FCntUp = nsDev.FCntUp pbDev.GetLorawanDevice().FCntDown = nsDev.FCntDown pbDev.GetLorawanDevice().LastSeen = nsDev.LastSeen return pbDev, nil }
func (h *handlerManager) SetDevice(ctx context.Context, in *pb.Device) (*empty.Empty, error) { if err := in.Validate(); err != nil { return nil, errors.Wrap(err, "Invalid Device") } ctx, claims, err := h.validateTTNAuthAppContext(ctx, in.AppId) if err != nil { return nil, err } if !claims.AppRight(in.AppId, rights.Devices) { return nil, errors.NewErrPermissionDenied(fmt.Sprintf(`No "devices" rights to application "%s"`, in.AppId)) } if _, err := h.handler.applications.Get(in.AppId); err != nil { return nil, errors.Wrap(err, "Application not registered to this Handler") } dev, err := h.handler.devices.Get(in.AppId, in.DevId) if err != nil && errors.GetErrType(err) != errors.NotFound { return nil, err } lorawan := in.GetLorawanDevice() if lorawan == nil { return nil, errors.NewErrInvalidArgument("Device", "No LoRaWAN Device") } if dev != nil { // When this is an update if dev.AppEUI != *lorawan.AppEui || dev.DevEUI != *lorawan.DevEui { // If the AppEUI or DevEUI is changed, we should remove the device from the NetworkServer and re-add it later _, err = h.deviceManager.DeleteDevice(ctx, &pb_lorawan.DeviceIdentifier{ AppEui: &dev.AppEUI, DevEui: &dev.DevEUI, }) if err != nil { return nil, errors.Wrap(errors.FromGRPCError(err), "Broker did not delete device") } } dev.StartUpdate() } else { // When this is a create existingDevices, err := h.handler.devices.ListForApp(in.AppId) if err != nil { return nil, err } for _, existingDevice := range existingDevices { if existingDevice.AppEUI == *lorawan.AppEui && existingDevice.DevEUI == *lorawan.DevEui { return nil, errors.NewErrAlreadyExists("Device with AppEUI and DevEUI") } } dev = new(device.Device) } dev.AppID = in.AppId dev.AppEUI = *lorawan.AppEui dev.DevID = in.DevId dev.DevEUI = *lorawan.DevEui dev.Options = device.Options{ DisableFCntCheck: lorawan.DisableFCntCheck, Uses32BitFCnt: lorawan.Uses32BitFCnt, ActivationConstraints: lorawan.ActivationConstraints, } if dev.Options.ActivationConstraints == "" { dev.Options.ActivationConstraints = "local" } if lorawan.DevAddr != nil { dev.DevAddr = *lorawan.DevAddr } if lorawan.NwkSKey != nil { dev.NwkSKey = *lorawan.NwkSKey } if lorawan.AppSKey != nil { dev.AppSKey = *lorawan.AppSKey } if lorawan.AppKey != nil { if dev.AppKey != *lorawan.AppKey { // When the AppKey of an existing device is changed dev.UsedAppNonces = []device.AppNonce{} dev.UsedDevNonces = []device.DevNonce{} } dev.AppKey = *lorawan.AppKey } // Update the device in the Broker (NetworkServer) nsUpdated := dev.GetLoRaWAN() nsUpdated.FCntUp = lorawan.FCntUp nsUpdated.FCntDown = lorawan.FCntDown _, err = h.deviceManager.SetDevice(ctx, nsUpdated) if err != nil { return nil, errors.Wrap(errors.FromGRPCError(err), "Broker did not set device") } err = h.handler.devices.Set(dev) if err != nil { return nil, err } return &empty.Empty{}, nil }
func errPermissionDeniedf(format string, args ...interface{}) error { return errors.NewErrPermissionDenied(fmt.Sprintf("Discovery:"+format, args...)) }