mirror of
https://github.com/mautrix/signal.git
synced 2026-09-16 15:52:04 -04:00
169 lines
6.4 KiB
Go
169 lines
6.4 KiB
Go
// mautrix-signal - A Matrix-signal puppeting bridge.
|
|
// Copyright (C) 2026 Tulir Asokan
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
package web
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
"errors"
|
|
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/credentials"
|
|
|
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/rpc/account"
|
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/rpc/attachments"
|
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/rpc/backups"
|
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/rpc/call_quality"
|
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/rpc/calling"
|
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/rpc/challenge"
|
|
scredentials "go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/rpc/credentials"
|
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/rpc/device"
|
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/rpc/donations"
|
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/rpc/keys"
|
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/rpc/login_purchase"
|
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/rpc/messages"
|
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/rpc/one_time_donations"
|
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/rpc/payments"
|
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/rpc/product_configuration"
|
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/rpc/profile"
|
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/rpc/remote_configuration"
|
|
"go.mau.fi/mautrix-signal/pkg/signalmeow/protobuf/rpc/subscriptions"
|
|
)
|
|
|
|
type GRPCAuthHeader struct {
|
|
value string
|
|
}
|
|
|
|
var _ credentials.PerRPCCredentials = (*GRPCAuthHeader)(nil)
|
|
|
|
func basicAuth(username, password string) string {
|
|
auth := username + ":" + password
|
|
return base64.StdEncoding.EncodeToString([]byte(auth))
|
|
}
|
|
|
|
func (a *GRPCAuthHeader) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
|
|
return map[string]string{
|
|
"authorization": a.value,
|
|
}, nil
|
|
}
|
|
|
|
func (a *GRPCAuthHeader) RequireTransportSecurity() bool {
|
|
return true
|
|
}
|
|
|
|
type GRPCClient struct {
|
|
AuthConn *grpc.ClientConn
|
|
UnauthConn *grpc.ClientConn
|
|
|
|
Accounts account.AccountsClient
|
|
Attachments attachments.AttachmentsClient
|
|
Backups backups.BackupsClient
|
|
Calling calling.CallingClient
|
|
Challenge challenge.ChallengeClient
|
|
Credentials scredentials.CredentialsClient
|
|
Devices device.DevicesClient
|
|
Donations donations.DonationsClient
|
|
Keys keys.KeysClient
|
|
Messages messages.MessagesClient
|
|
Payments payments.PaymentsClient
|
|
Profile profile.ProfileClient
|
|
RemoteConfiguration remote_configuration.RemoteConfigurationClient
|
|
|
|
AccountsAnonymous account.AccountsAnonymousClient
|
|
BackupsAnonymous backups.BackupsAnonymousClient
|
|
CredentialsAnonymous scredentials.CredentialsAnonymousClient
|
|
KeysAnonymous keys.KeysAnonymousClient
|
|
MessagesAnonymous messages.MessagesAnonymousClient
|
|
ProfileAnonymous profile.ProfileAnonymousClient
|
|
CallQuality call_quality.CallQualityClient
|
|
LoginPurchase login_purchase.LoginPurchaseClient
|
|
OneTimeDonations one_time_donations.OneTimeDonationsClient
|
|
ProductConfiguration product_configuration.ProductConfigurationClient
|
|
Subscriptions subscriptions.SubscriptionsClient
|
|
}
|
|
|
|
func (gc *GRPCClient) Close() error {
|
|
if gc == nil {
|
|
return nil
|
|
}
|
|
return errors.Join(
|
|
gc.AuthConn.Close(),
|
|
gc.UnauthConn.Close(),
|
|
)
|
|
}
|
|
|
|
func (gc *GRPCClient) ResetConnectBackoff() {
|
|
if gc == nil {
|
|
return
|
|
}
|
|
gc.AuthConn.ResetConnectBackoff()
|
|
gc.UnauthConn.ResetConnectBackoff()
|
|
}
|
|
|
|
const GRPCTarget = "dns://grpc.chat.signal.org:443"
|
|
|
|
func NewGRPCClient(username, password string) (*GRPCClient, error) {
|
|
grpcTLSConfig := credentials.NewTLS(SignalTLSConfig)
|
|
authConn, err := grpc.NewClient(
|
|
GRPCTarget,
|
|
grpc.WithUserAgent(UserAgent),
|
|
grpc.WithTransportCredentials(grpcTLSConfig),
|
|
grpc.WithPerRPCCredentials(&GRPCAuthHeader{value: "Basic " + basicAuth(username, password)}),
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
unauthConn, err := grpc.NewClient(
|
|
GRPCTarget,
|
|
grpc.WithUserAgent(UserAgent),
|
|
grpc.WithTransportCredentials(grpcTLSConfig),
|
|
)
|
|
if err != nil {
|
|
_ = authConn.Close()
|
|
return nil, err
|
|
}
|
|
return &GRPCClient{
|
|
AuthConn: authConn,
|
|
UnauthConn: unauthConn,
|
|
|
|
Accounts: account.NewAccountsClient(authConn),
|
|
Attachments: attachments.NewAttachmentsClient(authConn),
|
|
Backups: backups.NewBackupsClient(authConn),
|
|
Calling: calling.NewCallingClient(authConn),
|
|
Challenge: challenge.NewChallengeClient(authConn),
|
|
Credentials: scredentials.NewCredentialsClient(authConn),
|
|
Devices: device.NewDevicesClient(authConn),
|
|
Donations: donations.NewDonationsClient(authConn),
|
|
Keys: keys.NewKeysClient(authConn),
|
|
Messages: messages.NewMessagesClient(authConn),
|
|
Payments: payments.NewPaymentsClient(authConn),
|
|
Profile: profile.NewProfileClient(authConn),
|
|
RemoteConfiguration: remote_configuration.NewRemoteConfigurationClient(authConn),
|
|
|
|
AccountsAnonymous: account.NewAccountsAnonymousClient(unauthConn),
|
|
BackupsAnonymous: backups.NewBackupsAnonymousClient(unauthConn),
|
|
CredentialsAnonymous: scredentials.NewCredentialsAnonymousClient(unauthConn),
|
|
KeysAnonymous: keys.NewKeysAnonymousClient(unauthConn),
|
|
MessagesAnonymous: messages.NewMessagesAnonymousClient(unauthConn),
|
|
ProfileAnonymous: profile.NewProfileAnonymousClient(unauthConn),
|
|
CallQuality: call_quality.NewCallQualityClient(unauthConn),
|
|
LoginPurchase: login_purchase.NewLoginPurchaseClient(unauthConn),
|
|
OneTimeDonations: one_time_donations.NewOneTimeDonationsClient(unauthConn),
|
|
ProductConfiguration: product_configuration.NewProductConfigurationClient(unauthConn),
|
|
Subscriptions: subscriptions.NewSubscriptionsClient(unauthConn),
|
|
}, nil
|
|
}
|