webappdb.go 2.29 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
package webappdbbackend

import (
	"context"
	"log"

	as "git.autistici.org/ai3/accountserver"
	"git.autistici.org/ai3/go-common/clientutil"
	"git.autistici.org/ai3/tools/webappdb/proto"
)

// WebappDBBackend looks up website information in the webappdb
// (FreeWVS) service.
type WebappDBBackend struct {
	as.Backend

	dbbe clientutil.Backend
}

type wdbTX struct {
	as.TX
	dbbe clientutil.Backend
}

func Wrap(b as.Backend, config *clientutil.BackendConfig) (*WebappDBBackend, error) {
	be, err := clientutil.NewBackend(config)
	if err != nil {
		return nil, err
	}
	return &WebappDBBackend{
		Backend: b,
		dbbe:    be,
	}, nil
}

func (b *WebappDBBackend) NewTransaction() (as.TX, error) {
	tx, err := b.Backend.NewTransaction()
	if err != nil {
		return nil, err
	}
	return &wdbTX{
		TX:   tx,
		dbbe: b.dbbe,
	}, nil
}

func (tx *wdbTX) GetUser(ctx context.Context, name string) (*as.RawUser, error) {
	user, err := tx.TX.GetUser(ctx, name)
	if err != nil {
		return nil, err
	}

	// Find all web resources.
	var sites []string
	sitemap := make(map[string]*as.Resource)
	for _, r := range user.Resources {
		if r.Type == as.ResourceTypeWebsite || r.Type == as.ResourceTypeDomain {
			sites = append(sites, r.Name)
			sitemap[r.Name] = r
		}
	}

	var cmsinfo map[string][]*webappdb.App
	if len(sitemap) == 0 {
		goto skip
	}

	cmsinfo, err = tx.lookup(ctx, sites)
	if err != nil {
		log.Printf("error looking up webappdb: %v", err)
		goto skip
	}
	for key, values := range cmsinfo {
		r, ok := sitemap[key]
		if !ok || r.Website == nil {
			continue
		}
		r.Website.CMSInfo = values
	}

skip:
	return user, nil
}

func (tx *wdbTX) GetResource(ctx context.Context, id as.ResourceID) (*as.RawResource, error) {
	rsrc, err := tx.TX.GetResource(ctx, id)
	if err != nil {
		return nil, err
	}
	if rsrc.Type != as.ResourceTypeWebsite && rsrc.Type != as.ResourceTypeDomain {
		return rsrc, nil
	}

	if tmp, err := tx.lookup(ctx, []string{rsrc.Name}); err == nil {
		rsrc.Website.CMSInfo = tmp[rsrc.Name]
	}

	return rsrc, nil
}

func (tx *wdbTX) lookup(ctx context.Context, sites []string) (map[string][]*webappdb.App, error) {
	var resp webappdb.FindAppsBySiteResponse
	if err := tx.dbbe.Call(ctx, "", "/api/search/by_site", &webappdb.FindAppsBySiteRequest{
		Sites: sites,
	}, &resp); err != nil {
		return nil, err
	}
	return resp.Apps, nil
}