mirror of
https://github.com/kevin-DL/services.git
synced 2026-01-11 19:04:35 +00:00
138 lines
3.6 KiB
Go
138 lines
3.6 KiB
Go
package handler
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/micro/micro/v3/service/config"
|
|
"github.com/micro/micro/v3/service/errors"
|
|
log "github.com/micro/micro/v3/service/logger"
|
|
"github.com/micro/micro/v3/service/store"
|
|
pauth "github.com/micro/services/pkg/auth"
|
|
adminpb "github.com/micro/services/pkg/service/proto"
|
|
"github.com/micro/services/pkg/tenant"
|
|
qr "github.com/micro/services/qr/proto"
|
|
"github.com/skip2/go-qrcode"
|
|
)
|
|
|
|
const (
|
|
prefixByTenant = "qrByTenant"
|
|
defaultCodeSize = 256
|
|
)
|
|
|
|
type QrCode struct {
|
|
Filename string `json:"filename"`
|
|
Created int64 `json:"created"`
|
|
Text string `json:"text"`
|
|
}
|
|
|
|
type Qr struct {
|
|
cdnPrefix string
|
|
}
|
|
|
|
func New() *Qr {
|
|
v, err := config.Get("micro.qr.cdnprefix")
|
|
if err != nil {
|
|
log.Fatalf("Failed to get CDN prefix %s", err)
|
|
}
|
|
pref := v.String("")
|
|
if len(pref) == 0 {
|
|
log.Fatalf("Failed to get CDN prefix")
|
|
}
|
|
return &Qr{cdnPrefix: pref}
|
|
}
|
|
|
|
func namespacePrefix(tenantID string) string {
|
|
return "micro/qr/" + tenantID
|
|
}
|
|
|
|
func (q *Qr) Generate(ctx context.Context, request *qr.GenerateRequest, response *qr.GenerateResponse) error {
|
|
if len(request.Text) == 0 {
|
|
return errors.BadRequest("qr.generate", "Missing parameter text")
|
|
}
|
|
ten, ok := tenant.FromContext(ctx)
|
|
if !ok {
|
|
log.Errorf("Error retrieving tenant")
|
|
return errors.Unauthorized("qr.generate", "Unauthorized")
|
|
}
|
|
size := defaultCodeSize
|
|
if request.Size > 0 {
|
|
size = int(request.Size)
|
|
}
|
|
qrc, err := qrcode.Encode(request.Text, qrcode.Medium, size)
|
|
if err != nil {
|
|
log.Errorf("Error generating QR code %s", err)
|
|
return errors.InternalServerError("qr.generate", "Error while generating QR code")
|
|
}
|
|
|
|
nsPrefix := namespacePrefix(ten)
|
|
fileName := fmt.Sprintf("%s.png", uuid.New().String())
|
|
if err := store.DefaultBlobStore.Write(
|
|
fileName, bytes.NewBuffer(qrc),
|
|
store.BlobContentType("image/png"),
|
|
store.BlobPublic(true),
|
|
store.BlobNamespace(nsPrefix)); err != nil {
|
|
log.Errorf("Error saving QR code to blob store %s", err)
|
|
return errors.InternalServerError("qr.generate", "Error while generating QR code")
|
|
}
|
|
// store record of it
|
|
rec := QrCode{
|
|
Filename: fileName,
|
|
Created: time.Now().Unix(),
|
|
Text: request.Text,
|
|
}
|
|
b, _ := json.Marshal(&rec)
|
|
if err := store.Write(&store.Record{
|
|
Key: fmt.Sprintf("%s/%s/%s", prefixByTenant, nsPrefix, fileName),
|
|
Value: b,
|
|
}); err != nil {
|
|
log.Errorf("Error saving QR code record %s", err)
|
|
return errors.InternalServerError("qr.generate", "Error while generating QR code")
|
|
}
|
|
response.Qr = fmt.Sprintf("%s/%s/%s", q.cdnPrefix, nsPrefix, rec.Filename)
|
|
return nil
|
|
}
|
|
|
|
func (q *Qr) DeleteData(ctx context.Context, request *adminpb.DeleteDataRequest, response *adminpb.DeleteDataResponse) error {
|
|
method := "admin.DeleteData"
|
|
_, err := pauth.VerifyMicroAdmin(ctx, method)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(request.TenantId) < 10 { // deliberate length check so we don't delete all the things
|
|
return errors.BadRequest(method, "Missing tenant ID")
|
|
}
|
|
ns := namespacePrefix(request.TenantId)
|
|
keys, err := store.DefaultBlobStore.List(store.BlobListNamespace(ns))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, key := range keys {
|
|
err = store.DefaultBlobStore.Delete(key, store.BlobNamespace(ns))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
log.Infof("Deleted %d objects from S3 for %s", len(keys), request.TenantId)
|
|
|
|
keys, err = store.List(store.ListPrefix(fmt.Sprintf("%s/%s/", prefixByTenant, ns)))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, key := range keys {
|
|
if err := store.Delete(key); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
log.Infof("Deleted %d objects from store for %s", len(keys), request.TenantId)
|
|
|
|
return nil
|
|
}
|