mirror of
https://github.com/hoernschen/dendrite.git
synced 2024-12-27 07:28:27 +00:00
Revert "Handle cases when AS is not masquerading"
This reverts commit 911deb88f4
.
This commit is contained in:
parent
1401a102fc
commit
cc9cae60cb
6 changed files with 91 additions and 33 deletions
|
@ -15,6 +15,7 @@
|
|||
package appservice
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
@ -27,7 +28,9 @@ import (
|
|||
"github.com/matrix-org/dendrite/appservice/types"
|
||||
"github.com/matrix-org/dendrite/appservice/workers"
|
||||
"github.com/matrix-org/dendrite/clientapi/auth/storage/accounts"
|
||||
"github.com/matrix-org/dendrite/clientapi/auth/storage/devices"
|
||||
"github.com/matrix-org/dendrite/common/basecomponent"
|
||||
"github.com/matrix-org/dendrite/common/config"
|
||||
"github.com/matrix-org/dendrite/common/transactions"
|
||||
roomserverAPI "github.com/matrix-org/dendrite/roomserver/api"
|
||||
"github.com/matrix-org/gomatrixserverlib"
|
||||
|
@ -39,6 +42,7 @@ import (
|
|||
func SetupAppServiceAPIComponent(
|
||||
base *basecomponent.BaseDendrite,
|
||||
accountsDB *accounts.Database,
|
||||
deviceDB *devices.Database,
|
||||
federation *gomatrixserverlib.FederationClient,
|
||||
roomserverAliasAPI roomserverAPI.RoomserverAliasAPI,
|
||||
roomserverQueryAPI roomserverAPI.RoomserverQueryAPI,
|
||||
|
@ -50,11 +54,11 @@ func SetupAppServiceAPIComponent(
|
|||
logrus.WithError(err).Panicf("failed to connect to appservice db")
|
||||
}
|
||||
|
||||
// Wrap application services in a type that relates the application service and
|
||||
// a sync.Cond object that can be used to notify workers when there are new
|
||||
// events to be sent out.
|
||||
workerStates := make([]types.ApplicationServiceWorkerState, len(base.Cfg.Derived.ApplicationServices))
|
||||
for _, appservice := range base.Cfg.Derived.ApplicationServices {
|
||||
// Wrap each application service in a type that relates the application
|
||||
// service and a sync.Cond object that can be used to notify workers when
|
||||
// there are new events to be sent out.
|
||||
eventCount := 0
|
||||
|
||||
m := sync.Mutex{}
|
||||
|
@ -64,6 +68,15 @@ func SetupAppServiceAPIComponent(
|
|||
EventsReady: &eventCount,
|
||||
}
|
||||
workerStates = append(workerStates, ws)
|
||||
|
||||
// Generate a dummy account using the `sender_localpart` field for each
|
||||
// application service. An application service will masquerade as this user if
|
||||
// they do not provide a `user_id` during a request.
|
||||
err := generateAppServiceAccount(accountsDB, deviceDB, appservice)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Panicf("unable to register appservice %s",
|
||||
appservice.ID)
|
||||
}
|
||||
}
|
||||
|
||||
// Create a HTTP client that this component will use for all outbound and
|
||||
|
@ -100,3 +113,31 @@ func SetupAppServiceAPIComponent(
|
|||
|
||||
return &appserviceQueryAPI
|
||||
}
|
||||
|
||||
// generateAppServiceAccounts creates a dummy account based off the
|
||||
// `sender_localpart` field of each application service if it doesn't
|
||||
// exist already
|
||||
func generateAppServiceAccount(
|
||||
accountsDB *accounts.Database,
|
||||
deviceDB *devices.Database,
|
||||
as config.ApplicationService,
|
||||
) error {
|
||||
ctx := context.Background()
|
||||
|
||||
// Create an account for the application service
|
||||
acc, err := accountsDB.CreateAccount(ctx, as.SenderLocalpart, "", as.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if acc == nil {
|
||||
// This account already exists
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create a dummy device with a dummy token for the application service
|
||||
_, err = deviceDB.CreateDevice(ctx, as.SenderLocalpart, nil, as.ASToken, &as.SenderLocalpart)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ package storage
|
|||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
|
@ -174,9 +175,18 @@ func retrieveEvents(eventRows *sql.Rows) (events []gomatrixserverlib.Application
|
|||
maxID = id
|
||||
}
|
||||
|
||||
// Get age of the event from original timestamp and current time
|
||||
// TODO: Consider removing age as not many app services use it
|
||||
event.Age = nowMilli - event.OriginServerTimestamp
|
||||
// unsigned portion of a application service event
|
||||
unsigned := gomatrixserverlib.ApplicationServiceUnsigned{
|
||||
// Age of the event from original timestamp and current time TODO: Consider
|
||||
// removing age as not many app services use it
|
||||
Age: nowMilli - event.OriginServerTimestamp,
|
||||
}
|
||||
|
||||
unsignedJSON, err := json.Marshal(unsigned)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
event.Unsigned = gomatrixserverlib.RawJSON(unsignedJSON)
|
||||
|
||||
// TODO: Synapse does this. It's unnecessary to send Sender and UserID as the
|
||||
// same value. Do app services really require this? :)
|
||||
|
|
|
@ -217,8 +217,14 @@ func send(
|
|||
transaction []byte,
|
||||
) error {
|
||||
// POST a transaction to our AS
|
||||
address := fmt.Sprintf("%s/transactions/%d", appservice.URL, txnID)
|
||||
resp, err := client.Post(address, "application/json", bytes.NewBuffer(transaction))
|
||||
address := fmt.Sprintf("%s/transactions/%d?access_token=%s", appservice.URL, txnID, appservice.HSToken)
|
||||
req, err := http.NewRequest(http.MethodPut, address, bytes.NewBuffer(transaction))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -90,14 +90,6 @@ func VerifyUserFromRequest(
|
|||
}
|
||||
|
||||
if appService != nil {
|
||||
// Create a dummy device for AS user
|
||||
dev := authtypes.Device{
|
||||
// Use AS dummy device ID
|
||||
ID: types.AppServiceDeviceID,
|
||||
// AS dummy device has AS's token.
|
||||
AccessToken: token,
|
||||
}
|
||||
|
||||
userID := req.URL.Query().Get("user_id")
|
||||
localpart, err := userutil.ParseUsernameParam(userID, nil)
|
||||
if err != nil {
|
||||
|
@ -107,25 +99,28 @@ func VerifyUserFromRequest(
|
|||
}
|
||||
}
|
||||
|
||||
if localpart != "" { // AS is masquerading as another user
|
||||
// Verify that the user is registered
|
||||
account, err := data.AccountDB.GetAccountByLocalpart(req.Context(), localpart)
|
||||
// Verify that account exists & appServiceID matches
|
||||
if err == nil && account.AppServiceID == appService.ID {
|
||||
// Set the userID of dummy device
|
||||
dev.UserID = userID
|
||||
return &dev, nil
|
||||
// Verify that the user is registered
|
||||
account, err := data.AccountDB.GetAccountByLocalpart(req.Context(), localpart)
|
||||
|
||||
// Verify that account exists & appServiceID matches
|
||||
if err == nil && account.AppServiceID == appService.ID {
|
||||
// Create a dummy device for AS user
|
||||
dev := authtypes.Device{
|
||||
// Use AS dummy device ID
|
||||
ID: types.AppServiceDeviceID,
|
||||
// User the AS is masquerading as.
|
||||
UserID: userID,
|
||||
// AS dummy device has AS's token.
|
||||
AccessToken: token,
|
||||
}
|
||||
|
||||
return nil, &util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
JSON: jsonerror.Forbidden("Application service has not registered this user"),
|
||||
}
|
||||
return &dev, nil
|
||||
}
|
||||
|
||||
// AS is not masquerading as any user, so use AS's sender_localpart
|
||||
dev.UserID = appService.SenderLocalpart
|
||||
return &dev, nil
|
||||
return nil, &util.JSONResponse{
|
||||
Code: http.StatusForbidden,
|
||||
JSON: jsonerror.Forbidden("Application service has not registered this user"),
|
||||
}
|
||||
}
|
||||
|
||||
return nil, &util.JSONResponse{
|
||||
|
|
|
@ -56,7 +56,7 @@ func main() {
|
|||
|
||||
alias, input, query := roomserver.SetupRoomServerComponent(base)
|
||||
asQuery := appservice.SetupAppServiceAPIComponent(
|
||||
base, accountDB, federation, alias, query, transactions.New(),
|
||||
base, accountDB, deviceDB, federation, alias, query, transactions.New(),
|
||||
)
|
||||
|
||||
clientapi.SetupClientAPIComponent(
|
||||
|
|
|
@ -15,10 +15,16 @@
|
|||
|
||||
package gomatrixserverlib
|
||||
|
||||
// ApplicationServiceUnsigned is the contents of the unsigned field of an
|
||||
// ApplicationServiceEvent
|
||||
type ApplicationServiceUnsigned struct {
|
||||
Age int64 `json:"age,omitempty"`
|
||||
}
|
||||
|
||||
// ApplicationServiceEvent is an event format that is sent off to an
|
||||
// application service as part of a transaction.
|
||||
type ApplicationServiceEvent struct {
|
||||
Age int64 `json:"age,omitempty"`
|
||||
Unsigned RawJSON `json:"unsigned,omitempty"`
|
||||
Content RawJSON `json:"content,omitempty"`
|
||||
EventID string `json:"event_id,omitempty"`
|
||||
OriginServerTimestamp int64 `json:"origin_server_ts,omitempty"`
|
||||
|
|
Loading…
Reference in a new issue