feat(auth): Complete Auth Service implementation and fix Consul health checks

- Add VerifyPassword RPC to Identity Service
  - Added to proto file and generated code
  - Implemented in Identity Service gRPC server
  - Added to Identity Service client interface and gRPC client

- Complete RefreshToken implementation
  - Store refresh tokens in database using RefreshToken entity
  - Validate refresh tokens with expiration checking
  - Revoke refresh tokens on logout and token rotation

- Integrate Authz Service for role retrieval
  - Added AuthzServiceClient to Auth Service
  - Get user roles during login and token refresh
  - Gracefully handle Authz Service failures

- Require JWT secret in configuration
  - Removed default secret fallback
  - Service fails to start if JWT secret is not configured

- Fix Consul health checks for Docker
  - Services now register with Docker service names (e.g., audit-service)
  - Allows Consul (in Docker) to reach services via Docker DNS
  - Health checks use gRPC service names instead of localhost

This completes all TODOs in auth_service_fx.go and fixes the Consul
health check failures in Docker environments.
This commit is contained in:
2025-11-06 21:26:34 +01:00
parent b02c1d44c8
commit 04022b835e
34 changed files with 6775 additions and 90 deletions

View File

@@ -0,0 +1,82 @@
// Code generated by ent, DO NOT EDIT.
package refreshtoken
import (
"time"
"entgo.io/ent/dialect/sql"
)
const (
// Label holds the string label denoting the refreshtoken type in the database.
Label = "refresh_token"
// FieldID holds the string denoting the id field in the database.
FieldID = "id"
// FieldUserID holds the string denoting the user_id field in the database.
FieldUserID = "user_id"
// FieldTokenHash holds the string denoting the token_hash field in the database.
FieldTokenHash = "token_hash"
// FieldExpiresAt holds the string denoting the expires_at field in the database.
FieldExpiresAt = "expires_at"
// FieldCreatedAt holds the string denoting the created_at field in the database.
FieldCreatedAt = "created_at"
// Table holds the table name of the refreshtoken in the database.
Table = "refresh_tokens"
)
// Columns holds all SQL columns for refreshtoken fields.
var Columns = []string{
FieldID,
FieldUserID,
FieldTokenHash,
FieldExpiresAt,
FieldCreatedAt,
}
// ValidColumn reports if the column name is valid (part of the table columns).
func ValidColumn(column string) bool {
for i := range Columns {
if column == Columns[i] {
return true
}
}
return false
}
var (
// UserIDValidator is a validator for the "user_id" field. It is called by the builders before save.
UserIDValidator func(string) error
// TokenHashValidator is a validator for the "token_hash" field. It is called by the builders before save.
TokenHashValidator func(string) error
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
DefaultCreatedAt func() time.Time
)
// OrderOption defines the ordering options for the RefreshToken queries.
type OrderOption func(*sql.Selector)
// ByID orders the results by the id field.
func ByID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldID, opts...).ToFunc()
}
// ByUserID orders the results by the user_id field.
func ByUserID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldUserID, opts...).ToFunc()
}
// ByTokenHash orders the results by the token_hash field.
func ByTokenHash(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldTokenHash, opts...).ToFunc()
}
// ByExpiresAt orders the results by the expires_at field.
func ByExpiresAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldExpiresAt, opts...).ToFunc()
}
// ByCreatedAt orders the results by the created_at field.
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
}

View File

