2020-03-30 15:19:36 +01:00
|
|
|
// Copyright (C) 2019 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package metainfo
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"storj.io/common/pb"
|
|
|
|
"storj.io/common/rpc/rpcstatus"
|
|
|
|
"storj.io/common/useragent"
|
2020-03-30 10:08:50 +01:00
|
|
|
"storj.io/common/uuid"
|
2020-03-30 15:19:36 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// ResolvePartnerID returns partnerIDBytes as parsed or UUID corresponding to header.UserAgent.
|
|
|
|
// returns empty uuid when neither is defined.
|
|
|
|
func (endpoint *Endpoint) ResolvePartnerID(ctx context.Context, header *pb.RequestHeader, partnerIDBytes []byte) (uuid.UUID, error) {
|
|
|
|
if header == nil {
|
|
|
|
return uuid.UUID{}, rpcstatus.Error(rpcstatus.InvalidArgument, "header is nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(partnerIDBytes) > 0 {
|
2020-03-31 17:49:16 +01:00
|
|
|
partnerID, err := uuid.FromBytes(partnerIDBytes)
|
2020-03-30 15:19:36 +01:00
|
|
|
if err != nil {
|
|
|
|
return uuid.UUID{}, rpcstatus.Errorf(rpcstatus.InvalidArgument, "unable to parse partner ID: %v", err)
|
|
|
|
}
|
|
|
|
return partnerID, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(header.UserAgent) == 0 {
|
|
|
|
return uuid.UUID{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
entries, err := useragent.ParseEntries(header.UserAgent)
|
|
|
|
if err != nil {
|
|
|
|
return uuid.UUID{}, rpcstatus.Errorf(rpcstatus.InvalidArgument, "invalid user agent %q: %v", string(header.UserAgent), err)
|
|
|
|
}
|
|
|
|
entries = removeUplinkUserAgent(entries)
|
|
|
|
|
|
|
|
// no user agent defined
|
|
|
|
if len(entries) == 0 {
|
|
|
|
return uuid.UUID{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Use the first partner product entry as the PartnerID.
|
|
|
|
for _, entry := range entries {
|
|
|
|
if entry.Product != "" {
|
|
|
|
partner, err := endpoint.partners.ByUserAgent(ctx, entry.Product)
|
|
|
|
if err != nil || partner.UUID == nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
return *partner.UUID, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return uuid.UUID{}, rpcstatus.Errorf(rpcstatus.InvalidArgument, "unable to resolve user agent %q", string(header.UserAgent))
|
|
|
|
}
|
|
|
|
|
|
|
|
func removeUplinkUserAgent(entries []useragent.Entry) []useragent.Entry {
|
|
|
|
var xs []useragent.Entry
|
|
|
|
for i := 0; i < len(entries); i++ {
|
|
|
|
// If it's "uplink" then skip it.
|
|
|
|
if strings.EqualFold(entries[i].Product, "uplink") {
|
|
|
|
// also skip any associated comments
|
|
|
|
for i+1 < len(entries) && entries[i+1].Comment != "" {
|
|
|
|
i++
|
|
|
|
}
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
xs = append(xs, entries[i])
|
|
|
|
}
|
|
|
|
return xs
|
|
|
|
}
|