MF-1008 - Make token duration configurable (#1550)

* Make token duration configurable

Signed-off-by: 0x6f736f646f <blackd0t@protonmail.com>

* Change env variable name

Signed-off-by: 0x6f736f646f <blackd0t@protonmail.com>

* Add MF_AUTH_LOGIN_TOKEN_DURATION in environment variable

Signed-off-by: 0x6f736f646f <blackd0t@protonmail.com>

* Change tests

Signed-off-by: 0x6f736f646f <blackd0t@protonmail.com>

* Document MF_AUTH_LOGIN_TOKEN_DURATION

Signed-off-by: 0x6f736f646f <blackd0t@protonmail.com>

* Change default login duration

Signed-off-by: 0x6f736f646f <blackd0t@protonmail.com>

* Change declaration of loginduration

Signed-off-by: 0x6f736f646f <blackd0t@protonmail.com>

* Add space after port

Signed-off-by: 0x6f736f646f <blackd0t@protonmail.com>

* Change time to hours

Signed-off-by: 0x6f736f646f <blackd0t@protonmail.com>

* Remove constant login duration

Signed-off-by: 0x6f736f646f <blackd0t@protonmail.com>

* Keep back recovery duration

Signed-off-by: 0x6f736f646f <blackd0t@protonmail.com>

* Change docs for login token duration

Signed-off-by: 0x6f736f646f <blackd0t@protonmail.com>

* Change login description

Signed-off-by: 0x6f736f646f <blackd0t@protonmail.com>

* Remove blank lines

Signed-off-by: 0x6f736f646f <blackd0t@protonmail.com>
This commit is contained in:
b1ackd0t 2022-01-25 21:42:41 +03:00 committed by GitHub
parent 42dd813521
commit 2abf9da27e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 77 additions and 59 deletions

View File

@ -55,24 +55,25 @@ The service is configured using the environment variables presented in the
following table. Note that any unset variables will be replaced with their
default values.
| Variable | Description | Default |
|---------------------------|--------------------------------------------------------------------------|---------------|
| MF_AUTH_LOG_LEVEL | Service level (debug, info, warn, error) | error |
| MF_AUTH_DB_HOST | Database host address | localhost |
| MF_AUTH_DB_PORT | Database host port | 5432 |
| MF_AUTH_DB_USER | Database user | mainflux |
| MF_AUTH_DB_PASSWORD | Database password | mainflux |
| MF_AUTH_DB | Name of the database used by the service | auth |
| MF_AUTH_DB_SSL_MODE | Database connection SSL mode (disable, require, verify-ca, verify-full) | disable |
| MF_AUTH_DB_SSL_CERT | Path to the PEM encoded certificate file | |
| MF_AUTH_DB_SSL_KEY | Path to the PEM encoded key file | |
| MF_AUTH_DB_SSL_ROOT_CERT | Path to the PEM encoded root certificate file | |
| MF_AUTH_HTTP_PORT | Auth service HTTP port | 8180 |
| MF_AUTH_GRPC_PORT | Auth service gRPC port | 8181 |
| MF_AUTH_SERVER_CERT | Path to server certificate in pem format | |
| MF_AUTH_SERVER_KEY | Path to server key in pem format | |
| MF_AUTH_SECRET | String used for signing tokens | auth |
| MF_JAEGER_URL | Jaeger server URL | localhost:6831|
| Variable | Description | Default |
|-------------------------------|--------------------------------------------------------------------------|----------------|
| MF_AUTH_LOG_LEVEL | Service level (debug, info, warn, error) | error |
| MF_AUTH_DB_HOST | Database host address | localhost |
| MF_AUTH_DB_PORT | Database host port | 5432 |
| MF_AUTH_DB_USER | Database user | mainflux |
| MF_AUTH_DB_PASSWORD | Database password | mainflux |
| MF_AUTH_DB | Name of the database used by the service | auth |
| MF_AUTH_DB_SSL_MODE | Database connection SSL mode (disable, require, verify-ca, verify-full) | disable |
| MF_AUTH_DB_SSL_CERT | Path to the PEM encoded certificate file | |
| MF_AUTH_DB_SSL_KEY | Path to the PEM encoded key file | |
| MF_AUTH_DB_SSL_ROOT_CERT | Path to the PEM encoded root certificate file | |
| MF_AUTH_HTTP_PORT | Auth service HTTP port | 8180 |
| MF_AUTH_GRPC_PORT | Auth service gRPC port | 8181 |
| MF_AUTH_SERVER_CERT | Path to server certificate in pem format | |
| MF_AUTH_SERVER_KEY | Path to server key in pem format | |
| MF_AUTH_SECRET | String used for signing tokens | auth |
| MF_AUTH_LOGIN_TOKEN_DURATION | The login token expiration period | 10h |
| MF_JAEGER_URL | Jaeger server URL | localhost:6831 |
## Deployment
@ -95,7 +96,7 @@ make auth
make install
# set the environment variables and run the service
MF_AUTH_LOG_LEVEL=[Service log level] MF_AUTH_DB_HOST=[Database host address] MF_AUTH_DB_PORT=[Database host port] MF_AUTH_DB_USER=[Database user] MF_AUTH_DB_PASS=[Database password] MF_AUTH_DB=[Name of the database used by the service] MF_AUTH_DB_SSL_MODE=[SSL mode to connect to the database with] MF_AUTH_DB_SSL_CERT=[Path to the PEM encoded certificate file] MF_AUTH_DB_SSL_KEY=[Path to the PEM encoded key file] MF_AUTH_DB_SSL_ROOT_CERT=[Path to the PEM encoded root certificate file] MF_AUTH_HTTP_PORT=[Service HTTP port] MF_AUTH_GRPC_PORT=[Service gRPC port] MF_AUTH_SECRET=[String used for signing tokens] MF_AUTH_SERVER_CERT=[Path to server certificate] MF_AUTH_SERVER_KEY=[Path to server key] MF_JAEGER_URL=[Jaeger server URL] $GOBIN/mainflux-auth
MF_AUTH_LOG_LEVEL=[Service log level] MF_AUTH_DB_HOST=[Database host address] MF_AUTH_DB_PORT=[Database host port] MF_AUTH_DB_USER=[Database user] MF_AUTH_DB_PASS=[Database password] MF_AUTH_DB=[Name of the database used by the service] MF_AUTH_DB_SSL_MODE=[SSL mode to connect to the database with] MF_AUTH_DB_SSL_CERT=[Path to the PEM encoded certificate file] MF_AUTH_DB_SSL_KEY=[Path to the PEM encoded key file] MF_AUTH_DB_SSL_ROOT_CERT=[Path to the PEM encoded root certificate file] MF_AUTH_HTTP_PORT=[Service HTTP port] MF_AUTH_GRPC_PORT=[Service gRPC port] MF_AUTH_SECRET=[String used for signing tokens] MF_AUTH_SERVER_CERT=[Path to server certificate] MF_AUTH_SERVER_KEY=[Path to server key] MF_JAEGER_URL=[Jaeger server URL] MF_AUTH_LOGIN_TOKEN_DURATION=[The login token expiration period] $GOBIN/mainflux-auth
```
If `MF_EMAIL_TEMPLATE` doesn't point to any file service will function but password reset functionality will not work.

View File

@ -37,6 +37,7 @@ const (
authoritiesObj = "authorities"
memberRelation = "member"
loginDuration = 30 * time.Minute
)
var svc auth.Service
@ -52,7 +53,7 @@ func newService() auth.Service {
t := jwt.New(secret)
return auth.New(repo, groupRepo, idProvider, t, ketoMock)
return auth.New(repo, groupRepo, idProvider, t, ketoMock, loginDuration)
}
func startGRPCServer(svc auth.Service, port int) {

View File

@ -24,10 +24,11 @@ import (
)
const (
contentType = "application/json"
email = "user@example.com"
secret = "secret"
id = "testID"
contentType = "application/json"
email = "user@example.com"
secret = "secret"
id = "testID"
loginDuration = 30 * time.Minute
)
type testRequest struct {
@ -59,7 +60,7 @@ func newService() auth.Service {
idProvider := uuid.NewMock()
t := jwt.New(secret)
policies := mocks.NewKetoMock(map[string][]mocks.MockSubjectSet{})
return auth.New(keys, groups, idProvider, t, policies)
return auth.New(keys, groups, idProvider, t, policies, loginDuration)
}
func newServer(svc auth.Service) *httptest.Server {

View File

@ -24,10 +24,11 @@ import (
)
const (
secret = "secret"
contentType = "application/json"
id = "123e4567-e89b-12d3-a456-000000000001"
email = "user@example.com"
secret = "secret"
contentType = "application/json"
id = "123e4567-e89b-12d3-a456-000000000001"
email = "user@example.com"
loginDuration = 30 * time.Minute
)
type issueRequest struct {
@ -70,7 +71,7 @@ func newService() auth.Service {
mockAuthzDB[id] = append(mockAuthzDB[id], mocks.MockSubjectSet{Object: "authorities", Relation: "member"})
ketoMock := mocks.NewKetoMock(mockAuthzDB)
return auth.New(repo, groupRepo, idProvider, t, ketoMock)
return auth.New(repo, groupRepo, idProvider, t, ketoMock, loginDuration)
}
func newServer(svc auth.Service) *httptest.Server {

View File

@ -24,12 +24,13 @@ import (
)
const (
secret = "secret"
contentType = "application/json"
id = uuid.Prefix + "-000000000001"
email = "user@example.com"
unauthzID = uuid.Prefix + "-000000000002"
unauthzEmail = "unauthz@example.com"
secret = "secret"
contentType = "application/json"
id = uuid.Prefix + "-000000000001"
email = "user@example.com"
unauthzID = uuid.Prefix + "-000000000002"
unauthzEmail = "unauthz@example.com"
loginDuration = 30 * time.Minute
)
type testRequest struct {
@ -68,7 +69,7 @@ func newService() auth.Service {
mockAuthzDB[unauthzID] = append(mockAuthzDB[unauthzID], mocks.MockSubjectSet{Object: "users", Relation: "member"})
ketoMock := mocks.NewKetoMock(mockAuthzDB)
return auth.New(repo, groupRepo, idProvider, t, ketoMock)
return auth.New(repo, groupRepo, idProvider, t, ketoMock, loginDuration)
}
func newServer(svc auth.Service) *httptest.Server {

View File

@ -14,10 +14,8 @@ import (
)
const (
loginDuration = 10 * time.Hour
recoveryDuration = 5 * time.Minute
thingsGroupType = "things"
thingsGroupType = "things"
authoritiesObject = "authorities"
memberRelation = "member"
@ -102,23 +100,25 @@ type Service interface {
var _ Service = (*service)(nil)
type service struct {
keys KeyRepository
groups GroupRepository
idProvider mainflux.IDProvider
ulidProvider mainflux.IDProvider
agent PolicyAgent
tokenizer Tokenizer
keys KeyRepository
groups GroupRepository
idProvider mainflux.IDProvider
ulidProvider mainflux.IDProvider
agent PolicyAgent
tokenizer Tokenizer
loginDuration time.Duration
}
// New instantiates the auth service implementation.
func New(keys KeyRepository, groups GroupRepository, idp mainflux.IDProvider, tokenizer Tokenizer, policyAgent PolicyAgent) Service {
func New(keys KeyRepository, groups GroupRepository, idp mainflux.IDProvider, tokenizer Tokenizer, policyAgent PolicyAgent, duration time.Duration) Service {
return &service{
tokenizer: tokenizer,
keys: keys,
groups: groups,
idProvider: idp,
ulidProvider: ulid.New(),
agent: policyAgent,
tokenizer: tokenizer,
keys: keys,
groups: groups,
idProvider: idp,
ulidProvider: ulid.New(),
agent: policyAgent,
loginDuration: duration,
}
}
@ -132,7 +132,7 @@ func (svc service) Issue(ctx context.Context, token string, key Key) (Key, strin
case RecoveryKey:
return svc.tmpKey(recoveryDuration, key)
default:
return svc.tmpKey(loginDuration, key)
return svc.tmpKey(svc.loginDuration, key)
}
}

View File

@ -29,6 +29,7 @@ const (
memberRelation = "member"
authoritiesObj = "authorities"
loginDuration = 30 * time.Minute
)
func newService() auth.Service {
@ -41,7 +42,7 @@ func newService() auth.Service {
ketoMock := mocks.NewKetoMock(mockAuthzDB)
t := jwt.New(secret)
return auth.New(repo, groupRepo, idProvider, t, ketoMock)
return auth.New(repo, groupRepo, idProvider, t, ketoMock, loginDuration)
}
func TestIssue(t *testing.T) {

View File

@ -10,6 +10,7 @@ import (
"os"
"os/signal"
"syscall"
"time"
kitprometheus "github.com/go-kit/kit/metrics/prometheus"
"github.com/jmoiron/sqlx"
@ -52,6 +53,7 @@ const (
defKetoHost = "mainflux-keto"
defKetoWritePort = "4467"
defKetoReadPort = "4466"
defLoginDuration = "10h"
envLogLevel = "MF_AUTH_LOG_LEVEL"
envDBHost = "MF_AUTH_DB_HOST"
@ -72,6 +74,7 @@ const (
envKetoHost = "MF_KETO_HOST"
envKetoWritePort = "MF_KETO_WRITE_REMOTE_PORT"
envKetoReadPort = "MF_KETO_READ_REMOTE_PORT"
envLoginDuration = "MF_AUTH_LOGIN_TOKEN_DURATION"
)
type config struct {
@ -87,6 +90,7 @@ type config struct {
ketoHost string
ketoWritePort string
ketoReadPort string
loginDuration time.Duration
}
type tokenConfig struct {
@ -113,7 +117,7 @@ func main() {
readerConn, writerConn := initKeto(cfg.ketoHost, cfg.ketoReadPort, cfg.ketoWritePort, logger)
svc := newService(db, dbTracer, cfg.secret, logger, readerConn, writerConn)
svc := newService(db, dbTracer, cfg.secret, logger, readerConn, writerConn, cfg.loginDuration)
errs := make(chan error, 2)
go startHTTPServer(tracer, svc, cfg.httpPort, cfg.serverCert, cfg.serverKey, logger, errs)
@ -142,6 +146,11 @@ func loadConfig() config {
SSLRootCert: mainflux.Env(envDBSSLRootCert, defDBSSLRootCert),
}
loginDuration, err := time.ParseDuration(mainflux.Env(envLoginDuration, defLoginDuration))
if err != nil {
log.Fatal(err)
}
return config{
logLevel: mainflux.Env(envLogLevel, defLogLevel),
dbConfig: dbConfig,
@ -154,6 +163,7 @@ func loadConfig() config {
ketoHost: mainflux.Env(envKetoHost, defKetoHost),
ketoReadPort: mainflux.Env(envKetoReadPort, defKetoReadPort),
ketoWritePort: mainflux.Env(envKetoWritePort, defKetoWritePort),
loginDuration: loginDuration,
}
}
@ -207,7 +217,7 @@ func connectToDB(dbConfig postgres.Config, logger logger.Logger) *sqlx.DB {
return db
}
func newService(db *sqlx.DB, tracer opentracing.Tracer, secret string, logger logger.Logger, readerConn, writerConn *grpc.ClientConn) auth.Service {
func newService(db *sqlx.DB, tracer opentracing.Tracer, secret string, logger logger.Logger, readerConn, writerConn *grpc.ClientConn, duration time.Duration) auth.Service {
database := postgres.NewDatabase(db)
keysRepo := tracing.New(postgres.New(database), tracer)
@ -219,7 +229,7 @@ func newService(db *sqlx.DB, tracer opentracing.Tracer, secret string, logger lo
idProvider := uuid.New()
t := jwt.New(secret)
svc := auth.New(keysRepo, groupsRepo, idProvider, t, pa)
svc := auth.New(keysRepo, groupsRepo, idProvider, t, pa, duration)
svc = api.LoggingMiddleware(svc, logger)
svc = api.MetricsMiddleware(
svc,

View File

@ -35,6 +35,7 @@ MF_AUTH_DB_USER=mainflux
MF_AUTH_DB_PASS=mainflux
MF_AUTH_DB=auth
MF_AUTH_SECRET=secret
MF_AUTH_LOGIN_TOKEN_DURATION="10h"
### Keto
MF_KETO_HOST=mainflux-keto

View File

@ -138,6 +138,7 @@ services:
MF_AUTH_HTTP_PORT: ${MF_AUTH_HTTP_PORT}
MF_AUTH_GRPC_PORT: ${MF_AUTH_GRPC_PORT}
MF_AUTH_SECRET: ${MF_AUTH_SECRET}
MF_AUTH_LOGIN_TOKEN_DURATION: ${MF_AUTH_LOGIN_TOKEN_DURATION}
MF_JAEGER_URL: ${MF_JAEGER_URL}
MF_KETO_HOST: ${MF_KETO_HOST}
MF_KETO_WRITE_REMOTE_PORT: ${MF_KETO_WRITE_REMOTE_PORT}

View File

@ -63,7 +63,7 @@ MF_COAP_ADAPTER_LOG_LEVEL=info MF_COAP_ADAPTER_PORT=5683 MF_THINGS_AUTH_GRPC_URL
###
# AUTH
###
MF_AUTH_LOG_LEVEL=debug MF_AUTH_HTTP_PORT=8189 MF_AUTH_GRPC_PORT=8181 MF_AUTH_DB_PORT=5432 MF_AUTH_DB_USER=mainflux MF_AUTH_DB_PASS=mainflux MF_AUTH_DB=auth MF_AUTH_SECRET=secret $BUILD_DIR/mainflux-auth &
MF_AUTH_LOG_LEVEL=debug MF_AUTH_HTTP_PORT=8189 MF_AUTH_GRPC_PORT=8181 MF_AUTH_DB_PORT=5432 MF_AUTH_DB_USER=mainflux MF_AUTH_DB_PASS=mainflux MF_AUTH_DB=auth MF_AUTH_SECRET=secret MF_AUTH_LOGIN_TOKEN_DURATION=10h $BUILD_DIR/mainflux-auth &
trap cleanup EXIT