mirror of
https://github.com/absmach/magistrala.git
synced 2026-06-23 04:10:28 +00:00
Add HTTP auth check (#128)
* Add HTTP auth check Signed-off-by: Drasko DRASKOVIC <drasko.draskovic@gmail.com> * Add HTTP auth via Manager Client Signed-off-by: Drasko DRASKOVIC <drasko.draskovic@gmail.com> * Change the way manager client is injected Instead of relying on modifying service structure, manager client is injected through handler factory method, and store as a variable in that module. Signed-off-by: Dejan Mijic <dejan@mainflux.com> * Update dockerignore Signed-off-by: Dejan Mijic <dejan@mainflux.com>
This commit is contained in:
committed by
Dejan Mijić
parent
d413508b25
commit
4f467dcdde
+1
-2
@@ -1,9 +1,8 @@
|
||||
.git/
|
||||
.github/
|
||||
bin/
|
||||
docker/
|
||||
glide.lock
|
||||
glide.yaml
|
||||
LICENSE
|
||||
MAINTAINERS
|
||||
README.md
|
||||
swagger.yml
|
||||
|
||||
@@ -74,3 +74,4 @@ services:
|
||||
- mainflux-nats:nats
|
||||
environment:
|
||||
- HTTP_ADAPTER_NATS_URL=nats://nats:4222
|
||||
- HTTP_ADAPTER_MANAGER_URL=http://manager:8180
|
||||
|
||||
+14
-8
@@ -12,25 +12,30 @@ import (
|
||||
adapter "github.com/mainflux/mainflux/http"
|
||||
"github.com/mainflux/mainflux/http/api"
|
||||
"github.com/mainflux/mainflux/http/nats"
|
||||
manager "github.com/mainflux/mainflux/manager/client"
|
||||
broker "github.com/nats-io/go-nats"
|
||||
stdprometheus "github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
const (
|
||||
port int = 7070
|
||||
defNatsURL string = broker.DefaultURL
|
||||
envNatsURL string = "HTTP_ADAPTER_NATS_URL"
|
||||
port int = 7070
|
||||
defNatsURL string = broker.DefaultURL
|
||||
envNatsURL string = "HTTP_ADAPTER_NATS_URL"
|
||||
defManagerURL string = "http://localhost:8180"
|
||||
envManagerURL string = "HTTP_ADAPTER_MANAGER_URL"
|
||||
)
|
||||
|
||||
type config struct {
|
||||
Port int
|
||||
NatsURL string
|
||||
Port int
|
||||
NatsURL string
|
||||
ManagerURL string
|
||||
}
|
||||
|
||||
func main() {
|
||||
cfg := config{
|
||||
Port: port,
|
||||
NatsURL: getenv(envNatsURL, defNatsURL),
|
||||
Port: port,
|
||||
NatsURL: getenv(envNatsURL, defNatsURL),
|
||||
ManagerURL: getenv(envManagerURL, defManagerURL),
|
||||
}
|
||||
|
||||
logger := log.NewJSONLogger(log.NewSyncWriter(os.Stdout))
|
||||
@@ -69,7 +74,8 @@ func main() {
|
||||
|
||||
go func() {
|
||||
p := fmt.Sprintf(":%d", cfg.Port)
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler(svc))
|
||||
mc := manager.NewClient(cfg.ManagerURL)
|
||||
errs <- http.ListenAndServe(p, api.MakeHandler(svc, mc))
|
||||
}()
|
||||
|
||||
go func() {
|
||||
|
||||
+18
-5
@@ -6,11 +6,13 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
kithttp "github.com/go-kit/kit/transport/http"
|
||||
"github.com/go-zoo/bone"
|
||||
"github.com/mainflux/mainflux"
|
||||
adapter "github.com/mainflux/mainflux/http"
|
||||
manager "github.com/mainflux/mainflux/manager/client"
|
||||
"github.com/mainflux/mainflux/writer"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
)
|
||||
@@ -24,10 +26,13 @@ var (
|
||||
errMalformedData error = errors.New("malformed SenML data")
|
||||
errUnknownType error = errors.New("unknown content type")
|
||||
errUnauthorizedAccess error = errors.New("missing or invalid credentials provided")
|
||||
auth manager.ManagerClient
|
||||
)
|
||||
|
||||
// MakeHandler returns a HTTP handler for API endpoints.
|
||||
func MakeHandler(svc adapter.Service) http.Handler {
|
||||
func MakeHandler(svc adapter.Service, mc manager.ManagerClient) http.Handler {
|
||||
auth = mc
|
||||
|
||||
opts := []kithttp.ServerOption{
|
||||
kithttp.ServerErrorEncoder(encodeError),
|
||||
}
|
||||
@@ -76,14 +81,22 @@ func decodeRequest(_ context.Context, r *http.Request) (interface{}, error) {
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
// TODO: contact an auth provider
|
||||
func authorize(r *http.Request) (string, error) {
|
||||
var apiKey string
|
||||
if apiKey = r.Header.Get("Authorization"); apiKey == "" {
|
||||
apiKey := r.Header.Get("Authorization")
|
||||
|
||||
if apiKey == "" {
|
||||
return "", errUnauthorizedAccess
|
||||
}
|
||||
|
||||
return apiKey, nil
|
||||
// Path is `/channels/:id/messages`, we need chanID.
|
||||
c := strings.Split(r.URL.Path, "/")[2]
|
||||
|
||||
id, err := auth.CanAccess(c, apiKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func checkContentType(r *http.Request) (string, error) {
|
||||
|
||||
@@ -21,13 +21,13 @@ const (
|
||||
// ErrServiceUnreachable indicates that the service instance is not available.
|
||||
var ErrServiceUnreachable = errors.New("manager service unavailable")
|
||||
|
||||
type managerClient struct {
|
||||
type ManagerClient struct {
|
||||
url string
|
||||
cb *gobreaker.CircuitBreaker
|
||||
}
|
||||
|
||||
// NewClient instantiates the manager service client given its base URL.
|
||||
func NewClient(url string) managerClient {
|
||||
func NewClient(url string) ManagerClient {
|
||||
st := gobreaker.Settings{
|
||||
Name: "Manager",
|
||||
ReadyToTrip: func(counts gobreaker.Counts) bool {
|
||||
@@ -36,7 +36,7 @@ func NewClient(url string) managerClient {
|
||||
},
|
||||
}
|
||||
|
||||
mc := managerClient{
|
||||
mc := ManagerClient{
|
||||
url: url,
|
||||
cb: gobreaker.NewCircuitBreaker(st),
|
||||
}
|
||||
@@ -44,17 +44,17 @@ func NewClient(url string) managerClient {
|
||||
return mc
|
||||
}
|
||||
|
||||
func (mc managerClient) VerifyToken(token string) (string, error) {
|
||||
func (mc ManagerClient) VerifyToken(token string) (string, error) {
|
||||
url := fmt.Sprintf("%s/access-grant", mc.url)
|
||||
return mc.makeRequest(url, token)
|
||||
}
|
||||
|
||||
func (mc managerClient) CanAccess(channel, token string) (string, error) {
|
||||
func (mc ManagerClient) CanAccess(channel, token string) (string, error) {
|
||||
url := fmt.Sprintf("%s/channels/%s/access-grant", mc.url, channel)
|
||||
return mc.makeRequest(url, token)
|
||||
}
|
||||
|
||||
func (mc managerClient) makeRequest(url, token string) (string, error) {
|
||||
func (mc ManagerClient) makeRequest(url, token string) (string, error) {
|
||||
response, err := mc.cb.Execute(func() (interface{}, error) {
|
||||
hc := &http.Client{
|
||||
Timeout: timeout,
|
||||
|
||||
Reference in New Issue
Block a user