use single loop for telegram auth and notify
This commit is contained in:
committed by
Umputun
parent
c751fbaf37
commit
be3643ed10
+68
-53
@@ -454,7 +454,12 @@ func (s *ServerCommand) newServerApp(ctx context.Context) (*serverApp, error) {
|
||||
return nil, errors.Wrap(err, "failed to make avatar store")
|
||||
}
|
||||
authRefreshCache := newAuthRefreshCache()
|
||||
authenticator, err := s.makeAuthenticator(ctx, dataService, avatarStore, adminStore, authRefreshCache)
|
||||
authenticator := s.getAuthenticator(dataService, avatarStore, adminStore, authRefreshCache)
|
||||
|
||||
telegramAuth := s.makeTelegramAuth(authenticator) // telegram auth requires TelegramAPI listener which is constructed below
|
||||
telegramService, telegramBotUsername := s.startTelegramAuthAndNotify(ctx, telegramAuth)
|
||||
|
||||
err = s.addAuthProviders(authenticator)
|
||||
if err != nil {
|
||||
_ = dataService.Close()
|
||||
return nil, errors.Wrap(err, "failed to make authenticator")
|
||||
@@ -478,26 +483,7 @@ func (s *ServerCommand) newServerApp(ctx context.Context) (*serverApp, error) {
|
||||
log.Printf("[WARN] failed to prepare notify destinations, %s", err)
|
||||
}
|
||||
|
||||
// telegramService is used for getting user replies for both notifications and authorization
|
||||
var telegramService *notify.Telegram
|
||||
if contains("telegram", s.Notify.Users) || contains("telegram", s.Notify.Admins) || s.Auth.Telegram {
|
||||
telegramService, err = s.makeTelegramNotify()
|
||||
if err != nil {
|
||||
log.Printf("[WARN] failed to make telegram notify service, %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
var telegramBotUsername string
|
||||
if telegramService != nil {
|
||||
if contains("telegram", s.Notify.Users) {
|
||||
telegramBotUsername = telegramService.GetBotUsername()
|
||||
}
|
||||
notifyDestinations = append(notifyDestinations, telegramService)
|
||||
// start generic update for both notify and auth services
|
||||
go providers.DispatchTelegramUpdates(ctx, telegramService, []providers.TGUpdatesReceiver{telegramService}, time.Second*5)
|
||||
}
|
||||
|
||||
notifyService := s.makeNotifyService(dataService, notifyDestinations)
|
||||
notifyService := s.makeNotifyService(dataService, notifyDestinations, telegramService)
|
||||
|
||||
imgProxy := &proxy.Image{
|
||||
HTTP2HTTPS: s.ImageProxy.HTTP2HTTPS,
|
||||
@@ -785,9 +771,12 @@ func (s *ServerCommand) makeCache() (LoadingCache, error) {
|
||||
return nil, errors.Errorf("unsupported cache type %s", s.Cache.Type)
|
||||
}
|
||||
|
||||
func (s *ServerCommand) addAuthProviders(ctx context.Context, authenticator *auth.Service) error {
|
||||
|
||||
func (s *ServerCommand) addAuthProviders(authenticator *auth.Service) error {
|
||||
providersCount := 0
|
||||
if s.Auth.Telegram {
|
||||
providersCount++
|
||||
}
|
||||
|
||||
if s.Auth.Google.CID != "" && s.Auth.Google.CSEC != "" {
|
||||
authenticator.AddProvider("google", s.Auth.Google.CID, s.Auth.Google.CSEC)
|
||||
providersCount++
|
||||
@@ -816,27 +805,6 @@ func (s *ServerCommand) addAuthProviders(ctx context.Context, authenticator *aut
|
||||
authenticator.AddProvider("patreon", s.Auth.Patreon.CID, s.Auth.Patreon.CSEC)
|
||||
providersCount++
|
||||
}
|
||||
if s.Auth.Telegram {
|
||||
telegram := &provider.TelegramHandler{
|
||||
ProviderName: "telegram",
|
||||
ErrorMsg: "❌ Invalid auth request. Please try requesting the link again.",
|
||||
SuccessMsg: "✅ You have successfully authenticated, check the web!",
|
||||
Telegram: provider.NewTelegramAPI(s.Telegram.Token, &http.Client{Timeout: s.Telegram.Timeout}),
|
||||
L: log.Default(),
|
||||
TokenService: authenticator.TokenService(),
|
||||
AvatarSaver: authenticator.AvatarProxy(),
|
||||
}
|
||||
// Run Telegram provider in the background
|
||||
go func() {
|
||||
err := telegram.Run(ctx)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] telegram auth error %+v", err)
|
||||
}
|
||||
}()
|
||||
authenticator.AddCustomHandler(telegram)
|
||||
|
||||
providersCount++
|
||||
}
|
||||
|
||||
if s.Auth.Dev {
|
||||
log.Print("[INFO] dev access enabled")
|
||||
@@ -921,7 +889,31 @@ func (s *ServerCommand) loadEmailTemplate() (string, error) {
|
||||
return string(file), nil
|
||||
}
|
||||
|
||||
func (s *ServerCommand) makeNotifyService(dataStore *service.DataStore, destinations []notify.Destination) *notify.Service {
|
||||
// creates and registers telegram auth, which we need separately from other auth providers
|
||||
func (s *ServerCommand) makeTelegramAuth(authenticator *auth.Service) providers.TGUpdatesReceiver {
|
||||
if s.Auth.Telegram {
|
||||
telegram := &provider.TelegramHandler{
|
||||
ProviderName: "telegram",
|
||||
SuccessMsg: "✅ You have successfully authenticated, check the web!",
|
||||
Telegram: provider.NewTelegramAPI(s.Telegram.Token, &http.Client{Timeout: s.Telegram.Timeout}),
|
||||
L: log.Default(),
|
||||
TokenService: authenticator.TokenService(),
|
||||
AvatarSaver: authenticator.AvatarProxy(),
|
||||
}
|
||||
authenticator.AddCustomHandler(telegram)
|
||||
return telegram
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ServerCommand) makeNotifyService(dataStore *service.DataStore, destinations []notify.Destination, telegram *notify.Telegram) *notify.Service {
|
||||
if destinations == nil {
|
||||
destinations = []notify.Destination{}
|
||||
}
|
||||
if telegram != nil {
|
||||
destinations = append(destinations, telegram)
|
||||
}
|
||||
|
||||
if len(destinations) > 0 {
|
||||
log.Printf("[INFO] make notify, for users: %s, for admins: %s", s.Notify.Users, s.Notify.Admins)
|
||||
return notify.NewService(dataStore, s.Notify.QueueSize, destinations...)
|
||||
@@ -1058,8 +1050,9 @@ func (s *ServerCommand) makeSSLConfig() (config api.SSLConfig, err error) {
|
||||
return config, err
|
||||
}
|
||||
|
||||
func (s *ServerCommand) makeAuthenticator(ctx context.Context, ds *service.DataStore, avas avatar.Store, admns admin.Store, authRefreshCache *authRefreshCache) (*auth.Service, error) {
|
||||
authenticator := auth.NewService(auth.Opts{
|
||||
// getAuthenticator creates new authenticator service, which doesn't have any auth providers enabled
|
||||
func (s *ServerCommand) getAuthenticator(ds *service.DataStore, avas avatar.Store, admns admin.Store, authRefreshCache *authRefreshCache) *auth.Service {
|
||||
return auth.NewService(auth.Opts{
|
||||
URL: strings.TrimSuffix(s.RemarkURL, "/"),
|
||||
Issuer: "remark42",
|
||||
TokenDuration: s.Auth.TTL.JWT,
|
||||
@@ -1114,12 +1107,6 @@ func (s *ServerCommand) makeAuthenticator(ctx context.Context, ds *service.DataS
|
||||
RefreshCache: authRefreshCache,
|
||||
UseGravatar: true,
|
||||
})
|
||||
|
||||
if err := s.addAuthProviders(ctx, authenticator); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return authenticator, nil
|
||||
}
|
||||
|
||||
func (s *ServerCommand) parseSameSite(ss string) http.SameSite {
|
||||
@@ -1137,6 +1124,34 @@ func (s *ServerCommand) parseSameSite(ss string) http.SameSite {
|
||||
}
|
||||
}
|
||||
|
||||
// startTelegramAuthAndNotify initializes telegram notify and auth Telegram Bot listen loop.
|
||||
// Does nothing if telegram auth and notifications are disabled.
|
||||
// Doesn't return telegram bot username if user notifications are disabled, as that is the way frontend knows they are enabled.
|
||||
func (s *ServerCommand) startTelegramAuthAndNotify(ctx context.Context, telegramAuth providers.TGUpdatesReceiver) (tg *notify.Telegram, telegramBotUsername string) {
|
||||
if !contains("telegram", s.Notify.Users) && !contains("telegram", s.Notify.Admins) && !s.Auth.Telegram {
|
||||
return nil, ""
|
||||
}
|
||||
|
||||
var err error
|
||||
if tg, err = s.makeTelegramNotify(); err != nil {
|
||||
log.Printf("[WARN] failed to make telegram notify service, %s", err)
|
||||
return nil, ""
|
||||
}
|
||||
|
||||
if contains("telegram", s.Notify.Users) {
|
||||
telegramBotUsername = tg.GetBotUsername()
|
||||
}
|
||||
|
||||
telegramReceivers := []providers.TGUpdatesReceiver{tg}
|
||||
if telegramAuth != nil {
|
||||
telegramReceivers = append(telegramReceivers, telegramAuth)
|
||||
}
|
||||
// start bot messages receiver for both notify and auth services
|
||||
go providers.DispatchTelegramUpdates(ctx, tg, telegramReceivers, time.Second*5)
|
||||
|
||||
return tg, telegramBotUsername
|
||||
}
|
||||
|
||||
// splitAtCommas split s at commas, ignoring commas in strings.
|
||||
// Eliminate leading and trailing dbl quotes in each element only if both presented
|
||||
// based on https://stackoverflow.com/a/59318708
|
||||
|
||||
Reference in New Issue
Block a user