mirror of
https://github.com/versia-pub/versia-go.git
synced 2026-03-13 04:29:15 +01:00
refactor!: working WD-4 user discovery
This commit is contained in:
parent
cf0053312d
commit
61891d891a
91 changed files with 12768 additions and 5562 deletions
|
|
@ -18,29 +18,31 @@ import (
|
|||
var _ service.InboxService = (*InboxServiceImpl)(nil)
|
||||
|
||||
type InboxServiceImpl struct {
|
||||
repositories repository.Manager
|
||||
|
||||
federationService service.FederationService
|
||||
|
||||
repositories repository.Manager
|
||||
|
||||
telemetry *unitel.Telemetry
|
||||
log logr.Logger
|
||||
}
|
||||
|
||||
func NewInboxService(repositories repository.Manager, federationService service.FederationService, telemetry *unitel.Telemetry, log logr.Logger) *InboxServiceImpl {
|
||||
func NewInboxService(federationService service.FederationService, repositories repository.Manager, telemetry *unitel.Telemetry, log logr.Logger) *InboxServiceImpl {
|
||||
return &InboxServiceImpl{
|
||||
repositories: repositories,
|
||||
federationService: federationService,
|
||||
telemetry: telemetry,
|
||||
log: log,
|
||||
|
||||
repositories: repositories,
|
||||
|
||||
telemetry: telemetry,
|
||||
log: log,
|
||||
}
|
||||
}
|
||||
|
||||
func (i InboxServiceImpl) WithRepositories(repositories repository.Manager) service.InboxService {
|
||||
return NewInboxService(repositories, i.federationService, i.telemetry, i.log)
|
||||
return NewInboxService(i.federationService, repositories, i.telemetry, i.log)
|
||||
}
|
||||
|
||||
func (i InboxServiceImpl) Handle(ctx context.Context, obj any, userId uuid.UUID) error {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "service/svc_impls.InboxServiceImpl.Handle")
|
||||
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/InboxServiceImpl.Handle")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
|
|
@ -87,7 +89,7 @@ func (i InboxServiceImpl) Handle(ctx context.Context, obj any, userId uuid.UUID)
|
|||
}
|
||||
|
||||
func (i InboxServiceImpl) handleFollow(ctx context.Context, o lysand.Follow, u *entity.User) error {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "service/svc_impls.InboxServiceImpl.handleFollow")
|
||||
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/InboxServiceImpl.handleFollow")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
|
|
@ -129,7 +131,7 @@ func (i InboxServiceImpl) handleFollow(ctx context.Context, o lysand.Follow, u *
|
|||
}
|
||||
|
||||
func (i InboxServiceImpl) handleNote(ctx context.Context, o lysand.Note, u *entity.User) error {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "service/svc_impls.InboxServiceImpl.handleNote")
|
||||
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/InboxServiceImpl.handleNote")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,34 @@
|
|||
package svc_impls
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.devminer.xyz/devminer/unitel"
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/lysand-org/versia-go/internal/entity"
|
||||
"github.com/lysand-org/versia-go/internal/service"
|
||||
"github.com/lysand-org/versia-go/pkg/lysand"
|
||||
versiacrypto "github.com/lysand-org/versia-go/pkg/lysand/crypto"
|
||||
"github.com/lysand-org/versia-go/pkg/protoretry"
|
||||
"github.com/lysand-org/versia-go/pkg/webfinger"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
var _ service.FederationService = (*FederationServiceImpl)(nil)
|
||||
var (
|
||||
_ service.FederationService = (*FederationServiceImpl)(nil)
|
||||
|
||||
ErrSignatureValidationFailed = errors.New("signature validation failed")
|
||||
)
|
||||
|
||||
type FederationServiceImpl struct {
|
||||
httpC *protoretry.Client
|
||||
|
||||
federationClient *lysand.FederationClient
|
||||
|
||||
telemetry *unitel.Telemetry
|
||||
|
|
@ -19,38 +36,139 @@ type FederationServiceImpl struct {
|
|||
log logr.Logger
|
||||
}
|
||||
|
||||
func NewFederationServiceImpl(federationClient *lysand.FederationClient, telemetry *unitel.Telemetry, log logr.Logger) *FederationServiceImpl {
|
||||
func NewFederationServiceImpl(httpClient *http.Client, federationClient *lysand.FederationClient, telemetry *unitel.Telemetry, log logr.Logger) *FederationServiceImpl {
|
||||
return &FederationServiceImpl{
|
||||
httpC: protoretry.New(httpClient),
|
||||
federationClient: federationClient,
|
||||
telemetry: telemetry,
|
||||
log: log,
|
||||
}
|
||||
}
|
||||
|
||||
func (i FederationServiceImpl) SendToInbox(ctx context.Context, author *entity.User, target *entity.User, object any) ([]byte, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "service/svc_impls.FederationServiceImpl.SendToInbox")
|
||||
func (i *FederationServiceImpl) GetUser(ctx context.Context, uri *lysand.URL) (*lysand.User, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/FederationServiceImpl.GetUser").
|
||||
AddAttribute("userURI", uri.String())
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
response, err := i.federationClient.SendToInbox(ctx, author.Signer, target.ToLysand(), object)
|
||||
body, resp, err := i.httpC.GET(ctx, uri.ToStd())
|
||||
if err != nil {
|
||||
i.log.Error(err, "Failed to send to inbox", "author", author.ID, "target", target.ID)
|
||||
return response, err
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func (i FederationServiceImpl) GetUser(ctx context.Context, uri *lysand.URL) (*lysand.User, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "service/svc_impls.FederationServiceImpl.GetUser")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
u, err := i.federationClient.GetUser(ctx, uri.ToStd())
|
||||
if err != nil {
|
||||
i.log.Error(err, "Failed to fetch remote user", "uri", uri)
|
||||
s.SetSimpleStatus(unitel.Error, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
u := &lysand.User{}
|
||||
if err := json.Unmarshal(body, u); err != nil {
|
||||
s.SetSimpleStatus(unitel.Error, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fedHeaders, err := lysand.ExtractFederationHeaders(resp.Header)
|
||||
if err != nil {
|
||||
s.SetSimpleStatus(unitel.Error, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v := lysand.Verifier{PublicKey: u.PublicKey.Key.Key}
|
||||
if !v.Verify("GET", uri.ToStd(), body, fedHeaders) {
|
||||
s.SetSimpleStatus(unitel.Error, ErrSignatureValidationFailed.Error())
|
||||
i.log.V(1).Error(ErrSignatureValidationFailed, "signature validation failed", "user", u.URI.String())
|
||||
return nil, ErrSignatureValidationFailed
|
||||
}
|
||||
|
||||
s.SetSimpleStatus(unitel.Ok, "")
|
||||
i.log.V(2).Info("signature verification succeeded", "user", u.URI.String())
|
||||
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (i *FederationServiceImpl) DiscoverUser(ctx context.Context, baseURL, username string) (*webfinger.User, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/FederationServiceImpl.DiscoverUser").
|
||||
AddAttribute("baseURL", baseURL).
|
||||
AddAttribute("username", username)
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
wf, err := webfinger.Discover(i.httpC, ctx, baseURL, username)
|
||||
if err != nil {
|
||||
s.SetSimpleStatus(unitel.Error, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.SetSimpleStatus(unitel.Ok, "")
|
||||
|
||||
return wf, nil
|
||||
}
|
||||
|
||||
func (i *FederationServiceImpl) DiscoverInstance(ctx context.Context, baseURL string) (*lysand.InstanceMetadata, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/FederationServiceImpl.DiscoverInstance").
|
||||
AddAttribute("baseURL", baseURL)
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
body, resp, err := i.httpC.GET(ctx, &url.URL{Scheme: "https", Host: baseURL, Path: "/.well-known/versia"})
|
||||
if err != nil {
|
||||
s.SetSimpleStatus(unitel.Error, err.Error())
|
||||
return nil, err
|
||||
} else if resp.StatusCode >= http.StatusBadRequest {
|
||||
s.SetSimpleStatus(unitel.Error, fmt.Sprintf("unexpected response code: %d", resp.StatusCode))
|
||||
return nil, &lysand.ResponseError{StatusCode: resp.StatusCode, URL: resp.Request.URL}
|
||||
}
|
||||
|
||||
var metadata lysand.InstanceMetadata
|
||||
if err := json.Unmarshal(body, &metadata); err != nil {
|
||||
s.SetSimpleStatus(unitel.Error, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.SetSimpleStatus(unitel.Ok, "")
|
||||
|
||||
return &metadata, nil
|
||||
}
|
||||
|
||||
func (i *FederationServiceImpl) SendToInbox(ctx context.Context, author *entity.User, user *entity.User, object any) ([]byte, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/FederationServiceImpl.SendToInbox").
|
||||
SetUser(uint64(author.ID.ID()), author.Username, "", "").
|
||||
AddAttribute("author", author.ID).
|
||||
AddAttribute("authorURI", author.URI).
|
||||
AddAttribute("target", user.ID).
|
||||
AddAttribute("targetURI", user.URI)
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
uri := user.Inbox.ToStd()
|
||||
|
||||
body, err := json.Marshal(object)
|
||||
if err != nil {
|
||||
s.SetSimpleStatus(unitel.Error, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nonce := make([]byte, 32)
|
||||
if _, err := rand.Read(nonce); err != nil {
|
||||
s.SetSimpleStatus(unitel.Error, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sigData := lysand.NewSignatureData("POST", base64.StdEncoding.EncodeToString(nonce), uri, versiacrypto.SHA256(body))
|
||||
sig := author.Signer.Sign(*sigData)
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, "POST", uri.String(), bytes.NewReader(body))
|
||||
if err != nil {
|
||||
s.SetSimpleStatus(unitel.Error, err.Error())
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sig.Inject(req.Header)
|
||||
|
||||
body, _, err = i.httpC.DoReq(req)
|
||||
if err != nil {
|
||||
s.SetSimpleStatus(unitel.Error, err.Error())
|
||||
i.log.Error(err, "Failed to send to inbox", "author", author.URI, "target", user.URI)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.SetSimpleStatus(unitel.Ok, "")
|
||||
|
||||
return body, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ func NewFollowServiceImpl(federationService service.FederationService, repositor
|
|||
}
|
||||
|
||||
func (i FollowServiceImpl) NewFollow(ctx context.Context, follower, followee *entity.User) (*entity.Follow, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "service/svc_impls.FollowServiceImpl.NewFollow").
|
||||
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/FollowServiceImpl.NewFollow").
|
||||
AddAttribute("follower", follower.URI).
|
||||
AddAttribute("followee", followee.URI)
|
||||
defer s.End()
|
||||
|
|
@ -54,7 +54,7 @@ func (i FollowServiceImpl) NewFollow(ctx context.Context, follower, followee *en
|
|||
}
|
||||
|
||||
func (i FollowServiceImpl) GetFollow(ctx context.Context, id uuid.UUID) (*entity.Follow, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "service/svc_impls.FollowServiceImpl.GetFollow").
|
||||
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/FollowServiceImpl.GetFollow").
|
||||
AddAttribute("followID", id)
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
|
@ -70,7 +70,7 @@ func (i FollowServiceImpl) GetFollow(ctx context.Context, id uuid.UUID) (*entity
|
|||
}
|
||||
|
||||
func (i FollowServiceImpl) ImportLysandFollow(ctx context.Context, lFollow *lysand.Follow) (*entity.Follow, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "service/svc_impls.FollowServiceImpl.ImportLysandFollow").
|
||||
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/FollowServiceImpl.ImportLysandFollow").
|
||||
AddAttribute("uri", lFollow.URI.String())
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
|
|
|||
52
internal/service/svc_impls/instance_metadata_service_impl.go
Normal file
52
internal/service/svc_impls/instance_metadata_service_impl.go
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
package svc_impls
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/lysand-org/versia-go/config"
|
||||
"github.com/lysand-org/versia-go/ent"
|
||||
"github.com/lysand-org/versia-go/internal/repository"
|
||||
"github.com/lysand-org/versia-go/internal/service"
|
||||
|
||||
"git.devminer.xyz/devminer/unitel"
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/lysand-org/versia-go/internal/entity"
|
||||
)
|
||||
|
||||
var _ service.InstanceMetadataService = (*InstanceMetadataServiceImpl)(nil)
|
||||
|
||||
type InstanceMetadataServiceImpl struct {
|
||||
federationService service.FederationService
|
||||
|
||||
repositories repository.Manager
|
||||
|
||||
telemetry *unitel.Telemetry
|
||||
log logr.Logger
|
||||
}
|
||||
|
||||
func NewInstanceMetadataServiceImpl(federationService service.FederationService, repositories repository.Manager, telemetry *unitel.Telemetry, log logr.Logger) *InstanceMetadataServiceImpl {
|
||||
return &InstanceMetadataServiceImpl{
|
||||
federationService: federationService,
|
||||
|
||||
repositories: repositories,
|
||||
|
||||
telemetry: telemetry,
|
||||
log: log,
|
||||
}
|
||||
}
|
||||
|
||||
func (i InstanceMetadataServiceImpl) Ours(ctx context.Context) (*entity.InstanceMetadata, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/InstanceMetadataServiceImpl.Ours")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
m, err := i.repositories.InstanceMetadata().GetByHost(ctx, config.C.Host)
|
||||
if err != nil {
|
||||
if ent.IsNotFound(err) {
|
||||
panic("could not find our own instance metadata")
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
|
@ -39,7 +39,7 @@ func NewNoteServiceImpl(federationService service.FederationService, taskService
|
|||
}
|
||||
|
||||
func (i NoteServiceImpl) CreateNote(ctx context.Context, req api_schema.CreateNoteRequest) (*entity.Note, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "service/svc_impls.NoteServiceImpl.CreateNote")
|
||||
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/NoteServiceImpl.CreateNote")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
|
|
@ -82,7 +82,7 @@ func (i NoteServiceImpl) CreateNote(ctx context.Context, req api_schema.CreateNo
|
|||
}
|
||||
|
||||
func (i NoteServiceImpl) GetNote(ctx context.Context, id uuid.UUID) (*entity.Note, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "service/svc_impls.NoteServiceImpl.GetUserByID")
|
||||
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/NoteServiceImpl.GetUserByID")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ func (i NoteServiceImpl) GetNote(ctx context.Context, id uuid.UUID) (*entity.Not
|
|||
}
|
||||
|
||||
func (i NoteServiceImpl) ImportLysandNote(ctx context.Context, lNote *lysand.Note) (*entity.Note, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "service/svc_impls.NoteServiceImpl.ImportLysandNote")
|
||||
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/NoteServiceImpl.ImportLysandNote")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
|
|
|
|||
63
internal/service/svc_impls/request_signer_impl.go
Normal file
63
internal/service/svc_impls/request_signer_impl.go
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
package svc_impls
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"git.devminer.xyz/devminer/unitel"
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/lysand-org/versia-go/internal/service"
|
||||
"github.com/lysand-org/versia-go/pkg/lysand"
|
||||
versiacrypto "github.com/lysand-org/versia-go/pkg/lysand/crypto"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
var _ service.RequestSigner = (*RequestSignerImpl)(nil)
|
||||
|
||||
type RequestSignerImpl struct {
|
||||
telemetry *unitel.Telemetry
|
||||
|
||||
log logr.Logger
|
||||
}
|
||||
|
||||
func NewRequestSignerImpl(telemetry *unitel.Telemetry, log logr.Logger) *RequestSignerImpl {
|
||||
return &RequestSignerImpl{
|
||||
telemetry: telemetry,
|
||||
log: log,
|
||||
}
|
||||
}
|
||||
|
||||
func (i *RequestSignerImpl) Sign(c *fiber.Ctx, signer lysand.Signer, body any) error {
|
||||
s := i.telemetry.StartSpan(c.UserContext(), "function", "svc_impls/RequestSignerImpl.Sign")
|
||||
defer s.End()
|
||||
|
||||
j, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rawNonce := make([]byte, 64)
|
||||
if _, err := rand.Read(rawNonce); err != nil {
|
||||
return err
|
||||
}
|
||||
nonce := base64.StdEncoding.EncodeToString(rawNonce)
|
||||
|
||||
uri, err := url.ParseRequestURI(string(c.Request().RequestURI()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
digest := versiacrypto.SHA256(j)
|
||||
|
||||
d := lysand.NewSignatureData(c.Method(), nonce, uri, digest)
|
||||
|
||||
signed := signer.Sign(*d)
|
||||
for k, v := range signed.Headers() {
|
||||
c.Set(k, v)
|
||||
}
|
||||
|
||||
i.log.V(2).Info("signed response", "digest", base64.StdEncoding.EncodeToString(digest), "nonce", nonce)
|
||||
|
||||
return c.Send(j)
|
||||
}
|
||||
|
|
@ -28,7 +28,7 @@ func NewTaskServiceImpl(client *taskqueue.Client, telemetry *unitel.Telemetry, l
|
|||
}
|
||||
|
||||
func (i TaskServiceImpl) ScheduleTask(ctx context.Context, type_ string, data any) error {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "service/svc_impls.TaskServiceImpl.ScheduleTask")
|
||||
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/TaskServiceImpl.ScheduleTask")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import (
|
|||
"context"
|
||||
"crypto/ed25519"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"github.com/lysand-org/versia-go/internal/api_schema"
|
||||
"github.com/lysand-org/versia-go/internal/repository"
|
||||
"github.com/lysand-org/versia-go/internal/service"
|
||||
"net/url"
|
||||
|
|
@ -45,7 +45,7 @@ func (i UserServiceImpl) WithRepositories(repositories repository.Manager) servi
|
|||
}
|
||||
|
||||
func (i UserServiceImpl) NewUser(ctx context.Context, username, password string) (*entity.User, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "service/svc_impls.UserServiceImpl.NewUser")
|
||||
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/UserServiceImpl.NewUser")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ func (i UserServiceImpl) NewUser(ctx context.Context, username, password string)
|
|||
}
|
||||
|
||||
func (i UserServiceImpl) GetUserByID(ctx context.Context, id uuid.UUID) (*entity.User, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "service/svc_impls.UserServiceImpl.GetUserByID")
|
||||
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/UserServiceImpl.GetUserByID")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
|
|
@ -81,7 +81,7 @@ func (i UserServiceImpl) GetUserByID(ctx context.Context, id uuid.UUID) (*entity
|
|||
}
|
||||
|
||||
func (i UserServiceImpl) GetWebfingerForUser(ctx context.Context, userID string) (*webfinger.User, error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "service/svc_impls.UserServiceImpl.GetWebfingerForUser")
|
||||
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/UserServiceImpl.GetWebfingerForUser")
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
|
|
@ -90,7 +90,7 @@ func (i UserServiceImpl) GetWebfingerForUser(ctx context.Context, userID string)
|
|||
return nil, err
|
||||
}
|
||||
if u == nil {
|
||||
return nil, fmt.Errorf("user not found")
|
||||
return nil, api_schema.ErrUserNotFound
|
||||
}
|
||||
|
||||
wf := &webfinger.User{
|
||||
|
|
@ -120,3 +120,25 @@ func (i UserServiceImpl) GetWebfingerForUser(ctx context.Context, userID string)
|
|||
|
||||
return wf, nil
|
||||
}
|
||||
|
||||
func (i UserServiceImpl) Search(ctx context.Context, req api_schema.SearchUserRequest) (u *entity.User, err error) {
|
||||
s := i.telemetry.StartSpan(ctx, "function", "svc_impls/UserServiceImpl.Search").
|
||||
AddAttribute("username", req.Username)
|
||||
defer s.End()
|
||||
ctx = s.Context()
|
||||
|
||||
domain := ""
|
||||
if req.Domain != nil {
|
||||
domain = *req.Domain
|
||||
}
|
||||
|
||||
err = i.repositories.Atomic(ctx, func(ctx context.Context, tx repository.Manager) error {
|
||||
var err error
|
||||
if u, err = i.repositories.Users().Discover(ctx, domain, req.Username); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
return
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue