2018-08-26 13:15:48 +02:00
|
|
|
//
|
|
|
|
// Copyright (c) 2018
|
|
|
|
// Mainflux
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
//
|
|
|
|
|
2018-05-15 17:13:09 +02:00
|
|
|
package things
|
2017-09-23 01:03:27 +02:00
|
|
|
|
2018-05-11 01:00:10 +02:00
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"errors"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/mainflux/mainflux"
|
|
|
|
)
|
2017-09-23 01:03:27 +02:00
|
|
|
|
|
|
|
var (
|
2017-10-01 01:07:37 +02:00
|
|
|
// ErrMalformedEntity indicates malformed entity specification (e.g.
|
|
|
|
// invalid username or password).
|
2018-05-10 23:53:25 +02:00
|
|
|
ErrMalformedEntity = errors.New("malformed entity specification")
|
2017-09-23 01:03:27 +02:00
|
|
|
|
|
|
|
// ErrUnauthorizedAccess indicates missing or invalid credentials provided
|
|
|
|
// when accessing a protected resource.
|
2018-05-10 23:53:25 +02:00
|
|
|
ErrUnauthorizedAccess = errors.New("missing or invalid credentials provided")
|
2017-09-23 01:03:27 +02:00
|
|
|
|
|
|
|
// ErrNotFound indicates a non-existent entity request.
|
2018-05-10 23:53:25 +02:00
|
|
|
ErrNotFound = errors.New("non-existent entity")
|
2019-04-25 14:37:51 +02:00
|
|
|
|
|
|
|
// ErrConflict indicates that entity already exists.
|
|
|
|
ErrConflict = errors.New("entity already exists")
|
2017-09-23 01:03:27 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
// Service specifies an API that must be fullfiled by the domain service
|
|
|
|
// implementation, and all of its decorators (e.g. logging & metrics).
|
|
|
|
type Service interface {
|
2018-05-15 17:13:09 +02:00
|
|
|
// AddThing adds new thing to the user identified by the provided key.
|
2018-05-16 14:28:41 +02:00
|
|
|
AddThing(string, Thing) (Thing, error)
|
2017-09-23 01:03:27 +02:00
|
|
|
|
2018-05-15 17:13:09 +02:00
|
|
|
// UpdateThing updates the thing identified by the provided ID, that
|
2017-09-23 01:03:27 +02:00
|
|
|
// belongs to the user identified by the provided key.
|
2018-05-15 17:13:09 +02:00
|
|
|
UpdateThing(string, Thing) error
|
2017-09-23 01:03:27 +02:00
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
// UpdateKey updates key value of the existing thing. A non-nil error is
|
|
|
|
// returned to indicate operation failure.
|
|
|
|
UpdateKey(string, string, string) error
|
|
|
|
|
2018-05-15 17:13:09 +02:00
|
|
|
// ViewThing retrieves data about the thing identified with the provided
|
2017-09-23 01:03:27 +02:00
|
|
|
// ID, that belongs to the user identified by the provided key.
|
2018-12-05 13:09:25 +01:00
|
|
|
ViewThing(string, string) (Thing, error)
|
2017-09-23 01:03:27 +02:00
|
|
|
|
2018-05-15 17:13:09 +02:00
|
|
|
// ListThings retrieves data about subset of things that belongs to the
|
2018-04-18 22:36:24 +02:00
|
|
|
// user identified by the provided key.
|
2019-05-30 15:33:49 +02:00
|
|
|
ListThings(string, uint64, uint64, string) (ThingsPage, error)
|
2019-01-08 11:53:24 +01:00
|
|
|
|
|
|
|
// ListThingsByChannel retrieves data about subset of things that are
|
|
|
|
// connected to specified channel and belong to the user identified by
|
|
|
|
// the provided key.
|
|
|
|
ListThingsByChannel(string, string, uint64, uint64) (ThingsPage, error)
|
2017-09-23 01:03:27 +02:00
|
|
|
|
2018-05-15 17:13:09 +02:00
|
|
|
// RemoveThing removes the thing identified with the provided ID, that
|
2017-09-23 01:03:27 +02:00
|
|
|
// belongs to the user identified by the provided key.
|
2018-12-05 13:09:25 +01:00
|
|
|
RemoveThing(string, string) error
|
2017-09-23 01:03:27 +02:00
|
|
|
|
|
|
|
// CreateChannel adds new channel to the user identified by the provided key.
|
2018-05-16 14:28:41 +02:00
|
|
|
CreateChannel(string, Channel) (Channel, error)
|
2017-09-23 01:03:27 +02:00
|
|
|
|
|
|
|
// UpdateChannel updates the channel identified by the provided ID, that
|
|
|
|
// belongs to the user identified by the provided key.
|
|
|
|
UpdateChannel(string, Channel) error
|
|
|
|
|
|
|
|
// ViewChannel retrieves data about the channel identified by the provided
|
|
|
|
// ID, that belongs to the user identified by the provided key.
|
2018-12-05 13:09:25 +01:00
|
|
|
ViewChannel(string, string) (Channel, error)
|
2017-09-23 01:03:27 +02:00
|
|
|
|
2018-04-18 22:36:24 +02:00
|
|
|
// ListChannels retrieves data about subset of channels that belongs to the
|
|
|
|
// user identified by the provided key.
|
2019-01-08 11:53:24 +01:00
|
|
|
ListChannels(string, uint64, uint64) (ChannelsPage, error)
|
|
|
|
|
|
|
|
// ListChannelsByThing retrieves data about subset of channels that have
|
|
|
|
// specified thing connected to them and belong to the user identified by
|
|
|
|
// the provided key.
|
|
|
|
ListChannelsByThing(string, string, uint64, uint64) (ChannelsPage, error)
|
2017-09-23 01:03:27 +02:00
|
|
|
|
2018-05-15 17:13:09 +02:00
|
|
|
// RemoveChannel removes the thing identified by the provided ID, that
|
2017-09-23 01:03:27 +02:00
|
|
|
// belongs to the user identified by the provided key.
|
2018-12-05 13:09:25 +01:00
|
|
|
RemoveChannel(string, string) error
|
2017-09-23 01:03:27 +02:00
|
|
|
|
2018-05-15 17:13:09 +02:00
|
|
|
// Connect adds thing to the channel's list of connected things.
|
2018-12-05 13:09:25 +01:00
|
|
|
Connect(string, string, string) error
|
2018-03-11 18:06:01 +01:00
|
|
|
|
2018-05-15 17:13:09 +02:00
|
|
|
// Disconnect removes thing from the channel's list of connected
|
|
|
|
// things.
|
2018-12-05 13:09:25 +01:00
|
|
|
Disconnect(string, string, string) error
|
2018-03-11 18:06:01 +01:00
|
|
|
|
2017-12-29 10:40:44 +01:00
|
|
|
// CanAccess determines whether the channel can be accessed using the
|
2018-05-16 14:28:41 +02:00
|
|
|
// provided key and returns thing's id if access is allowed.
|
2018-12-05 13:09:25 +01:00
|
|
|
CanAccess(string, string) (string, error)
|
2018-05-17 20:17:02 +02:00
|
|
|
|
|
|
|
// Identify returns thing ID for given thing key.
|
2018-12-05 13:09:25 +01:00
|
|
|
Identify(string) (string, error)
|
2017-09-23 01:03:27 +02:00
|
|
|
}
|
2018-05-11 01:00:10 +02:00
|
|
|
|
2019-01-08 11:53:24 +01:00
|
|
|
// PageMetadata contains page metadata that helps navigation.
|
|
|
|
type PageMetadata struct {
|
|
|
|
Total uint64
|
|
|
|
Offset uint64
|
|
|
|
Limit uint64
|
|
|
|
}
|
|
|
|
|
2018-05-15 17:13:09 +02:00
|
|
|
var _ Service = (*thingsService)(nil)
|
2018-05-11 01:00:10 +02:00
|
|
|
|
2018-05-15 17:13:09 +02:00
|
|
|
type thingsService struct {
|
2018-09-04 22:19:43 +02:00
|
|
|
users mainflux.UsersServiceClient
|
|
|
|
things ThingRepository
|
|
|
|
channels ChannelRepository
|
|
|
|
channelCache ChannelCache
|
|
|
|
thingCache ThingCache
|
|
|
|
idp IdentityProvider
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
|
|
|
|
2018-05-15 17:13:09 +02:00
|
|
|
// New instantiates the things service implementation.
|
2018-09-04 22:19:43 +02:00
|
|
|
func New(users mainflux.UsersServiceClient, things ThingRepository, channels ChannelRepository, ccache ChannelCache, tcache ThingCache, idp IdentityProvider) Service {
|
2018-05-15 17:13:09 +02:00
|
|
|
return &thingsService{
|
2018-09-04 22:19:43 +02:00
|
|
|
users: users,
|
|
|
|
things: things,
|
|
|
|
channels: channels,
|
|
|
|
channelCache: ccache,
|
|
|
|
thingCache: tcache,
|
|
|
|
idp: idp,
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
func (ts *thingsService) AddThing(token string, thing Thing) (Thing, error) {
|
2018-10-24 11:21:03 +02:00
|
|
|
if err := thing.Validate(); err != nil {
|
|
|
|
return Thing{}, ErrMalformedEntity
|
|
|
|
}
|
|
|
|
|
2018-05-11 01:00:10 +02:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
res, err := ts.users.Identify(ctx, &mainflux.Token{Value: token})
|
2018-05-11 01:00:10 +02:00
|
|
|
if err != nil {
|
2018-05-16 14:28:41 +02:00
|
|
|
return Thing{}, ErrUnauthorizedAccess
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
|
|
|
|
2019-05-16 13:35:13 +02:00
|
|
|
thing.ID, err = ts.idp.ID()
|
|
|
|
if err != nil {
|
|
|
|
return Thing{}, err
|
|
|
|
}
|
|
|
|
|
2018-05-15 17:13:09 +02:00
|
|
|
thing.Owner = res.GetValue()
|
2019-04-25 14:37:51 +02:00
|
|
|
|
|
|
|
if thing.Key == "" {
|
2019-05-16 13:35:13 +02:00
|
|
|
thing.Key, err = ts.idp.ID()
|
|
|
|
if err != nil {
|
|
|
|
return Thing{}, err
|
|
|
|
}
|
2019-04-25 14:37:51 +02:00
|
|
|
}
|
2018-05-16 14:28:41 +02:00
|
|
|
|
2018-05-21 12:51:46 +02:00
|
|
|
id, err := ts.things.Save(thing)
|
|
|
|
if err != nil {
|
2018-05-16 14:28:41 +02:00
|
|
|
return Thing{}, err
|
|
|
|
}
|
2018-05-11 01:00:10 +02:00
|
|
|
|
2018-05-21 12:51:46 +02:00
|
|
|
thing.ID = id
|
2018-05-16 14:28:41 +02:00
|
|
|
return thing, nil
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
func (ts *thingsService) UpdateThing(token string, thing Thing) error {
|
2018-10-24 11:21:03 +02:00
|
|
|
if err := thing.Validate(); err != nil {
|
|
|
|
return ErrMalformedEntity
|
|
|
|
}
|
|
|
|
|
2018-05-11 01:00:10 +02:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
res, err := ts.users.Identify(ctx, &mainflux.Token{Value: token})
|
2018-05-11 01:00:10 +02:00
|
|
|
if err != nil {
|
|
|
|
return ErrUnauthorizedAccess
|
|
|
|
}
|
|
|
|
|
2018-05-15 17:13:09 +02:00
|
|
|
thing.Owner = res.GetValue()
|
2018-05-11 01:00:10 +02:00
|
|
|
|
2018-05-16 14:28:41 +02:00
|
|
|
return ts.things.Update(thing)
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
func (ts *thingsService) UpdateKey(token, id, key string) error {
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
res, err := ts.users.Identify(ctx, &mainflux.Token{Value: token})
|
|
|
|
if err != nil {
|
|
|
|
return ErrUnauthorizedAccess
|
|
|
|
}
|
|
|
|
|
|
|
|
owner := res.GetValue()
|
|
|
|
|
|
|
|
return ts.things.UpdateKey(owner, id, key)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ts *thingsService) ViewThing(token, id string) (Thing, error) {
|
2018-05-11 01:00:10 +02:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
res, err := ts.users.Identify(ctx, &mainflux.Token{Value: token})
|
2018-05-11 01:00:10 +02:00
|
|
|
if err != nil {
|
2018-05-15 17:13:09 +02:00
|
|
|
return Thing{}, ErrUnauthorizedAccess
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
|
|
|
|
2018-05-17 20:17:02 +02:00
|
|
|
return ts.things.RetrieveByID(res.GetValue(), id)
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
|
|
|
|
2019-05-30 15:33:49 +02:00
|
|
|
func (ts *thingsService) ListThings(token string, offset, limit uint64, name string) (ThingsPage, error) {
|
2018-05-11 01:00:10 +02:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
res, err := ts.users.Identify(ctx, &mainflux.Token{Value: token})
|
2018-05-11 01:00:10 +02:00
|
|
|
if err != nil {
|
2019-01-08 11:53:24 +01:00
|
|
|
return ThingsPage{}, ErrUnauthorizedAccess
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
|
|
|
|
2019-05-30 15:33:49 +02:00
|
|
|
return ts.things.RetrieveAll(res.GetValue(), offset, limit, name)
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
func (ts *thingsService) ListThingsByChannel(token, channel string, offset, limit uint64) (ThingsPage, error) {
|
2019-01-08 11:53:24 +01:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
res, err := ts.users.Identify(ctx, &mainflux.Token{Value: token})
|
2019-01-08 11:53:24 +01:00
|
|
|
if err != nil {
|
|
|
|
return ThingsPage{}, ErrUnauthorizedAccess
|
|
|
|
}
|
|
|
|
|
2019-05-10 18:55:13 +02:00
|
|
|
return ts.things.RetrieveByChannel(res.GetValue(), channel, offset, limit)
|
2019-01-08 11:53:24 +01:00
|
|
|
}
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
func (ts *thingsService) RemoveThing(token, id string) error {
|
2018-05-11 01:00:10 +02:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
res, err := ts.users.Identify(ctx, &mainflux.Token{Value: token})
|
2018-05-11 01:00:10 +02:00
|
|
|
if err != nil {
|
|
|
|
return ErrUnauthorizedAccess
|
|
|
|
}
|
|
|
|
|
2018-09-04 22:19:43 +02:00
|
|
|
ts.thingCache.Remove(id)
|
2018-05-16 14:28:41 +02:00
|
|
|
return ts.things.Remove(res.GetValue(), id)
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
func (ts *thingsService) CreateChannel(token string, channel Channel) (Channel, error) {
|
2018-05-11 01:00:10 +02:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
res, err := ts.users.Identify(ctx, &mainflux.Token{Value: token})
|
2018-05-11 01:00:10 +02:00
|
|
|
if err != nil {
|
2018-05-16 14:28:41 +02:00
|
|
|
return Channel{}, ErrUnauthorizedAccess
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
|
|
|
|
2019-05-16 13:35:13 +02:00
|
|
|
channel.ID, err = ts.idp.ID()
|
|
|
|
if err != nil {
|
|
|
|
return Channel{}, err
|
|
|
|
}
|
|
|
|
|
2018-05-11 01:00:10 +02:00
|
|
|
channel.Owner = res.GetValue()
|
2018-05-16 14:28:41 +02:00
|
|
|
|
2018-05-21 12:51:46 +02:00
|
|
|
id, err := ts.channels.Save(channel)
|
|
|
|
if err != nil {
|
2018-05-16 14:28:41 +02:00
|
|
|
return Channel{}, err
|
|
|
|
}
|
|
|
|
|
2018-05-21 12:51:46 +02:00
|
|
|
channel.ID = id
|
2018-05-16 14:28:41 +02:00
|
|
|
return channel, nil
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
func (ts *thingsService) UpdateChannel(token string, channel Channel) error {
|
2018-05-11 01:00:10 +02:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
res, err := ts.users.Identify(ctx, &mainflux.Token{Value: token})
|
2018-05-11 01:00:10 +02:00
|
|
|
if err != nil {
|
|
|
|
return ErrUnauthorizedAccess
|
|
|
|
}
|
|
|
|
|
|
|
|
channel.Owner = res.GetValue()
|
2018-05-16 14:28:41 +02:00
|
|
|
return ts.channels.Update(channel)
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
func (ts *thingsService) ViewChannel(token, id string) (Channel, error) {
|
2018-05-11 01:00:10 +02:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
res, err := ts.users.Identify(ctx, &mainflux.Token{Value: token})
|
2018-05-11 01:00:10 +02:00
|
|
|
if err != nil {
|
|
|
|
return Channel{}, ErrUnauthorizedAccess
|
|
|
|
}
|
|
|
|
|
2018-05-17 20:17:02 +02:00
|
|
|
return ts.channels.RetrieveByID(res.GetValue(), id)
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
func (ts *thingsService) ListChannels(token string, offset, limit uint64) (ChannelsPage, error) {
|
2018-05-11 01:00:10 +02:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
res, err := ts.users.Identify(ctx, &mainflux.Token{Value: token})
|
2018-05-11 01:00:10 +02:00
|
|
|
if err != nil {
|
2019-01-08 11:53:24 +01:00
|
|
|
return ChannelsPage{}, ErrUnauthorizedAccess
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
|
|
|
|
2019-05-10 18:55:13 +02:00
|
|
|
return ts.channels.RetrieveAll(res.GetValue(), offset, limit)
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
func (ts *thingsService) ListChannelsByThing(token, thing string, offset, limit uint64) (ChannelsPage, error) {
|
2019-01-08 11:53:24 +01:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
res, err := ts.users.Identify(ctx, &mainflux.Token{Value: token})
|
2019-01-08 11:53:24 +01:00
|
|
|
if err != nil {
|
|
|
|
return ChannelsPage{}, ErrUnauthorizedAccess
|
|
|
|
}
|
|
|
|
|
2019-05-10 18:55:13 +02:00
|
|
|
return ts.channels.RetrieveByThing(res.GetValue(), thing, offset, limit)
|
2019-01-08 11:53:24 +01:00
|
|
|
}
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
func (ts *thingsService) RemoveChannel(token, id string) error {
|
2018-05-11 01:00:10 +02:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
res, err := ts.users.Identify(ctx, &mainflux.Token{Value: token})
|
2018-05-11 01:00:10 +02:00
|
|
|
if err != nil {
|
|
|
|
return ErrUnauthorizedAccess
|
|
|
|
}
|
|
|
|
|
2018-09-04 22:19:43 +02:00
|
|
|
ts.channelCache.Remove(id)
|
2018-05-16 14:28:41 +02:00
|
|
|
return ts.channels.Remove(res.GetValue(), id)
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
func (ts *thingsService) Connect(token, chanID, thingID string) error {
|
2018-05-11 01:00:10 +02:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
res, err := ts.users.Identify(ctx, &mainflux.Token{Value: token})
|
2018-05-11 01:00:10 +02:00
|
|
|
if err != nil {
|
|
|
|
return ErrUnauthorizedAccess
|
|
|
|
}
|
|
|
|
|
2018-05-16 14:28:41 +02:00
|
|
|
return ts.channels.Connect(res.GetValue(), chanID, thingID)
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
func (ts *thingsService) Disconnect(token, chanID, thingID string) error {
|
2018-05-11 01:00:10 +02:00
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
2019-04-25 14:37:51 +02:00
|
|
|
res, err := ts.users.Identify(ctx, &mainflux.Token{Value: token})
|
2018-05-11 01:00:10 +02:00
|
|
|
if err != nil {
|
|
|
|
return ErrUnauthorizedAccess
|
|
|
|
}
|
|
|
|
|
2018-09-04 22:19:43 +02:00
|
|
|
ts.channelCache.Disconnect(chanID, thingID)
|
2018-05-16 14:28:41 +02:00
|
|
|
return ts.channels.Disconnect(res.GetValue(), chanID, thingID)
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
|
|
|
|
2018-12-05 13:09:25 +01:00
|
|
|
func (ts *thingsService) CanAccess(chanID, key string) (string, error) {
|
2018-09-04 22:19:43 +02:00
|
|
|
thingID, err := ts.hasThing(chanID, key)
|
|
|
|
if err == nil {
|
|
|
|
return thingID, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
thingID, err = ts.channels.HasThing(chanID, key)
|
2018-05-11 01:00:10 +02:00
|
|
|
if err != nil {
|
2018-12-05 13:09:25 +01:00
|
|
|
return "", ErrUnauthorizedAccess
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
|
|
|
|
2018-09-04 22:19:43 +02:00
|
|
|
ts.thingCache.Save(key, thingID)
|
|
|
|
ts.channelCache.Connect(chanID, thingID)
|
2018-05-16 14:28:41 +02:00
|
|
|
return thingID, nil
|
2018-05-11 01:00:10 +02:00
|
|
|
}
|
2018-05-17 20:17:02 +02:00
|
|
|
|
2018-12-05 13:09:25 +01:00
|
|
|
func (ts *thingsService) Identify(key string) (string, error) {
|
2018-09-04 22:19:43 +02:00
|
|
|
id, err := ts.thingCache.ID(key)
|
|
|
|
if err == nil {
|
|
|
|
return id, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
id, err = ts.things.RetrieveByKey(key)
|
2018-05-17 20:17:02 +02:00
|
|
|
if err != nil {
|
2018-12-05 13:09:25 +01:00
|
|
|
return "", ErrUnauthorizedAccess
|
2018-05-17 20:17:02 +02:00
|
|
|
}
|
|
|
|
|
2018-09-04 22:19:43 +02:00
|
|
|
ts.thingCache.Save(key, id)
|
2018-05-17 20:17:02 +02:00
|
|
|
return id, nil
|
|
|
|
}
|
2018-09-04 22:19:43 +02:00
|
|
|
|
2018-12-05 13:09:25 +01:00
|
|
|
func (ts *thingsService) hasThing(chanID, key string) (string, error) {
|
2018-09-04 22:19:43 +02:00
|
|
|
thingID, err := ts.thingCache.ID(key)
|
|
|
|
if err != nil {
|
2018-12-05 13:09:25 +01:00
|
|
|
return "", err
|
2018-09-04 22:19:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if connected := ts.channelCache.HasThing(chanID, thingID); !connected {
|
2018-12-05 13:09:25 +01:00
|
|
|
return "", ErrUnauthorizedAccess
|
2018-09-04 22:19:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return thingID, nil
|
|
|
|
}
|