@@ -0,0 +1,310 @@
// Code generated by ent, DO NOT EDIT.
package refreshtoken
import (
"time"
"entgo.io/ent/dialect/sql"
"git.dcentral.systems/toolz/goplt/internal/ent/predicate"
)
// ID filters vertices based on their ID field.
func ID(id string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldEQ(FieldID, id))
}
// IDEQ applies the EQ predicate on the ID field.
func IDEQ(id string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldEQ(FieldID, id))
}
// IDNEQ applies the NEQ predicate on the ID field.
func IDNEQ(id string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldNEQ(FieldID, id))
}
// IDIn applies the In predicate on the ID field.
func IDIn(ids ...string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldIn(FieldID, ids...))
}
// IDNotIn applies the NotIn predicate on the ID field.
func IDNotIn(ids ...string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldNotIn(FieldID, ids...))
}
// IDGT applies the GT predicate on the ID field.
func IDGT(id string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldGT(FieldID, id))
}
// IDGTE applies the GTE predicate on the ID field.
func IDGTE(id string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldGTE(FieldID, id))
}
// IDLT applies the LT predicate on the ID field.
func IDLT(id string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldLT(FieldID, id))
}
// IDLTE applies the LTE predicate on the ID field.
func IDLTE(id string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldLTE(FieldID, id))
}
// IDEqualFold applies the EqualFold predicate on the ID field.
func IDEqualFold(id string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldEqualFold(FieldID, id))
}
// IDContainsFold applies the ContainsFold predicate on the ID field.
func IDContainsFold(id string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldContainsFold(FieldID, id))
}
// UserID applies equality check predicate on the "user_id" field. It's identical to UserIDEQ.
func UserID(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldEQ(FieldUserID, v))
}
// TokenHash applies equality check predicate on the "token_hash" field. It's identical to TokenHashEQ.
func TokenHash(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldEQ(FieldTokenHash, v))
}
// ExpiresAt applies equality check predicate on the "expires_at" field. It's identical to ExpiresAtEQ.
func ExpiresAt(v time.Time) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldEQ(FieldExpiresAt, v))
}
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
func CreatedAt(v time.Time) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldEQ(FieldCreatedAt, v))
}
// UserIDEQ applies the EQ predicate on the "user_id" field.
func UserIDEQ(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldEQ(FieldUserID, v))
}
// UserIDNEQ applies the NEQ predicate on the "user_id" field.
func UserIDNEQ(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldNEQ(FieldUserID, v))
}
// UserIDIn applies the In predicate on the "user_id" field.
func UserIDIn(vs ...string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldIn(FieldUserID, vs...))
}
// UserIDNotIn applies the NotIn predicate on the "user_id" field.
func UserIDNotIn(vs ...string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldNotIn(FieldUserID, vs...))
}
// UserIDGT applies the GT predicate on the "user_id" field.
func UserIDGT(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldGT(FieldUserID, v))
}
// UserIDGTE applies the GTE predicate on the "user_id" field.
func UserIDGTE(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldGTE(FieldUserID, v))
}
// UserIDLT applies the LT predicate on the "user_id" field.
func UserIDLT(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldLT(FieldUserID, v))
}
// UserIDLTE applies the LTE predicate on the "user_id" field.
func UserIDLTE(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldLTE(FieldUserID, v))
}
// UserIDContains applies the Contains predicate on the "user_id" field.
func UserIDContains(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldContains(FieldUserID, v))
}
// UserIDHasPrefix applies the HasPrefix predicate on the "user_id" field.
func UserIDHasPrefix(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldHasPrefix(FieldUserID, v))
}
// UserIDHasSuffix applies the HasSuffix predicate on the "user_id" field.
func UserIDHasSuffix(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldHasSuffix(FieldUserID, v))
}
// UserIDEqualFold applies the EqualFold predicate on the "user_id" field.
func UserIDEqualFold(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldEqualFold(FieldUserID, v))
}
// UserIDContainsFold applies the ContainsFold predicate on the "user_id" field.
func UserIDContainsFold(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldContainsFold(FieldUserID, v))
}
// TokenHashEQ applies the EQ predicate on the "token_hash" field.
func TokenHashEQ(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldEQ(FieldTokenHash, v))
}
// TokenHashNEQ applies the NEQ predicate on the "token_hash" field.
func TokenHashNEQ(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldNEQ(FieldTokenHash, v))
}
// TokenHashIn applies the In predicate on the "token_hash" field.
func TokenHashIn(vs ...string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldIn(FieldTokenHash, vs...))
}
// TokenHashNotIn applies the NotIn predicate on the "token_hash" field.
func TokenHashNotIn(vs ...string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldNotIn(FieldTokenHash, vs...))
}
// TokenHashGT applies the GT predicate on the "token_hash" field.
func TokenHashGT(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldGT(FieldTokenHash, v))
}
// TokenHashGTE applies the GTE predicate on the "token_hash" field.
func TokenHashGTE(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldGTE(FieldTokenHash, v))
}
// TokenHashLT applies the LT predicate on the "token_hash" field.
func TokenHashLT(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldLT(FieldTokenHash, v))
}
// TokenHashLTE applies the LTE predicate on the "token_hash" field.
func TokenHashLTE(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldLTE(FieldTokenHash, v))
}
// TokenHashContains applies the Contains predicate on the "token_hash" field.
func TokenHashContains(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldContains(FieldTokenHash, v))
}
// TokenHashHasPrefix applies the HasPrefix predicate on the "token_hash" field.
func TokenHashHasPrefix(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldHasPrefix(FieldTokenHash, v))
}
// TokenHashHasSuffix applies the HasSuffix predicate on the "token_hash" field.
func TokenHashHasSuffix(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldHasSuffix(FieldTokenHash, v))
}
// TokenHashEqualFold applies the EqualFold predicate on the "token_hash" field.
func TokenHashEqualFold(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldEqualFold(FieldTokenHash, v))
}
// TokenHashContainsFold applies the ContainsFold predicate on the "token_hash" field.
func TokenHashContainsFold(v string) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldContainsFold(FieldTokenHash, v))
}
// ExpiresAtEQ applies the EQ predicate on the "expires_at" field.
func ExpiresAtEQ(v time.Time) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldEQ(FieldExpiresAt, v))
}
// ExpiresAtNEQ applies the NEQ predicate on the "expires_at" field.
func ExpiresAtNEQ(v time.Time) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldNEQ(FieldExpiresAt, v))
}
// ExpiresAtIn applies the In predicate on the "expires_at" field.
func ExpiresAtIn(vs ...time.Time) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldIn(FieldExpiresAt, vs...))
}
// ExpiresAtNotIn applies the NotIn predicate on the "expires_at" field.
func ExpiresAtNotIn(vs ...time.Time) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldNotIn(FieldExpiresAt, vs...))
}
// ExpiresAtGT applies the GT predicate on the "expires_at" field.
func ExpiresAtGT(v time.Time) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldGT(FieldExpiresAt, v))
}
// ExpiresAtGTE applies the GTE predicate on the "expires_at" field.
func ExpiresAtGTE(v time.Time) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldGTE(FieldExpiresAt, v))
}
// ExpiresAtLT applies the LT predicate on the "expires_at" field.
func ExpiresAtLT(v time.Time) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldLT(FieldExpiresAt, v))
}
// ExpiresAtLTE applies the LTE predicate on the "expires_at" field.
func ExpiresAtLTE(v time.Time) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldLTE(FieldExpiresAt, v))
}
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
func CreatedAtEQ(v time.Time) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldEQ(FieldCreatedAt, v))
}
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
func CreatedAtNEQ(v time.Time) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldNEQ(FieldCreatedAt, v))
}
// CreatedAtIn applies the In predicate on the "created_at" field.
func CreatedAtIn(vs ...time.Time) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldIn(FieldCreatedAt, vs...))
}
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
func CreatedAtNotIn(vs ...time.Time) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldNotIn(FieldCreatedAt, vs...))
}
// CreatedAtGT applies the GT predicate on the "created_at" field.
func CreatedAtGT(v time.Time) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldGT(FieldCreatedAt, v))
}
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
func CreatedAtGTE(v time.Time) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldGTE(FieldCreatedAt, v))
}
// CreatedAtLT applies the LT predicate on the "created_at" field.
func CreatedAtLT(v time.Time) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldLT(FieldCreatedAt, v))
}
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
func CreatedAtLTE(v time.Time) predicate.RefreshToken {
return predicate.RefreshToken(sql.FieldLTE(FieldCreatedAt, v))
}
// And groups predicates with the AND operator between them.
func And(predicates ...predicate.RefreshToken) predicate.RefreshToken {
return predicate.RefreshToken(sql.AndPredicates(predicates...))
}
// Or groups predicates with the OR operator between them.
func Or(predicates ...predicate.RefreshToken) predicate.RefreshToken {
return predicate.RefreshToken(sql.OrPredicates(predicates...))
}
// Not applies the not operator on the given predicate.
func Not(p predicate.RefreshToken) predicate.RefreshToken {
return predicate.RefreshToken(sql.NotPredicates(p))
}