go-tdlib/client/authorization.go

199 lines
5.7 KiB
Go
Raw Normal View History

2018-08-30 14:55:42 +00:00
package client
import (
"errors"
"fmt"
"time"
)
var ErrNotSupportedAuthorizationState = errors.New("not supported state")
type AuthorizationStateHandler interface {
Handle(client *Client, state AuthorizationState) error
}
func Authorize(client *Client, authorizationStateHandler AuthorizationStateHandler) error {
for {
state, err := client.GetAuthorizationState()
if err != nil {
return err
}
err = authorizationStateHandler.Handle(client, state)
if err != nil {
return err
}
if state.AuthorizationStateType() == TypeAuthorizationStateReady {
// dirty hack for db flush after authorization
time.Sleep(1 * time.Second)
return nil
}
}
}
type clientAuthorizer struct {
TdlibParameters chan *TdlibParameters
PhoneNumber chan string
Code chan string
State chan AuthorizationState
2018-10-04 10:05:40 +00:00
FirstName chan string
LastName chan string
2018-08-30 14:55:42 +00:00
}
func ClientAuthorizer() *clientAuthorizer {
return &clientAuthorizer{
TdlibParameters: make(chan *TdlibParameters, 1),
PhoneNumber: make(chan string, 1),
Code: make(chan string, 1),
State: make(chan AuthorizationState, 10),
2018-10-04 10:05:40 +00:00
FirstName: make(chan string, 1),
LastName: make(chan string, 1),
2018-08-30 14:55:42 +00:00
}
}
func (stateHandler *clientAuthorizer) Handle(client *Client, state AuthorizationState) error {
stateHandler.State <- state
switch state.AuthorizationStateType() {
case TypeAuthorizationStateWaitTdlibParameters:
_, err := client.SetTdlibParameters(<-stateHandler.TdlibParameters)
return err
case TypeAuthorizationStateWaitEncryptionKey:
_, err := client.CheckDatabaseEncryptionKey(nil)
return err
case TypeAuthorizationStateWaitPhoneNumber:
_, err := client.SetAuthenticationPhoneNumber(<-stateHandler.PhoneNumber, false, false)
return err
case TypeAuthorizationStateWaitCode:
2018-10-04 10:05:40 +00:00
_, err := client.CheckAuthenticationCode(<-stateHandler.Code, <-stateHandler.FirstName, <-stateHandler.LastName)
2018-08-30 14:55:42 +00:00
return err
case TypeAuthorizationStateWaitPassword:
return ErrNotSupportedAuthorizationState
case TypeAuthorizationStateReady:
close(stateHandler.TdlibParameters)
close(stateHandler.PhoneNumber)
close(stateHandler.Code)
close(stateHandler.State)
2018-10-04 10:05:40 +00:00
close(stateHandler.FirstName)
close(stateHandler.LastName)
2018-08-30 14:55:42 +00:00
return nil
case TypeAuthorizationStateLoggingOut:
return ErrNotSupportedAuthorizationState
case TypeAuthorizationStateClosing:
return ErrNotSupportedAuthorizationState
case TypeAuthorizationStateClosed:
return ErrNotSupportedAuthorizationState
}
return ErrNotSupportedAuthorizationState
}
2018-10-04 10:05:40 +00:00
func CliInteractor(clientAuthorizer *clientAuthorizer, registration bool) {
2018-08-30 14:55:42 +00:00
for {
select {
case state := <-clientAuthorizer.State:
switch state.AuthorizationStateType() {
case TypeAuthorizationStateWaitPhoneNumber:
fmt.Println("Enter phone number: ")
var phoneNumber string
fmt.Scanln(&phoneNumber)
clientAuthorizer.PhoneNumber <- phoneNumber
case TypeAuthorizationStateWaitCode:
var code string
2018-10-09 13:06:42 +00:00
var firstName string
var lastName string
2018-08-30 14:55:42 +00:00
2018-10-09 13:06:42 +00:00
fmt.Println("Enter code: ")
fmt.Scanln(&code)
2018-08-30 14:55:42 +00:00
2018-10-04 10:05:40 +00:00
if registration {
fmt.Println("Enter first name: ")
fmt.Scanln(&firstName)
fmt.Println("Enter last name: ")
fmt.Scanln(&lastName)
}
2018-10-09 13:06:42 +00:00
clientAuthorizer.Code <- code
clientAuthorizer.FirstName <- firstName
clientAuthorizer.LastName <- lastName
2018-08-30 14:55:42 +00:00
case TypeAuthorizationStateReady:
return
}
}
}
}
type botAuthorizer struct {
TdlibParameters chan *TdlibParameters
Token chan string
State chan AuthorizationState
}
func BotAuthorizer(token string) *botAuthorizer {
botAuthorizer := &botAuthorizer{
TdlibParameters: make(chan *TdlibParameters, 1),
Token: make(chan string, 1),
State: make(chan AuthorizationState, 10),
}
botAuthorizer.Token <- token
return botAuthorizer
}
func (stateHandler *botAuthorizer) Handle(client *Client, state AuthorizationState) error {
stateHandler.State <- state
switch state.AuthorizationStateType() {
case TypeAuthorizationStateWaitTdlibParameters:
_, err := client.SetTdlibParameters(<-stateHandler.TdlibParameters)
return err
case TypeAuthorizationStateWaitEncryptionKey:
_, err := client.CheckDatabaseEncryptionKey(nil)
return err
case TypeAuthorizationStateWaitPhoneNumber:
_, err := client.CheckAuthenticationBotToken(<-stateHandler.Token)
return err
case TypeAuthorizationStateWaitCode:
return ErrNotSupportedAuthorizationState
case TypeAuthorizationStateWaitPassword:
return ErrNotSupportedAuthorizationState
case TypeAuthorizationStateReady:
close(stateHandler.TdlibParameters)
close(stateHandler.Token)
close(stateHandler.State)
return nil
case TypeAuthorizationStateLoggingOut:
return ErrNotSupportedAuthorizationState
case TypeAuthorizationStateClosing:
return ErrNotSupportedAuthorizationState
case TypeAuthorizationStateClosed:
return ErrNotSupportedAuthorizationState
}
return ErrNotSupportedAuthorizationState
}