51 lines
1.5 KiB
Go
51 lines
1.5 KiB
Go
|
|
package secrets
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"encoding/base64"
|
||
|
|
"fmt"
|
||
|
|
)
|
||
|
|
|
||
|
|
// SessionStorage keeps the MTProto session in OpenBao and never on disk.
|
||
|
|
//
|
||
|
|
// gotd's own FileStorage would put a full-account credential in the working
|
||
|
|
// directory, where it outlives the run, gets committed by accident, and is
|
||
|
|
// readable by anything on the box. The session can do everything the operator
|
||
|
|
// account can do, so it is held exactly where the bot token is.
|
||
|
|
type SessionStorage struct {
|
||
|
|
Store *Store
|
||
|
|
}
|
||
|
|
|
||
|
|
const sessionField = "session_b64"
|
||
|
|
|
||
|
|
func (s SessionStorage) LoadSession(ctx context.Context) ([]byte, error) {
|
||
|
|
fields, found, err := s.Store.Get(ctx, KeyOperatorSession)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
if !found || fields[sessionField] == "" {
|
||
|
|
// gotd treats a nil session as "not authenticated yet", which is the
|
||
|
|
// correct reading of an empty path.
|
||
|
|
return nil, nil
|
||
|
|
}
|
||
|
|
raw, err := base64.StdEncoding.DecodeString(fields[sessionField])
|
||
|
|
if err != nil {
|
||
|
|
return nil, fmt.Errorf("stored session at %s is not decodable; re-run "+
|
||
|
|
"`provision session bootstrap`", s.Store.Ref(KeyOperatorSession))
|
||
|
|
}
|
||
|
|
return raw, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s SessionStorage) StoreSession(ctx context.Context, data []byte) error {
|
||
|
|
return s.Store.Put(ctx, KeyOperatorSession, map[string]string{
|
||
|
|
sessionField: base64.StdEncoding.EncodeToString(data),
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
// AppCredentials are issued by my.telegram.org and cannot be provisioned; see
|
||
|
|
// docs/seeding-runbook.md step 2.
|
||
|
|
type AppCredentials struct {
|
||
|
|
AppID int
|
||
|
|
AppHash string
|
||
|
|
}
|