| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 | 
							- // Copyright (C) 2014 The Syncthing Authors.
 
- //
 
- // This Source Code Form is subject to the terms of the Mozilla Public
 
- // License, v. 2.0. If a copy of the MPL was not distributed with this file,
 
- // You can obtain one at https://mozilla.org/MPL/2.0/.
 
- package api
 
- import (
 
- 	"testing"
 
- 	"time"
 
- 	"github.com/syncthing/syncthing/lib/config"
 
- 	"github.com/syncthing/syncthing/lib/db"
 
- 	"github.com/syncthing/syncthing/lib/db/backend"
 
- 	"github.com/syncthing/syncthing/lib/events"
 
- )
 
- var guiCfg config.GUIConfiguration
 
- func init() {
 
- 	guiCfg.User = "user"
 
- 	guiCfg.SetPassword("pass")
 
- }
 
- func TestStaticAuthOK(t *testing.T) {
 
- 	t.Parallel()
 
- 	ok := authStatic("user", "pass", guiCfg)
 
- 	if !ok {
 
- 		t.Fatalf("should pass auth")
 
- 	}
 
- }
 
- func TestSimpleAuthUsernameFail(t *testing.T) {
 
- 	t.Parallel()
 
- 	ok := authStatic("userWRONG", "pass", guiCfg)
 
- 	if ok {
 
- 		t.Fatalf("should fail auth")
 
- 	}
 
- }
 
- func TestStaticAuthPasswordFail(t *testing.T) {
 
- 	t.Parallel()
 
- 	ok := authStatic("user", "passWRONG", guiCfg)
 
- 	if ok {
 
- 		t.Fatalf("should fail auth")
 
- 	}
 
- }
 
- func TestFormatOptionalPercentS(t *testing.T) {
 
- 	t.Parallel()
 
- 	cases := []struct {
 
- 		template string
 
- 		username string
 
- 		expected string
 
- 	}{
 
- 		{"cn=%s,dc=some,dc=example,dc=com", "username", "cn=username,dc=some,dc=example,dc=com"},
 
- 		{"cn=fixedusername,dc=some,dc=example,dc=com", "username", "cn=fixedusername,dc=some,dc=example,dc=com"},
 
- 		{"cn=%%s,dc=%s,dc=example,dc=com", "username", "cn=%s,dc=username,dc=example,dc=com"},
 
- 		{"cn=%%s,dc=%%s,dc=example,dc=com", "username", "cn=%s,dc=%s,dc=example,dc=com"},
 
- 		{"cn=%s,dc=%s,dc=example,dc=com", "username", "cn=username,dc=username,dc=example,dc=com"},
 
- 	}
 
- 	for _, c := range cases {
 
- 		templatedDn := formatOptionalPercentS(c.template, c.username)
 
- 		if c.expected != templatedDn {
 
- 			t.Fatalf("result should be %s != %s", c.expected, templatedDn)
 
- 		}
 
- 	}
 
- }
 
- func TestEscapeForLDAPFilter(t *testing.T) {
 
- 	t.Parallel()
 
- 	cases := []struct {
 
- 		in  string
 
- 		out string
 
- 	}{
 
- 		{"username", `username`},
 
- 		{"user(name", `user\28name`},
 
- 		{"user)name", `user\29name`},
 
- 		{"user\\name", `user\5Cname`},
 
- 		{"user*name", `user\2Aname`},
 
- 		{"*,CN=asdf", `\2A,CN=asdf`},
 
- 	}
 
- 	for _, c := range cases {
 
- 		res := escapeForLDAPFilter(c.in)
 
- 		if c.out != res {
 
- 			t.Fatalf("result should be %s != %s", c.out, res)
 
- 		}
 
- 	}
 
- }
 
- func TestEscapeForLDAPDN(t *testing.T) {
 
- 	t.Parallel()
 
- 	cases := []struct {
 
- 		in  string
 
- 		out string
 
- 	}{
 
- 		{"username", `username`},
 
- 		{"* ,CN=asdf", `*\20\2CCN\3Dasdf`},
 
- 	}
 
- 	for _, c := range cases {
 
- 		res := escapeForLDAPDN(c.in)
 
- 		if c.out != res {
 
- 			t.Fatalf("result should be %s != %s", c.out, res)
 
- 		}
 
- 	}
 
- }
 
- type mockClock struct {
 
- 	now time.Time
 
- }
 
- func (c *mockClock) Now() time.Time {
 
- 	c.now = c.now.Add(1) // time always ticks by at least 1 ns
 
- 	return c.now
 
- }
 
- func (c *mockClock) wind(t time.Duration) {
 
- 	c.now = c.now.Add(t)
 
- }
 
- func TestTokenManager(t *testing.T) {
 
- 	t.Parallel()
 
- 	mdb, _ := db.NewLowlevel(backend.OpenMemory(), events.NoopLogger)
 
- 	kdb := db.NewNamespacedKV(mdb, "test")
 
- 	clock := &mockClock{now: time.Now()}
 
- 	// Token manager keeps up to three tokens with a validity time of 24 hours.
 
- 	tm := newTokenManager("testTokens", kdb, 24*time.Hour, 3)
 
- 	tm.timeNow = clock.Now
 
- 	// Create three tokens
 
- 	t0 := tm.New()
 
- 	t1 := tm.New()
 
- 	t2 := tm.New()
 
- 	// Check that the tokens are valid
 
- 	if !tm.Check(t0) {
 
- 		t.Errorf("token %q should be valid", t0)
 
- 	}
 
- 	if !tm.Check(t1) {
 
- 		t.Errorf("token %q should be valid", t1)
 
- 	}
 
- 	if !tm.Check(t2) {
 
- 		t.Errorf("token %q should be valid", t2)
 
- 	}
 
- 	// Create a fourth token
 
- 	t3 := tm.New()
 
- 	// It should be valid
 
- 	if !tm.Check(t3) {
 
- 		t.Errorf("token %q should be valid", t3)
 
- 	}
 
- 	// But the first token should have been removed
 
- 	if tm.Check(t0) {
 
- 		t.Errorf("token %q should be invalid", t0)
 
- 	}
 
- 	// Wind the clock by 12 hours
 
- 	clock.wind(12 * time.Hour)
 
- 	// The second token should still be valid (and checking it will give it more life)
 
- 	if !tm.Check(t1) {
 
- 		t.Errorf("token %q should be valid", t1)
 
- 	}
 
- 	// Wind the clock by 12 hours
 
- 	clock.wind(12 * time.Hour)
 
- 	// The second token should still be valid
 
- 	if !tm.Check(t1) {
 
- 		t.Errorf("token %q should be valid", t1)
 
- 	}
 
- 	// But the third and fourth tokens should have expired
 
- 	if tm.Check(t2) {
 
- 		t.Errorf("token %q should be invalid", t2)
 
- 	}
 
- 	if tm.Check(t3) {
 
- 		t.Errorf("token %q should be invalid", t3)
 
- 	}
 
- }
 
 
  |