-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmodule.go
More file actions
166 lines (152 loc) · 7.28 KB
/
module.go
File metadata and controls
166 lines (152 loc) · 7.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
package auth
import (
"time"
"github.com/go-modulus/auth/hash"
"github.com/go-modulus/auth/locales"
"github.com/go-modulus/auth/repository"
"github.com/go-modulus/auth/storage"
"github.com/go-modulus/graphql"
"github.com/go-modulus/modulus/logger"
"github.com/go-modulus/modulus/module"
"github.com/go-modulus/pgx"
)
type ModuleConfig struct {
AccessTokenTTL time.Duration `env:"AUTH_ACCESS_TOKEN_TTL, default=1h"`
RefreshTokenTTL time.Duration `env:"AUTH_REFRESH_TOKEN_TTL, default=720h"`
}
// NewModule creates a new module for the auth package.
// It works with the default storage implementation. It uses pgxpool for database connection.
//
// If you want to use a custom identity storage implementation, you should implement the IdentityRepository interface
// and call authModule := auth.OverrideIdentityRepository(auth.NewModule(), NewYourIdentityRepositoryImplementation).
// The same is for other storage implementations if you need it.
func NewModule(options ...module.Option) *module.Module {
return module.NewModule("modulus/auth").
AddDependencies(
pgx.NewModule(),
graphql.NewModule(),
logger.NewModule(),
).
AddProviders(
NewMiddlewareConfig,
NewMiddleware,
NewPasswordAuthenticator,
NewPlainTokenAuthenticator,
locales.ProvideLocalesFs(),
).
SetOverriddenProvider("modulus/auth.CredentialRepository", storage.NewDefaultCredentialRepository).
SetOverriddenProvider("modulus/auth.IdentityRepository", storage.NewDefaultIdentityRepository).
SetOverriddenProvider("modulus/auth.TokenRepository", storage.NewDefaultTokenRepository).
SetOverriddenProvider("modulus/auth.AccountRepository", storage.NewDefaultAccountRepository).
SetOverriddenProvider(
"modulus/auth.ResetPasswordRequestRepository",
storage.NewDefaultResetPasswordRequestRepository,
).
SetOverriddenProvider("modulus/auth.TokenHashStrategy", hash.NewSha1).
SetOverriddenProvider(
"modulus/auth.MiddlewareAuthenticator", func(auth *PlainTokenAuthenticator) Authenticator {
return auth
},
).
InitConfig(&ModuleConfig{}).
InitConfig(&storage.ResetPasswordConfig{}).
WithOptions(options...)
}
// OverrideIdentityRepository overrides the default identity storage implementation with the custom one.
// repository should be a constructor returning the implementation of the IdentityRepository interface.
func OverrideIdentityRepository[T repository.IdentityRepository](authModule *module.Module) *module.Module {
return authModule.SetOverriddenProvider(
"modulus/auth.IdentityRepository",
func(impl T) repository.IdentityRepository { return impl },
)
}
// OverrideCredentialRepository overrides the default credential storage implementation with the custom one.
// repository should be a constructor returning the implementation of the CredentialRepository interface.
func OverrideCredentialRepository[T repository.CredentialRepository](authModule *module.Module) *module.Module {
return authModule.SetOverriddenProvider(
"modulus/auth.CredentialRepository",
func(impl T) repository.CredentialRepository { return impl },
)
}
// OverrideTokenRepository overrides the default token storage implementation with the custom one.
// repository should be a constructor returning the implementation of the TokenRepository interface.
func OverrideTokenRepository[T repository.TokenRepository](authModule *module.Module) *module.Module {
return authModule.SetOverriddenProvider(
"modulus/auth.TokenRepository",
func(impl T) repository.TokenRepository { return impl },
)
}
// OverrideAccountRepository overrides the default account storage implementation with the custom one.
// repository should be a constructor returning the implementation of the AccountRepository interface.
func OverrideAccountRepository[T repository.AccountRepository](authModule *module.Module) *module.Module {
return authModule.SetOverriddenProvider(
"modulus/auth.AccountRepository",
func(impl T) repository.AccountRepository { return impl },
)
}
// OverrideTokenHashStrategy overrides the default token hash strategy with the custom one.
// strategy should be a constructor returning the implementation of the hash.TokenHashStrategy interface.
// by default, the sha1 hash strategy is used.
// if you don't want to hash tokens, you can set the strategy to none, like this auth.OverrideTokenHashStrategy[*hash.None](authModule)
func OverrideTokenHashStrategy[T hash.TokenHashStrategy](authModule *module.Module) *module.Module {
return authModule.SetOverriddenProvider(
"modulus/auth.TokenHashStrategy",
func(impl T) hash.TokenHashStrategy { return impl },
)
}
// OverrideMiddlewareAuthenticator overrides the default middleware authenticator with the custom one.
// authenticator should be a constructor returning the implementation of the Authenticator interface.
func OverrideMiddlewareAuthenticator[T Authenticator](authModule *module.Module) *module.Module {
return authModule.SetOverriddenProvider(
"modulus/auth.MiddlewareAuthenticator",
func(impl T) Authenticator { return impl },
)
}
// OverrideResetPasswordRequestRepository overrides the default reset password request storage implementation with the custom one.
func OverrideResetPasswordRequestRepository[T repository.ResetPasswordRequestRepository](authModule *module.Module) *module.Module {
return authModule.SetOverriddenProvider(
"modulus/auth.ResetPasswordRequestRepository",
func(impl T) repository.ResetPasswordRequestRepository { return impl },
)
}
func NewManifesto() module.Manifesto {
graphqlModule := module.NewManifesto(
NewModule(),
"github.com/go-modulus/auth",
"Authentication module. Helps protect HTTP routes with tokens and sessions. If you want to use default storage for identities and tokens, please install pgx module first.",
"1.0.0",
)
graphqlModule.Install.AppendFiles(
module.InstalledFile{
SourceUrl: "https://raw.githubusercontent.com/go-modulus/modulus/refs/heads/main/auth/storage/migration/20240214134322_auth.sql",
DestFile: "internal/auth/storage/migration/20240214134322_auth.sql",
},
module.InstalledFile{
SourceUrl: "https://raw.githubusercontent.com/go-modulus/modulus/refs/heads/main/auth/storage/migration/20240320084613_auth_account.sql",
DestFile: "internal/auth/storage/migration/20240320084613_auth_account.sql",
},
module.InstalledFile{
SourceUrl: "https://raw.githubusercontent.com/go-modulus/modulus/refs/heads/main/auth/storage/migration/20250508110252_add_reset_password_request_table.sql",
DestFile: "internal/auth/storage/migration/20250508110252_add_reset_password_request_table.sql",
},
module.InstalledFile{
SourceUrl: "https://raw.githubusercontent.com/go-modulus/modulus/refs/heads/main/auth/install/module.go.tmpl",
DestFile: "internal/auth/module.go",
},
module.InstalledFile{
SourceUrl: "https://raw.githubusercontent.com/go-modulus/modulus/refs/heads/main/auth/install/graphql/auth.graphql",
DestFile: "internal/auth/graphql/auth.graphql",
},
module.InstalledFile{
SourceUrl: "https://raw.githubusercontent.com/go-modulus/modulus/refs/heads/main/auth/install/graphql/directive.go",
DestFile: "internal/auth/graphql/directive.go",
},
).AppendPostInstallCommands(
module.PostInstallCommand{
CmdPackage: "github.com/go-modulus/mtools/cmd/mtools@latest",
Params: []string{"db", "migrate"},
},
)
graphqlModule.LocalPath = "internal/auth"
return graphqlModule
}