Mercurial > go > multipass
comparison auth/auth_test.go @ 0:c18bc7b9d1d9
Basic binaries. checkpassword doesn't yet work.
| author | Paul Fisher <paul@pfish.zone> |
|---|---|
| date | Sat, 24 Oct 2015 21:32:03 -0400 |
| parents | |
| children | 1c194fa9bbf4 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:c18bc7b9d1d9 |
|---|---|
| 1 package auth | |
| 2 | |
| 3 import ( | |
| 4 "regexp" | |
| 5 "testing" | |
| 6 ) | |
| 7 | |
| 8 var passPattern *regexp.Regexp = regexp.MustCompile(`^(?:[a-z]{4}-){3}[a-z]{4}$`) | |
| 9 | |
| 10 const basicShadow = "jhh:9999:$2a$12$tcv2MrtXgibAJHsSwVfHiOevXBFmiGy0HTNoOB8QzIhEh46iWS1uC:YW55dGhpbmcgbW9yZSB0aGFuIDUgcmVwcyBpcyBjYXJkaW8=" | |
| 11 const extraDataShadow = "skw:1:$2a$12$lINQdYWHOcLKoqhNOr3mNOpZSAu5JOBS2F7T/VDfYn2rvv6qUJehG::additional:fields" | |
| 12 | |
| 13 func TestEntryFromShadow(t *testing.T) { | |
| 14 cases := []struct { | |
| 15 shadow string | |
| 16 wantErr bool | |
| 17 username string | |
| 18 id uint64 | |
| 19 hash string | |
| 20 description string | |
| 21 rest []string | |
| 22 }{ | |
| 23 { | |
| 24 shadow: "pfish:1234:$2a$12$apFtWGXKtWBavVy5eo.22Ohs43GudT5IYTqyQkIBX9LpS7YtvKBpa", | |
| 25 username: "pfish", | |
| 26 id: 1234, | |
| 27 hash: "$2a$12$apFtWGXKtWBavVy5eo.22Ohs43GudT5IYTqyQkIBX9LpS7YtvKBpa", | |
| 28 }, | |
| 29 { | |
| 30 shadow: basicShadow, | |
| 31 username: "jhh", | |
| 32 id: 9999, | |
| 33 hash: "$2a$12$tcv2MrtXgibAJHsSwVfHiOevXBFmiGy0HTNoOB8QzIhEh46iWS1uC", | |
| 34 description: "anything more than 5 reps is cardio", | |
| 35 }, | |
| 36 { | |
| 37 shadow: extraDataShadow, | |
| 38 username: "skw", | |
| 39 id: 1, | |
| 40 hash: "$2a$12$lINQdYWHOcLKoqhNOr3mNOpZSAu5JOBS2F7T/VDfYn2rvv6qUJehG", | |
| 41 rest: []string{"additional", "fields"}, | |
| 42 }, | |
| 43 { | |
| 44 shadow: "user:one:bogushash", | |
| 45 wantErr: true, | |
| 46 }, | |
| 47 { | |
| 48 shadow: "user:-1:bogushash", | |
| 49 wantErr: true, | |
| 50 }, | |
| 51 { | |
| 52 shadow: "tooshort", | |
| 53 wantErr: true, | |
| 54 }, | |
| 55 { | |
| 56 shadow: "test:0:bogushash:invalid base64", | |
| 57 wantErr: true, | |
| 58 }, | |
| 59 } | |
| 60 for _, c := range cases { | |
| 61 entry, err := EntryFromShadow(c.shadow) | |
| 62 if c.wantErr { | |
| 63 if err == nil { | |
| 64 t.Errorf("EntryFromShadow(%q) == _, nil; want non-nil err", c.shadow) | |
| 65 } | |
| 66 continue | |
| 67 } | |
| 68 if err != nil { | |
| 69 t.Errorf("EntryFromShadow(%q) == _, %q; want nil err", c.shadow, err) | |
| 70 } | |
| 71 if c.username != entry.username { | |
| 72 t.Errorf("EntryFromShadow(%q).username = %q; want %q", c.shadow, entry.username, c.username) | |
| 73 } | |
| 74 if c.hash != string(entry.hash) { | |
| 75 t.Errorf("EntryFromShadow(%q).password = %q; want %q", c.shadow, entry.hash, c.hash) | |
| 76 } | |
| 77 if c.description != entry.description { | |
| 78 t.Errorf("EntryFromShadow(%q).description = %q; want %q", c.shadow, entry.description, c.description) | |
| 79 } | |
| 80 restEqual := false | |
| 81 if len(c.rest) == len(entry.rest) { | |
| 82 restEqual = true | |
| 83 for i := range c.rest { | |
| 84 if c.rest[i] != entry.rest[i] { | |
| 85 restEqual = false | |
| 86 break | |
| 87 } | |
| 88 } | |
| 89 } | |
| 90 if !restEqual { | |
| 91 t.Errorf("EntryFromShadow(%q).rest = %q; want %q", c.shadow, entry.rest, c.rest) | |
| 92 } | |
| 93 } | |
| 94 } | |
| 95 | |
| 96 func TestNewEntry(t *testing.T) { | |
| 97 cases := []struct { | |
| 98 username string | |
| 99 description string | |
| 100 wantErr bool | |
| 101 }{ | |
| 102 {"pfish", "one", false}, | |
| 103 {"pfish", "the other", false}, | |
| 104 {"with:colons", "", true}, | |
| 105 {"pfish", string(make([]byte, 1000)), true}, | |
| 106 } | |
| 107 for _, c := range cases { | |
| 108 entry, password, err := NewEntry(c.username, c.description) | |
| 109 if c.wantErr { | |
| 110 if err == nil { | |
| 111 t.Errorf("NewEntry(%q, %q) = _, _, nil; want non-nil err", c.username, c.description) | |
| 112 } | |
| 113 continue | |
| 114 } | |
| 115 if err != nil { | |
| 116 t.Errorf("NewEntry(%q, %q) = _, _, %q; want nil err", c.username, c.description, err) | |
| 117 } | |
| 118 if c.username != entry.username { | |
| 119 t.Errorf("NewEntry(%q, %q).username = %q, want %q", | |
| 120 c.username, c.description, entry.username, c.username) | |
| 121 } | |
| 122 if entry.id == 0 { | |
| 123 // This test has a 1/(2**64) chance of failing! :o | |
| 124 t.Errorf("NewEntry(_, _).id == 0, want nonzero") | |
| 125 } | |
| 126 if c.description != entry.description { | |
| 127 t.Errorf("NewEntry(%q, %q).description = %q, want %q", | |
| 128 c.username, c.description, entry.description, c.description) | |
| 129 } | |
| 130 if !passPattern.MatchString(password) { | |
| 131 t.Errorf("NewEntry(_, _) = _, %q, _; wanted to match xxxx-xxxx-xxxx-xxxx", password) | |
| 132 } | |
| 133 if !entry.Authenticate(c.username, password) { | |
| 134 t.Errorf("NewEntry(%q, %q).Authenticate(%q, %q) failed", | |
| 135 c.username, c.description, c.username, password) | |
| 136 } | |
| 137 } | |
| 138 } | |
| 139 | |
| 140 func TestGenPassword(t *testing.T) { | |
| 141 p := genPassword() | |
| 142 if !passPattern.MatchString(string(p)) { | |
| 143 t.Errorf("genPassword() = %q; wanted to match xxxx-xxxx-xxxx-xxxx", p) | |
| 144 } | |
| 145 } | |
| 146 | |
| 147 func TestAuthenticate(t *testing.T) { | |
| 148 entry, password, err := NewEntry("pfish", "") | |
| 149 if err != nil { | |
| 150 t.Errorf("Error building entry") | |
| 151 } | |
| 152 type testcase struct { | |
| 153 username, password string | |
| 154 want bool | |
| 155 } | |
| 156 | |
| 157 cases := []testcase{ | |
| 158 {"pfish", password, true}, | |
| 159 {"jhh", password, false}, | |
| 160 {"pfish", "not the password", false}, | |
| 161 {"jhh", "not the password", false}, | |
| 162 } | |
| 163 for _, c := range cases { | |
| 164 got := entry.Authenticate(c.username, c.password) | |
| 165 if got != c.want { | |
| 166 t.Errorf("entry.Authenticate(%q, %q) == %q, want %q", | |
| 167 c.username, c.password, got, c.want) | |
| 168 } | |
| 169 } | |
| 170 | |
| 171 entry, err = EntryFromShadow(basicShadow) | |
| 172 if err != nil { | |
| 173 t.Errorf("Error loading valid shadow") | |
| 174 } | |
| 175 | |
| 176 cases = []testcase{ | |
| 177 {"jhh", "nocardio", true}, | |
| 178 {"pfish", "nocardio", false}, | |
| 179 {"jhh", "not the password", false}, | |
| 180 {"pfish", "not the password", false}, | |
| 181 } | |
| 182 for _, c := range cases { | |
| 183 got := entry.Authenticate(c.username, c.password) | |
| 184 if got != c.want { | |
| 185 t.Errorf("entry.Authenticate(%q, %q) == %q, want %q", | |
| 186 c.username, c.password, got, c.want) | |
| 187 } | |
| 188 } | |
| 189 } | |
| 190 | |
| 191 func testMatchesID(t *testing.T) { | |
| 192 entry, err := EntryFromShadow(basicShadow) | |
| 193 if err != nil { | |
| 194 t.Errorf("Error loading valid shadow") | |
| 195 } | |
| 196 cases := []struct { | |
| 197 username string | |
| 198 id uint64 | |
| 199 want bool | |
| 200 }{ | |
| 201 {"jhh", 1234, true}, | |
| 202 {"pfish", 1234, false}, | |
| 203 {"jhh", 9999, false}, | |
| 204 {"pfish", 9999, false}, | |
| 205 } | |
| 206 for _, c := range cases { | |
| 207 got := entry.MatchesID(c.username, c.id) | |
| 208 if got != c.want { | |
| 209 t.Errorf("entry.MatchesID(%q, %q) == %q, want %q", | |
| 210 c.username, c.id, got, c.want) | |
| 211 } | |
| 212 } | |
| 213 } | |
| 214 | |
| 215 func TestEncode(t *testing.T) { | |
| 216 // Crafted entry | |
| 217 shadowed, err := EntryFromShadow(basicShadow) | |
| 218 if err != nil { | |
| 219 t.Errorf("Error loading valid shadow") | |
| 220 } | |
| 221 extraShadowed, err := EntryFromShadow(extraDataShadow) | |
| 222 if err != nil { | |
| 223 t.Errorf("Error loading valid shadow") | |
| 224 } | |
| 225 cases := []struct { | |
| 226 entry *Entry | |
| 227 want string | |
| 228 }{ | |
| 229 { | |
| 230 &Entry{ | |
| 231 username: "testuser", | |
| 232 id: 6775, | |
| 233 hash: "bogushash", | |
| 234 description: "something", | |
| 235 }, | |
| 236 "testuser:6775:bogushash:c29tZXRoaW5n", | |
| 237 }, | |
| 238 { | |
| 239 &Entry{ | |
| 240 username: "testuser", | |
| 241 id: 6775, | |
| 242 hash: "bogushash", | |
| 243 description: "something", | |
| 244 rest: []string{"a", "B"}, | |
| 245 }, | |
| 246 "testuser:6775:bogushash:c29tZXRoaW5n:a:B", | |
| 247 }, | |
| 248 {shadowed, basicShadow}, | |
| 249 {extraShadowed, extraDataShadow}, | |
| 250 } | |
| 251 for _, c := range cases { | |
| 252 got := string(c.entry.Encode()) | |
| 253 if got != c.want { | |
| 254 t.Errorf("entry.Encode() = %q, want %q", got, c.want) | |
| 255 } | |
| 256 } | |
| 257 } |
