func makeFakeWriterMetadataFuture(t *testing.T) writerMetadataFuture {
	wmd := WriterMetadata{
		// This needs to be list format so it fails to compile if new fields
		// are added, effectively checking at compile time whether new fields
		// have been added
		[]byte{0xa, 0xb},
		"uid1",
		[]keybase1.UID{"uid1", "uid2"},
		nil,
		FakeTlfID(1, false),
		NullBranchID,
		0xa,
		100,
		99,
		101,
		WriterMetadataExtra{},
	}
	wkb := makeFakeTLFWriterKeyBundleFuture(t)
	sa, _ := libkb.NormalizeSocialAssertion("foo@twitter")
	return writerMetadataFuture{
		wmd,
		tlfWriterKeyGenerationsFuture{&wkb},
		writerMetadataExtraFuture{
			WriterMetadataExtra{
				// This needs to be list format so it fails to compile if new
				// fields are added, effectively checking at compile time
				// whether new fields have been added
				[]keybase1.SocialAssertion{sa},
				codec.UnknownFieldSetHandler{},
			},
			makeExtraOrBust("WriterMetadata", t),
		},
	}
}
Beispiel #2
0
// AddNewAssertionForTest makes newAssertion, which should be a single
// assertion that doesn't already resolve to anything, resolve to the
// same UID as oldAssertion, which should be an arbitrary assertion
// that does already resolve to something.  It only applies to the
// given config.
func AddNewAssertionForTest(
	config Config, oldAssertion, newAssertion string) error {
	kbd, ok := config.KeybaseDaemon().(*KeybaseDaemonLocal)
	if !ok {
		return errors.New("Bad keybase daemon")
	}

	uid, err := kbd.addNewAssertionForTest(oldAssertion, newAssertion)
	if err != nil {
		return err
	}

	// Let the mdserver know about the name change
	md, ok := config.MDServer().(*MDServerLocal)
	if !ok {
		return errors.New("Bad md server")
	}
	// If this function is called multiple times for different
	// configs, it may end up invoking the following call more than
	// once on the shared md databases.  That's ok though, it's an
	// idempotent call.
	newSocialAssertion, ok := libkb.NormalizeSocialAssertion(newAssertion)
	if !ok {
		return fmt.Errorf("%s couldn't be parsed as a social assertion", newAssertion)
	}
	if err := md.addNewAssertionForTest(uid, newSocialAssertion); err != nil {
		return fmt.Errorf("Couldn't update md server: %v", err)
	}
	return nil
}
Beispiel #3
0
func (ra resolvableAssertion) resolve(ctx context.Context) (
	nameUIDPair, keybase1.SocialAssertion, error) {
	if ra.assertion == PublicUIDName {
		return nameUIDPair{}, keybase1.SocialAssertion{}, fmt.Errorf("Invalid name %s", ra.assertion)
	}
	name, uid, err := ra.resolver.Resolve(ctx, ra.assertion)
	if err == nil && ra.mustBeUser != keybase1.UID("") && ra.mustBeUser != uid {
		// Force an unresolved assertion sinced the forced user doesn't match
		err = NoSuchUserError{ra.assertion}
	}
	switch err := err.(type) {
	default:
		return nameUIDPair{}, keybase1.SocialAssertion{}, err
	case nil:
		return nameUIDPair{
			name: name,
			uid:  uid,
		}, keybase1.SocialAssertion{}, nil
	case NoSuchUserError:
		if !ra.sharingBeforeSignupEnabled {
			return nameUIDPair{}, keybase1.SocialAssertion{}, err
		}
		socialAssertion, ok := libkb.NormalizeSocialAssertion(ra.assertion)
		if !ok {
			return nameUIDPair{}, keybase1.SocialAssertion{}, err
		}
		return nameUIDPair{}, socialAssertion, nil
	}
}
Beispiel #4
0
// TODO: this function can likely be replaced with a call to
// AssertionParseAndOnly when CORE-2967 and CORE-2968 are fixed.
func normalizeAssertionOrName(s string) (string, error) {
	if libkb.CheckUsername.F(s) {
		return libkb.NewNormalizedUsername(s).String(), nil
	}

	// TODO: this fails for http and https right now (see CORE-2968).
	socialAssertion, isSocialAssertion := libkb.NormalizeSocialAssertion(s)
	if isSocialAssertion {
		return socialAssertion.String(), nil
	}

	if expr, err := libkb.AssertionParseAndOnly(s); err == nil {
		// If the expression only contains a single url, make sure
		// it's not a just considered a single keybase username.  If
		// it is, then some non-username slipped into the default
		// "keybase" case and should be considered an error.
		urls := expr.CollectUrls(nil)
		if len(urls) == 1 && urls[0].IsKeybase() {
			return "", NoSuchUserError{s}
		}

		// Normalize and return.  Ideally `AssertionParseAndOnly`
		// would normalize for us, but that doesn't work yet, so for
		// now we'll just lower-case.  This will incorrectly lower
		// case http/https/web assertions, as well as case-sensitive
		// social assertions in AND expressions.  TODO: see CORE-2967.
		return strings.ToLower(s), nil
	}

	return "", BadTLFNameError{s}
}
// Test that WriterMetadata has only a fixed (frozen) set of fields.
func TestWriterMetadataEncodedFields(t *testing.T) {
	sa1, _ := libkb.NormalizeSocialAssertion("uid1@twitter")
	sa2, _ := libkb.NormalizeSocialAssertion("uid2@twitter")
	// Usually exactly one of Writers/WKeys is filled in, but we
	// fill in both here for testing.
	wm := WriterMetadata{
		ID:      FakeTlfID(0xa, false),
		Writers: []keybase1.UID{"uid1", "uid2"},
		WKeys:   TLFWriterKeyGenerations{{}},
		Extra: WriterMetadataExtra{
			UnresolvedWriters: []keybase1.SocialAssertion{sa1, sa2},
		},
	}

	c := NewCodecMsgpack()

	buf, err := c.Encode(wm)
	require.NoError(t, err)

	var m map[string]interface{}
	err = c.Decode(buf, &m)
	require.NoError(t, err)

	expectedFields := []string{
		"BID",
		"DiskUsage",
		"ID",
		"LastModifyingWriter",
		"RefBytes",
		"UnrefBytes",
		"WFlags",
		"WKeys",
		"Writers",
		"data",
		"x",
	}

	var fields []string
	for field := range m {
		fields = append(fields, field)
	}
	sort.Strings(fields)
	require.Equal(t, expectedFields, fields)
}
Beispiel #6
0
func (e *FavoriteAdd) checkInviteNeeded(ctx *Context) error {
	defer func() {
		close(e.checkInviteDone)
	}()

	// If not folder creator, do nothing.
	if !e.arg.Folder.Created {
		return nil
	}

	for _, user := range strings.Split(e.arg.Folder.Name, ",") {
		assertion, ok := libkb.NormalizeSocialAssertion(user)
		if !ok {
			e.G().Log.Debug("not a social assertion: %s", user)
			continue
		}

		e.G().Log.Debug("social assertion found in FavoriteAdd folder name: %s", assertion)
		e.G().Log.Debug("requesting an invitation for %s", assertion)

		inv, err := libkb.GenerateInvitationCodeForAssertion(e.G(), assertion, libkb.InviteArg{})
		if err != nil {
			return err
		}

		e.G().Log.Debug("invitation requested, informing folder creator with result")
		arg := keybase1.DisplayTLFCreateWithInviteArg{
			FolderName:      e.arg.Folder.Name,
			Assertion:       assertion.String(),
			SocialAssertion: assertion,
			IsPrivate:       e.arg.Folder.Private,
			Throttled:       inv.Throttled,
			InviteLink:      inv.Link(),
		}
		if err := ctx.IdentifyUI.DisplayTLFCreateWithInvite(arg); err != nil {
			return err
		}
	}

	return nil
}
func makeFakeRootMetadataFuture(t *testing.T) *rootMetadataFuture {
	wmf := makeFakeWriterMetadataFuture(t)
	rkb := makeFakeTLFReaderKeyBundleFuture(t)
	h, err := DefaultHash([]byte("fake buf"))
	require.NoError(t, err)
	sa, _ := libkb.NormalizeSocialAssertion("bar@github")
	rmf := rootMetadataFuture{
		wmf,
		rootMetadataWrapper{
			RootMetadata{
				// This needs to be list format so it fails to compile if new
				// fields are added, effectively checking at compile time
				// whether new fields have been added
				WriterMetadata{},
				SignatureInfo{
					100,
					[]byte{0xc},
					MakeFakeVerifyingKeyOrBust("fake kid"),
				},
				"uid1",
				0xb,
				5,
				MdID{h},
				nil,
				[]keybase1.SocialAssertion{sa},
				nil,
				codec.UnknownFieldSetHandler{},
				PrivateMetadata{},
				nil,
				sync.RWMutex{},
				MdID{},
			},
		},
		[]*tlfReaderKeyBundleFuture{&rkb},
		makeExtraOrBust("RootMetadata", t),
	}
	return &rmf
}