1// Copyright 2015 Keybase, Inc. All rights reserved. Use of
2// this source code is governed by the included BSD license.
3
4package engine
5
6import (
7	"errors"
8
9	"github.com/keybase/client/go/libkb"
10	keybase1 "github.com/keybase/client/go/protocol/keybase1"
11)
12
13type ListTrackersUnverifiedEngine struct {
14	libkb.Contextified
15	arg ListTrackersUnverifiedEngineArg
16	res keybase1.UserSummarySet
17}
18
19// If a UID is given, the engine will list its trackers
20// If an Assertion is given, the engine will try to resolve it to a UID via
21// remote unless CachedOnly is true.
22// Otherwise, the logged-in uid is used.
23// If no user is logged in, NoUIDError is returned.
24type ListTrackersUnverifiedEngineArg struct {
25	UID        keybase1.UID
26	Assertion  string
27	CachedOnly bool
28}
29
30func NewListTrackersUnverifiedEngine(g *libkb.GlobalContext, arg ListTrackersUnverifiedEngineArg) *ListTrackersUnverifiedEngine {
31	return &ListTrackersUnverifiedEngine{
32		Contextified: libkb.NewContextified(g),
33		arg:          arg,
34	}
35}
36
37// Name is the unique engine name.
38func (e *ListTrackersUnverifiedEngine) Name() string {
39	return "ListTrackersUnverifiedEngine"
40}
41
42func (e *ListTrackersUnverifiedEngine) Prereqs() Prereqs {
43	session := false
44	if len(e.arg.Assertion) == 0 && e.arg.UID.IsNil() {
45		session = true
46	}
47	return Prereqs{Device: session}
48}
49
50func (e *ListTrackersUnverifiedEngine) RequiredUIs() []libkb.UIKind {
51	return nil
52}
53
54func (e *ListTrackersUnverifiedEngine) SubConsumers() []libkb.UIConsumer {
55	return nil
56}
57
58// lookupUID prefers 1) the given uid if provided 2) assertion if provided 3) logged in uid
59func lookupUID(m libkb.MetaContext, uid keybase1.UID, assertion string, cachedOnly bool) (ret keybase1.UID, err error) {
60	// If we're given the uid explicitly, use it.
61	if uid.Exists() {
62		return uid, nil
63	}
64	// Otherwise,
65	if len(assertion) != 0 {
66		if cachedOnly {
67			return ret, errors.New("cannot lookup assertion in CachedOnly mode")
68		}
69
70		larg := libkb.NewLoadUserArgWithMetaContext(m).WithPublicKeyOptional().WithName(assertion)
71		upk, _, err := m.G().GetUPAKLoader().LoadV2(larg)
72		if err != nil {
73			return ret, err
74		}
75		return upk.GetUID(), nil
76	}
77
78	uid = m.G().GetMyUID()
79	if uid.Exists() {
80		return uid, nil
81	}
82
83	return ret, libkb.NoUIDError{}
84}
85
86func (e *ListTrackersUnverifiedEngine) Run(m libkb.MetaContext) error {
87	uid, err := lookupUID(m, e.arg.UID, e.arg.Assertion, e.arg.CachedOnly)
88	if err != nil {
89		return err
90	}
91
92	callerUID := m.G().Env.GetUID()
93	ts := libkb.NewServertrustTrackerSyncer(m.G(), callerUID, libkb.FollowDirectionFollowers)
94
95	if e.arg.CachedOnly {
96		if err := libkb.RunSyncerCached(m, ts, uid); err != nil {
97			return err
98		}
99		e.res = ts.Result()
100		return nil
101	}
102
103	if err := libkb.RunSyncer(m, ts, uid, false /* loggedIn */, false /* forceReload */); err != nil {
104		return err
105	}
106	e.res = ts.Result()
107	return nil
108}
109
110func (e *ListTrackersUnverifiedEngine) GetResults() keybase1.UserSummarySet {
111	return e.res
112}
113