Compare commits

...

18 commits

Author SHA1 Message Date
signaryk 73bd01f7b6 Forgejo does not support build cache
All checks were successful
/ Monolith image (push) Successful in 2m0s
2024-07-14 17:26:53 -05:00
signaryk 6a9a344d9a Try changing namespace to user
Some checks failed
/ Monolith image (push) Failing after 2m34s
2024-07-14 17:22:57 -05:00
signaryk 64cad580d1 Build cache bit was wrong
Some checks failed
/ Monolith image (push) Failing after 2m33s
2024-07-14 17:17:01 -05:00
signaryk 48e3701b85 Remove condition for main image build step
Some checks failed
/ Monolith image (push) Failing after 2m50s
2024-07-14 17:12:31 -05:00
signaryk 0c22b9ea58 Revert to smaller image
All checks were successful
/ Monolith image (push) Successful in 20s
2024-07-14 17:10:25 -05:00
signaryk d428ae7f62 Remove QEMU step, not actually using it
Some checks failed
/ Monolith image (push) Failing after 14s
2024-07-14 16:04:32 -05:00
signaryk b86c5110e1 Try the full clone of github actions container
Some checks failed
/ Monolith image (push) Failing after 11m56s
2024-07-14 15:40:03 -05:00
signaryk 09587775df Change the image for one compatible with docker builds
Some checks failed
/ Monolith image (push) Failing after 40s
2024-07-14 15:29:34 -05:00
signaryk af0eadd4fe Fix different image format for actions yaml
Some checks failed
/ Monolith image (push) Failing after 13s
2024-07-14 15:05:33 -05:00
signaryk 5f187e42d3 More actions updates
Some checks failed
/ Monolith image (push) Failing after 1m32s
2024-07-14 14:59:49 -05:00
signaryk 77264c3c20 Fix actions 2024-07-14 14:54:42 -05:00
signaryk a595be09a2 Add forgejo actions 2024-07-14 14:45:20 -05:00
signaryk 0bfe418b18 Update gitignore 2024-07-14 14:43:46 -05:00
Boris Rybalkin 20aa36ada7 go tidy
Some checks failed
Dendrite / WASM build test (push) Has been cancelled
Dendrite / Linting (push) Has been cancelled
Dendrite / Unit tests (push) Has been cancelled
Dendrite / Build for Linux (386, linux) (push) Has been cancelled
Dendrite / Build for Linux (amd64, linux) (push) Has been cancelled
Dendrite / Build for Windows (amd64, windows) (push) Has been cancelled
Dendrite / Initial tests passed (push) Has been cancelled
Dendrite / Integration tests (push) Has been cancelled
Dendrite / Upgrade tests (push) Has been cancelled
Dendrite / Upgrade tests from HEAD-2 (push) Has been cancelled
Dendrite / Sytest (${{ matrix.label }}) (1, SQLite Cgo) (push) Has been cancelled
Dendrite / Sytest (${{ matrix.label }}) (PostgreSQL, postgres) (push) Has been cancelled
Dendrite / Sytest (${{ matrix.label }}) (SQLite native) (push) Has been cancelled
Dendrite / Complement (${{ matrix.label }}) (0, PostgreSQL, Postgres) (push) Has been cancelled
Dendrite / Complement (${{ matrix.label }}) (0, SQLite native) (push) Has been cancelled
Dendrite / Complement (${{ matrix.label }}) (1, SQLite Cgo) (push) Has been cancelled
Dendrite / Integration tests passed (push) Has been cancelled
Dendrite / Update Docker images (push) Has been cancelled
2024-07-10 20:31:35 -05:00
Boris Rybalkin f9c6fbab69 basic ldap authentication support 2024-07-10 20:31:27 -05:00
Richard van der Hoff 3e62b986d1
Blacklist sytests that require MSC3967 (#3384)
https://github.com/matrix-org/sytest/pull/1383 updates some sytests in
line with MSC3967. Dendrite does not support MSC3967, so these tests
fail.
2024-06-13 23:55:02 +00:00
0x1a8510f2 46902e5766
Take advantage of changes in recent Go versions (#3361)
Given that #2714 wasn't merged but we are now at a minimum supported Go
version of 1.20 (soon to be 1.21), I wanted to carry over some of the
changes. Namely:
- Fix the log typo
- Simplify build constraints for unix
- Use stdlib atomic package

### Pull Request Checklist

<!-- Please read
https://matrix-org.github.io/dendrite/development/contributing before
submitting your pull request -->

* [x] I have added Go unit tests or [Complement integration
tests](https://github.com/matrix-org/complement) for this PR _or_ I have
justified why this PR doesn't need tests
* [x] Pull request includes a [sign off below using a legally
identifiable
name](https://matrix-org.github.io/dendrite/development/contributing#sign-off)
_or_ I have already signed off privately

Signed-off-by: `0x1a8510f2 <admin@0x1a8510f2.space>`

---------

Co-authored-by: devonh <devon.dmytro@gmail.com>
2024-05-01 00:38:36 +00:00
dependabot[bot] 5547bf8ca6
Bump golang.org/x/net from 0.21.0 to 0.23.0 (#3365)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.21.0 to
0.23.0.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="c48da13158"><code>c48da13</code></a>
http2: fix TestServerContinuationFlood flakes</li>
<li><a
href="762b58d1cf"><code>762b58d</code></a>
http2: fix tipos in comment</li>
<li><a
href="ba872109ef"><code>ba87210</code></a>
http2: close connections when receiving too many headers</li>
<li><a
href="ebc8168ac8"><code>ebc8168</code></a>
all: fix some typos</li>
<li><a
href="3678185f8a"><code>3678185</code></a>
http2: make TestCanonicalHeaderCacheGrowth faster</li>
<li><a
href="448c44f928"><code>448c44f</code></a>
http2: remove clientTester</li>
<li><a
href="c7877ac421"><code>c7877ac</code></a>
http2: convert the remaining clientTester tests to testClientConn</li>
<li><a
href="d8870b0bf2"><code>d8870b0</code></a>
http2: use synthetic time in TestIdleConnTimeout</li>
<li><a
href="d73acffdc9"><code>d73acff</code></a>
http2: only set up deadline when Server.IdleTimeout is positive</li>
<li><a
href="89f602b7bb"><code>89f602b</code></a>
http2: validate client/outgoing trailers</li>
<li>Additional commits viewable in <a
href="https://github.com/golang/net/compare/v0.21.0...v0.23.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=golang.org/x/net&package-manager=go_modules&previous-version=0.21.0&new-version=0.23.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/matrix-org/dendrite/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-30 23:12:52 +00:00
24 changed files with 324 additions and 65 deletions

View file

@ -0,0 +1,59 @@
on:
push:
tags:
- 'v*'
env:
GHCR_NAMESPACE: sigb.us
PLATFORMS: linux/amd64
FORGEJO_USER: signaryk
jobs:
monolith:
name: Monolith image
runs-on: docker
container:
image: ghcr.io/catthehacker/ubuntu:act-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Get release tag & build flags
if: github.event_name == 'release' # Only for GitHub releases
run: |
echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to sigb.us container registry
uses: docker/login-action@v3
with:
registry: git.sigb.us
username: ${{ env.FORGEJO_USER }}
password: ${{ secrets.FORGEJO_TOKEN }}
- name: Build main monolith image
id: docker_build_monolith
uses: docker/build-push-action@v3
with:
context: .
platforms: ${{ env.PLATFORMS }}
push: true
tags: |
git.sigb.us/${{ env.GHCR_NAMESPACE }}/dendrite:${{ github.ref_name }}
git.sigb.us/${{ env.GHCR_NAMESPACE }}/dendrite:latest
git.sigb.us/${{ env.GHCR_NAMESPACE }}/dendrite:devel
- name: Build release monolith image
if: github.event_name == 'release' # Only for GitHub releases
id: docker_build_monolith_release
uses: docker/build-push-action@v3
with:
context: .
platforms: ${{ env.PLATFORMS }}
push: true
tags: |
git.sigb.us/${{ env.GHCR_NAMESPACE }}/dendrite:latest
git.sigb.us/${{ env.GHCR_NAMESPACE }}/dendrite:stable
git.sigb.us/${{ env.GHCR_NAMESPACE }}/dendrite:${{ env.RELEASE_VERSION }}

1
.gitignore vendored
View file

@ -5,6 +5,7 @@
# Allow GitHub config
!.github
!.forgejo
# Downloads
/.downloads

View file

@ -61,7 +61,7 @@ func LoginFromJSONReader(
switch header.Type {
case authtypes.LoginTypePassword:
typ = &LoginTypePassword{
GetAccountByPassword: useraccountAPI.QueryAccountByPassword,
UserAPI: useraccountAPI,
Config: cfg,
}
case authtypes.LoginTypeToken:

View file

@ -292,6 +292,14 @@ func (ua *fakeUserInternalAPI) QueryAccountByPassword(ctx context.Context, req *
return nil
}
func (ua *fakeUserInternalAPI) QueryAccountByLocalpart(ctx context.Context, req *uapi.QueryAccountByLocalpartRequest, res *uapi.QueryAccountByLocalpartResponse) error {
return nil
}
func (ua *fakeUserInternalAPI) PerformAccountCreation(ctx context.Context, req *uapi.PerformAccountCreationRequest, res *uapi.PerformAccountCreationResponse) error {
return nil
}
func (ua *fakeUserInternalAPI) PerformLoginTokenDeletion(ctx context.Context, req *uapi.PerformLoginTokenDeletionRequest, res *uapi.PerformLoginTokenDeletionResponse) error {
ua.DeletedTokens = append(ua.DeletedTokens, req.Token)
return nil

View file

@ -16,6 +16,9 @@ package auth
import (
"context"
"database/sql"
"github.com/go-ldap/ldap/v3"
"github.com/google/uuid"
"net/http"
"strings"
@ -28,8 +31,6 @@ import (
"github.com/matrix-org/util"
)
type GetAccountByPassword func(ctx context.Context, req *api.QueryAccountByPasswordRequest, res *api.QueryAccountByPasswordResponse) error
type PasswordRequest struct {
Login
Password string `json:"password"`
@ -37,8 +38,8 @@ type PasswordRequest struct {
// LoginTypePassword implements https://matrix.org/docs/spec/client_server/r0.6.1#password-based
type LoginTypePassword struct {
GetAccountByPassword GetAccountByPassword
Config *config.ClientAPI
UserAPI api.UserLoginAPI
}
func (t *LoginTypePassword) Name() string {
@ -59,22 +60,21 @@ func (t *LoginTypePassword) LoginFromJSON(ctx context.Context, reqBytes []byte)
return login, func(context.Context, *util.JSONResponse) {}, nil
}
func (t *LoginTypePassword) Login(ctx context.Context, req interface{}) (*Login, *util.JSONResponse) {
r := req.(*PasswordRequest)
username := r.Username()
if username == "" {
func (t *LoginTypePassword) Login(ctx context.Context, request *PasswordRequest) (*Login, *util.JSONResponse) {
fullUsername := request.Username()
if fullUsername == "" {
return nil, &util.JSONResponse{
Code: http.StatusUnauthorized,
JSON: spec.BadJSON("A username must be supplied."),
}
}
if len(r.Password) == 0 {
if len(request.Password) == 0 {
return nil, &util.JSONResponse{
Code: http.StatusUnauthorized,
JSON: spec.BadJSON("A password must be supplied."),
}
}
localpart, domain, err := userutil.ParseUsernameParam(username, t.Config.Matrix)
username, domain, err := userutil.ParseUsernameParam(fullUsername, t.Config.Matrix)
if err != nil {
return nil, &util.JSONResponse{
Code: http.StatusUnauthorized,
@ -87,12 +87,38 @@ func (t *LoginTypePassword) Login(ctx context.Context, req interface{}) (*Login,
JSON: spec.InvalidUsername("The server name is not known."),
}
}
// Squash username to all lowercase letters
var account *api.Account
if t.Config.Ldap.Enabled {
isAdmin, err := t.authenticateLdap(username, request.Password)
if err != nil {
return nil, err
}
acc, err := t.getOrCreateAccount(ctx, username, domain, isAdmin)
if err != nil {
return nil, err
}
account = acc
} else {
acc, err := t.authenticateDb(ctx, username, domain, request.Password)
if err != nil {
return nil, err
}
account = acc
}
// Set the user, so login.Username() can do the right thing
request.Identifier.User = account.UserID
request.User = account.UserID
return &request.Login, nil
}
func (t *LoginTypePassword) authenticateDb(ctx context.Context, username string, domain spec.ServerName, password string) (*api.Account, *util.JSONResponse) {
res := &api.QueryAccountByPasswordResponse{}
err = t.GetAccountByPassword(ctx, &api.QueryAccountByPasswordRequest{
Localpart: strings.ToLower(localpart),
err := t.UserAPI.QueryAccountByPassword(ctx, &api.QueryAccountByPasswordRequest{
Localpart: strings.ToLower(username),
ServerName: domain,
PlaintextPassword: r.Password,
PlaintextPassword: password,
}, res)
if err != nil {
return nil, &util.JSONResponse{
@ -101,13 +127,11 @@ func (t *LoginTypePassword) Login(ctx context.Context, req interface{}) (*Login,
}
}
// If we couldn't find the user by the lower cased localpart, try the provided
// localpart as is.
if !res.Exists {
err = t.GetAccountByPassword(ctx, &api.QueryAccountByPasswordRequest{
Localpart: localpart,
err = t.UserAPI.QueryAccountByPassword(ctx, &api.QueryAccountByPasswordRequest{
Localpart: username,
ServerName: domain,
PlaintextPassword: r.Password,
PlaintextPassword: password,
}, res)
if err != nil {
return nil, &util.JSONResponse{
@ -115,8 +139,6 @@ func (t *LoginTypePassword) Login(ctx context.Context, req interface{}) (*Login,
JSON: spec.Unknown("Unable to fetch account by password."),
}
}
// Technically we could tell them if the user does not exist by checking if err == sql.ErrNoRows
// but that would leak the existence of the user.
if !res.Exists {
return nil, &util.JSONResponse{
Code: http.StatusForbidden,
@ -124,8 +146,141 @@ func (t *LoginTypePassword) Login(ctx context.Context, req interface{}) (*Login,
}
}
}
// Set the user, so login.Username() can do the right thing
r.Identifier.User = res.Account.UserID
r.User = res.Account.UserID
return &r.Login, nil
return res.Account, nil
}
func (t *LoginTypePassword) authenticateLdap(username, password string) (bool, *util.JSONResponse) {
var conn *ldap.Conn
conn, err := ldap.DialURL(t.Config.Ldap.Uri)
if err != nil {
return false, &util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.Unknown("unable to connect to ldap: " + err.Error()),
}
}
defer conn.Close()
if t.Config.Ldap.AdminBindEnabled {
err = conn.Bind(t.Config.Ldap.AdminBindDn, t.Config.Ldap.AdminBindPassword)
if err != nil {
return false, &util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.Unknown("unable to bind to ldap: " + err.Error()),
}
}
filter := strings.ReplaceAll(t.Config.Ldap.SearchFilter, "{username}", username)
searchRequest := ldap.NewSearchRequest(
t.Config.Ldap.BaseDn, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases,
0, 0, false, filter, []string{t.Config.Ldap.SearchAttribute}, nil,
)
result, err := conn.Search(searchRequest)
if err != nil {
return false, &util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.Unknown("unable to bind to search ldap: " + err.Error()),
}
}
if len(result.Entries) > 1 {
return false, &util.JSONResponse{
Code: http.StatusUnauthorized,
JSON: spec.BadJSON("'user' must be duplicated."),
}
}
if len(result.Entries) < 1 {
return false, &util.JSONResponse{
Code: http.StatusUnauthorized,
JSON: spec.BadJSON("'user' not found."),
}
}
userDN := result.Entries[0].DN
err = conn.Bind(userDN, password)
if err != nil {
return false, &util.JSONResponse{
Code: http.StatusUnauthorized,
JSON: spec.InvalidUsername(err.Error()),
}
}
} else {
bindDn := strings.ReplaceAll(t.Config.Ldap.UserBindDn, "{username}", username)
err = conn.Bind(bindDn, password)
if err != nil {
return false, &util.JSONResponse{
Code: http.StatusUnauthorized,
JSON: spec.InvalidUsername(err.Error()),
}
}
}
isAdmin, err := t.isLdapAdmin(conn, username)
if err != nil {
return false, &util.JSONResponse{
Code: http.StatusUnauthorized,
JSON: spec.InvalidUsername(err.Error()),
}
}
return isAdmin, nil
}
func (t *LoginTypePassword) isLdapAdmin(conn *ldap.Conn, username string) (bool, error) {
searchRequest := ldap.NewSearchRequest(
t.Config.Ldap.AdminGroupDn,
ldap.ScopeWholeSubtree, ldap.DerefAlways, 0, 0, false,
strings.ReplaceAll(t.Config.Ldap.AdminGroupFilter, "{username}", username),
[]string{t.Config.Ldap.AdminGroupAttribute},
nil)
sr, err := conn.Search(searchRequest)
if err != nil {
return false, err
}
if len(sr.Entries) < 1 {
return false, nil
}
return true, nil
}
func (t *LoginTypePassword) getOrCreateAccount(ctx context.Context, username string, domain spec.ServerName, admin bool) (*api.Account, *util.JSONResponse) {
var existing api.QueryAccountByLocalpartResponse
err := t.UserAPI.QueryAccountByLocalpart(ctx, &api.QueryAccountByLocalpartRequest{
Localpart: username,
ServerName: domain,
}, &existing)
if err == nil {
return existing.Account, nil
}
if err != sql.ErrNoRows {
return nil, &util.JSONResponse{
Code: http.StatusUnauthorized,
JSON: spec.InvalidUsername(err.Error()),
}
}
accountType := api.AccountTypeUser
if admin {
accountType = api.AccountTypeAdmin
}
var created api.PerformAccountCreationResponse
err = t.UserAPI.PerformAccountCreation(ctx, &api.PerformAccountCreationRequest{
AppServiceID: "ldap",
Localpart: username,
Password: uuid.New().String(),
AccountType: accountType,
OnConflict: api.ConflictAbort,
}, &created)
if err != nil {
if _, ok := err.(*api.ErrorConflict); ok {
return nil, &util.JSONResponse{
Code: http.StatusBadRequest,
JSON: spec.UserInUse("Desired user ID is already taken."),
}
}
return nil, &util.JSONResponse{
Code: http.StatusInternalServerError,
JSON: spec.Unknown("failed to create account: " + err.Error()),
}
}
return created.Account, nil
}

View file

@ -113,7 +113,7 @@ type UserInteractive struct {
func NewUserInteractive(userAccountAPI api.UserLoginAPI, cfg *config.ClientAPI) *UserInteractive {
typePassword := &LoginTypePassword{
GetAccountByPassword: userAccountAPI.QueryAccountByPassword,
UserAPI: userAccountAPI,
Config: cfg,
}
return &UserInteractive{

View file

@ -45,6 +45,14 @@ func (d *fakeAccountDatabase) QueryAccountByPassword(ctx context.Context, req *a
return nil
}
func (d *fakeAccountDatabase) QueryAccountByLocalpart(ctx context.Context, req *api.QueryAccountByLocalpartRequest, res *api.QueryAccountByLocalpartResponse) error {
return nil
}
func (d *fakeAccountDatabase) PerformAccountCreation(ctx context.Context, req *api.PerformAccountCreationRequest, res *api.PerformAccountCreationResponse) error {
return nil
}
func setup() *UserInteractive {
cfg := &config.ClientAPI{
Matrix: &config.Global{

View file

@ -32,7 +32,7 @@ type crossSigningRequest struct {
}
func UploadCrossSigningDeviceKeys(
req *http.Request, userInteractiveAuth *auth.UserInteractive,
req *http.Request,
keyserverAPI api.ClientKeyAPI, device *api.Device,
accountAPI api.ClientUserAPI, cfg *config.ClientAPI,
) util.JSONResponse {
@ -62,7 +62,7 @@ func UploadCrossSigningDeviceKeys(
}
}
typePassword := auth.LoginTypePassword{
GetAccountByPassword: accountAPI.QueryAccountByPassword,
UserAPI: accountAPI,
Config: cfg,
}
if _, authErr := typePassword.Login(req.Context(), &uploadReq.Auth.PasswordRequest); authErr != nil {

View file

@ -73,7 +73,7 @@ func Password(
// Check if the existing password is correct.
typePassword := auth.LoginTypePassword{
GetAccountByPassword: userAPI.QueryAccountByPassword,
UserAPI: userAPI,
Config: cfg,
}
if _, authErr := typePassword.Login(req.Context(), &r.Auth.PasswordRequest); authErr != nil {

View file

@ -255,7 +255,7 @@ func Setup(
logrus.Info("Enabling server notices at /_synapse/admin/v1/send_server_notice")
serverNotificationSender, err := getSenderDevice(context.Background(), rsAPI, userAPI, cfg)
if err != nil {
logrus.WithError(err).Fatal("unable to get account for sending sending server notices")
logrus.WithError(err).Fatal("unable to get account for sending server notices")
}
synapseAdminRouter.Handle("/admin/v1/send_server_notice/{txnID}",
@ -1448,7 +1448,7 @@ func Setup(
// Cross-signing device keys
postDeviceSigningKeys := httputil.MakeAuthAPI("post_device_signing_keys", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {
return UploadCrossSigningDeviceKeys(req, userInteractiveAuth, userAPI, device, userAPI, cfg)
return UploadCrossSigningDeviceKeys(req, userAPI, device, userAPI, cfg)
})
postDeviceSigningSignatures := httputil.MakeAuthAPI("post_device_signing_signatures", userAPI, func(req *http.Request, device *userapi.Device) util.JSONResponse {

View file

@ -17,13 +17,13 @@ package relay
import (
"context"
"sync"
"sync/atomic"
"time"
federationAPI "github.com/matrix-org/dendrite/federationapi/api"
relayServerAPI "github.com/matrix-org/dendrite/relayapi/api"
"github.com/matrix-org/gomatrixserverlib/spec"
"github.com/sirupsen/logrus"
"go.uber.org/atomic"
)
const (
@ -54,7 +54,7 @@ func NewRelayServerRetriever(
federationAPI: federationAPI,
relayAPI: relayAPI,
relayServersQueried: make(map[spec.ServerName]bool),
running: *atomic.NewBool(false),
running: atomic.Bool{},
quit: quit,
}
}

View file

@ -19,6 +19,7 @@ import (
"encoding/json"
"fmt"
"sync"
"sync/atomic"
"time"
"github.com/matrix-org/gomatrix"
@ -26,7 +27,6 @@ import (
"github.com/matrix-org/gomatrixserverlib/fclient"
"github.com/matrix-org/gomatrixserverlib/spec"
"github.com/sirupsen/logrus"
"go.uber.org/atomic"
"github.com/matrix-org/dendrite/federationapi/statistics"
"github.com/matrix-org/dendrite/federationapi/storage"

View file

@ -18,6 +18,7 @@ import (
"context"
"encoding/json"
"fmt"
"sync/atomic"
"testing"
"time"
@ -26,7 +27,6 @@ import (
"github.com/matrix-org/dendrite/test/testrig"
"github.com/matrix-org/gomatrixserverlib/fclient"
"github.com/matrix-org/gomatrixserverlib/spec"
"go.uber.org/atomic"
"gotest.tools/v3/poll"
"github.com/matrix-org/gomatrixserverlib"
@ -113,8 +113,8 @@ func testSetup(failuresUntilBlacklist uint32, failuresUntilAssumedOffline uint32
fc := &stubFederationClient{
shouldTxSucceed: shouldTxSucceed,
shouldTxRelaySucceed: shouldTxRelaySucceed,
txCount: *atomic.NewUint32(0),
txRelayCount: *atomic.NewUint32(0),
txCount: atomic.Uint32{},
txRelayCount: atomic.Uint32{},
}
stats := statistics.NewStatistics(db, failuresUntilBlacklist, failuresUntilAssumedOffline, false)

View file

@ -5,10 +5,10 @@ import (
"math"
"math/rand"
"sync"
"sync/atomic"
"time"
"github.com/sirupsen/logrus"
"go.uber.org/atomic"
"github.com/matrix-org/dendrite/federationapi/storage"
"github.com/matrix-org/gomatrixserverlib/spec"
@ -169,7 +169,7 @@ func (s *ServerStatistics) Success(method SendMethod) {
// NOTE : Sending to the final destination vs. a relay server has
// slightly different semantics.
if method == SendDirect {
s.successCounter.Inc()
s.successCounter.Add(1)
if s.blacklisted.Load() && s.statistics.DB != nil {
if err := s.statistics.DB.RemoveServerFromBlacklist(s.serverName); err != nil {
logrus.WithError(err).Errorf("Failed to remove %q from blacklist", s.serverName)
@ -195,7 +195,7 @@ func (s *ServerStatistics) Failure() (time.Time, bool) {
// start a goroutine which will wait out the backoff and
// unset the backoffStarted flag when done.
if s.backoffStarted.CompareAndSwap(false, true) {
backoffCount := s.backoffCount.Inc()
backoffCount := s.backoffCount.Add(1)
if backoffCount >= s.statistics.FailuresUntilAssumedOffline {
s.assumedOffline.CompareAndSwap(false, true)

5
go.mod
View file

@ -12,6 +12,7 @@ require (
github.com/docker/docker v24.0.9+incompatible
github.com/docker/go-connections v0.4.0
github.com/getsentry/sentry-go v0.14.0
github.com/go-ldap/ldap/v3 v3.4.4
github.com/gologme/log v1.3.0
github.com/google/go-cmp v0.6.0
github.com/google/uuid v1.3.0
@ -57,6 +58,7 @@ require (
)
require (
github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e // indirect
github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect
github.com/Microsoft/go-winio v0.5.2 // indirect
github.com/RoaringBitmap/roaring v1.2.3 // indirect
@ -84,6 +86,7 @@ require (
github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 // indirect
@ -124,7 +127,7 @@ require (
github.com/tidwall/pretty v1.2.1 // indirect
go.etcd.io/bbolt v1.3.7 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.21.0 // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect

13
go.sum
View file

@ -5,6 +5,8 @@ github.com/Arceliar/phony v0.0.0-20210209235338-dde1a8dca979 h1:WndgpSW13S32VLQ3
github.com/Arceliar/phony v0.0.0-20210209235338-dde1a8dca979/go.mod h1:6Lkn+/zJilRMsKmbmG1RPoamiArC6HS73xbwRyp3UyI=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e h1:NeAW1fUYUEWhft7pkxDf6WoUvEZJ/uOKsvtpjLnn8MU=
github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
@ -115,8 +117,12 @@ github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwv
github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
github.com/glycerine/goconvey v0.0.0-20180728074245-46e3a41ad493/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A=
github.com/go-asn1-ber/asn1-ber v1.5.4/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-ldap/ldap/v3 v3.4.4 h1:qPjipEpt+qDa6SI/h1fzuGWoRUY+qqQ9sOZq67/PYUs=
github.com/go-ldap/ldap/v3 v3.4.4/go.mod h1:fe1MsuN5eJJ1FeLT/LEBVdWfNWKh459R7aXgXtJC+aI=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
@ -383,10 +389,11 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -406,6 +413,7 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -427,6 +435,7 @@ golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=

View file

@ -3,8 +3,7 @@ package sqlutil
import (
"database/sql"
"errors"
"go.uber.org/atomic"
"sync/atomic"
)
// ExclusiveWriter implements sqlutil.Writer.

View file

@ -19,6 +19,7 @@ import (
"encoding/json"
"fmt"
"strconv"
"sync/atomic"
"testing"
"time"
@ -26,7 +27,6 @@ import (
"github.com/matrix-org/gomatrixserverlib/spec"
"github.com/nats-io/nats.go"
"github.com/stretchr/testify/assert"
"go.uber.org/atomic"
"gotest.tools/v3/poll"
"github.com/matrix-org/dendrite/federationapi/producers"
@ -228,7 +228,7 @@ func TestProcessTransactionRequestEDUTyping(t *testing.T) {
ctx := process.NewProcessContext()
defer ctx.ShutdownDendrite()
txn, js, cfg := createTransactionWithEDU(ctx, edus)
received := atomic.NewBool(false)
received := atomic.Bool{}
onMessage := func(ctx context.Context, msgs []*nats.Msg) bool {
msg := msgs[0] // Guaranteed to exist if onMessage is called
room := msg.Header.Get(jetstream.RoomID)
@ -294,7 +294,7 @@ func TestProcessTransactionRequestEDUToDevice(t *testing.T) {
ctx := process.NewProcessContext()
defer ctx.ShutdownDendrite()
txn, js, cfg := createTransactionWithEDU(ctx, edus)
received := atomic.NewBool(false)
received := atomic.Bool{}
onMessage := func(ctx context.Context, msgs []*nats.Msg) bool {
msg := msgs[0] // Guaranteed to exist if onMessage is called
@ -371,7 +371,7 @@ func TestProcessTransactionRequestEDUDeviceListUpdate(t *testing.T) {
ctx := process.NewProcessContext()
defer ctx.ShutdownDendrite()
txn, js, cfg := createTransactionWithEDU(ctx, edus)
received := atomic.NewBool(false)
received := atomic.Bool{}
onMessage := func(ctx context.Context, msgs []*nats.Msg) bool {
msg := msgs[0] // Guaranteed to exist if onMessage is called
@ -468,7 +468,7 @@ func TestProcessTransactionRequestEDUReceipt(t *testing.T) {
ctx := process.NewProcessContext()
defer ctx.ShutdownDendrite()
txn, js, cfg := createTransactionWithEDU(ctx, edus)
received := atomic.NewBool(false)
received := atomic.Bool{}
onMessage := func(ctx context.Context, msgs []*nats.Msg) bool {
msg := msgs[0] // Guaranteed to exist if onMessage is called
@ -512,7 +512,7 @@ func TestProcessTransactionRequestEDUSigningKeyUpdate(t *testing.T) {
ctx := process.NewProcessContext()
defer ctx.ShutdownDendrite()
txn, js, cfg := createTransactionWithEDU(ctx, edus)
received := atomic.NewBool(false)
received := atomic.Bool{}
onMessage := func(ctx context.Context, msgs []*nats.Msg) bool {
msg := msgs[0] // Guaranteed to exist if onMessage is called
@ -569,7 +569,7 @@ func TestProcessTransactionRequestEDUPresence(t *testing.T) {
ctx := process.NewProcessContext()
defer ctx.ShutdownDendrite()
txn, js, cfg := createTransactionWithEDU(ctx, edus)
received := atomic.NewBool(false)
received := atomic.Bool{}
onMessage := func(ctx context.Context, msgs []*nats.Msg) bool {
msg := msgs[0] // Guaranteed to exist if onMessage is called

View file

@ -28,13 +28,13 @@ import (
_ "net/http/pprof"
"os"
"os/signal"
"sync/atomic"
"syscall"
"time"
sentryhttp "github.com/getsentry/sentry-go/http"
"github.com/matrix-org/gomatrixserverlib/fclient"
"github.com/prometheus/client_golang/prometheus/promhttp"
"go.uber.org/atomic"
"github.com/gorilla/mux"
"github.com/kardianos/minwinsvc"

View file

@ -1,5 +1,5 @@
//go:build !linux && !darwin && !netbsd && !freebsd && !openbsd && !solaris && !dragonfly && !aix
// +build !linux,!darwin,!netbsd,!freebsd,!openbsd,!solaris,!dragonfly,!aix
//go:build !unix
// +build !unix
package base

View file

@ -1,5 +1,5 @@
//go:build linux || darwin || netbsd || freebsd || openbsd || solaris || dragonfly || aix
// +build linux darwin netbsd freebsd openbsd solaris dragonfly aix
//go:build unix
// +build unix
package base

View file

@ -56,9 +56,26 @@ type ClientAPI struct {
RateLimiting RateLimiting `yaml:"rate_limiting"`
MSCs *MSCs `yaml:"-"`
Ldap Ldap `yaml:"ldap"`
}
func (c *ClientAPI) Defaults(opts DefaultOpts) {
type Ldap struct {
Enabled bool `yaml:"enabled"`
Uri string `yaml:"uri"`
BaseDn string `yaml:"base_dn"`
SearchFilter string `yaml:"search_filter"`
SearchAttribute string `yaml:"search_attribute"`
AdminBindEnabled bool `yaml:"admin_bind_enabled"`
AdminBindDn string `yaml:"admin_bind_dn"`
AdminBindPassword string `yaml:"admin_bind_password"`
UserBindDn string `yaml:"user_bind_dn"`
AdminGroupDn string `yaml:"admin_group_dn"`
AdminGroupFilter string `yaml:"admin_group_filter"`
AdminGroupAttribute string `yaml:"admin_group_attribute"`
}
func (c *ClientAPI) Defaults(_ DefaultOpts) {
c.RegistrationSharedSecret = ""
c.RegistrationRequiresToken = false
c.RecaptchaPublicKey = ""

View file

@ -540,7 +540,6 @@ Will not back up to an old backup version
Can create more than 10 backup versions
Can delete backup
Deleted & recreated backups are empty
Can upload self-signing keys
Fails to upload self-signing keys with no auth
Fails to upload self-signing key without master key
can fetch self-signing keys over federation
@ -633,7 +632,6 @@ Trying to add push rule with no scope fails with 400
Trying to add push rule with invalid scope fails with 400
Forward extremities remain so even after the next events are populated as outliers
uploading self-signing key notifies over federation
uploading signed devices gets propagated over federation
Device list doesn't change if remote server is down
/context/ on joined room works
/context/ on non world readable room does not work

View file

@ -144,6 +144,8 @@ type QueryAcccessTokenAPI interface {
type UserLoginAPI interface {
QueryAccountByPassword(ctx context.Context, req *QueryAccountByPasswordRequest, res *QueryAccountByPasswordResponse) error
QueryAccountByLocalpart(ctx context.Context, req *QueryAccountByLocalpartRequest, res *QueryAccountByLocalpartResponse) error
PerformAccountCreation(ctx context.Context, req *PerformAccountCreationRequest, res *PerformAccountCreationResponse) error
}
type PerformKeyBackupRequest struct {