func ExamplePassword_Check() { // This will usually come from the database. In this case, the encoded // password is "gondola". encoded := "sha1:4096:JJf2f46fmbw06LwXJ308:9b4d23006b93e1d6bb052c1545d9532d1433736b" // This will usually come from a form, filled in by the user for signing in. plain := "gondola" p := password.Password(encoded) if p.Check(plain) == nil { // Plaintext password matches the stored one. fmt.Println("Password is", plain) } // Output: Password is gondola }
func (f *Form) makeField(name string) (*Field, error) { var s *structs.Struct idx := -1 var fieldValue reflect.Value var sval reflect.Value for ii, v := range f.structs { pos, ok := v.QNameMap[name] if ok { if s != nil { return nil, fmt.Errorf("duplicate field %q (found in %v and %v)", name, s.Type, v.Type) } s = v idx = pos sval = f.values[ii] fieldValue = fieldByIndex(sval, s.Indexes[pos]) // Check the validation function, so if the function is not valid // the error is generated at form instantiation. if _, err := structs.ValidationFunction(sval, name); err != nil { return nil, err } } } if idx < 0 { return nil, fmt.Errorf("can't map form field %q", name) } tag := s.Tags[idx] label := tag.Value("label") if label == "" { label = stringutil.CamelCaseToWords(name, " ") } var typ Type if tag.Has("hidden") { typ = HIDDEN } else if tag.Has("radio") { typ = RADIO } else if tag.Has("select") { typ = SELECT } else { switch s.Types[idx].Kind() { case reflect.Func: return nil, nil case reflect.String: if s.Types[idx] == reflect.TypeOf(password.Password("")) || tag.Has("password") { typ = PASSWORD } else if tag.Has("email") { typ = EMAIL } else { if ml, ok := tag.MaxLength(); ok && ml > 0 { typ = TEXT } else if tag.Has("singleline") || tag.Has("line") { typ = TEXT } else if tag.Has("password") { typ = PASSWORD } else { typ = TEXTAREA } } case reflect.Bool: typ = CHECKBOX case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64: typ = TEXT default: if s.Types[idx] == fileType { typ = FILE break } return nil, fmt.Errorf("field %q has invalid type %v", name, s.Types[idx]) } } // Check if the struct implements the ChoicesProvider interface if typ == RADIO || typ == SELECT { container := sval.Addr().Interface() if _, ok := container.(ChoicesProvider); !ok { return nil, fmt.Errorf("field %q requires choices, but %T does not implement ChoicesProvider", name, container) } } htmlName := f.toHTMLName(name) field := &Field{ Type: typ, Name: name, HTMLName: htmlName, Label: i18n.String(label), Placeholder: i18n.String(tag.Value("placeholder")), Help: i18n.String(tag.Value("help")), id: htmlName, value: fieldValue, s: s, sval: sval, pos: idx, } return field, nil }