1package client
2
3import (
4	"reflect"
5)
6
7// FieldRegistry is designed to look and feel
8// like an enum from another language like Python.
9//
10// Example: Accessing constants
11//
12//   FieldRegistry.AccountExpires
13//   FieldRegistry.BadPasswordCount
14//
15// Example: Utility methods
16//
17//   FieldRegistry.List()
18//   FieldRegistry.Parse("givenName")
19//
20var FieldRegistry = newFieldRegistry()
21
22// newFieldRegistry iterates through all the fields in the registry,
23// pulls their ldap strings, and sets up each field to contain its ldap string
24func newFieldRegistry() *fieldRegistry {
25	reg := &fieldRegistry{}
26	vOfReg := reflect.ValueOf(reg)
27
28	registryFields := vOfReg.Elem()
29	for i := 0; i < registryFields.NumField(); i++ {
30
31		if registryFields.Field(i).Kind() == reflect.Ptr {
32
33			field := registryFields.Type().Field(i)
34			ldapString := field.Tag.Get("ldap")
35			ldapField := &Field{ldapString}
36			vOfLDAPField := reflect.ValueOf(ldapField)
37
38			registryFields.FieldByName(field.Name).Set(vOfLDAPField)
39
40			reg.fieldList = append(reg.fieldList, ldapField)
41		}
42	}
43	return reg
44}
45
46// fieldRegistry isn't currently intended to be an exhaustive list -
47// there are more fields in LDAP because schema can be defined by the user.
48// Here are some of the more common fields.
49type fieldRegistry struct {
50	CommonName         *Field `ldap:"cn"`
51	DisplayName        *Field `ldap:"displayName"`
52	DistinguishedName  *Field `ldap:"distinguishedName"`
53	DomainComponent    *Field `ldap:"dc"`
54	DomainName         *Field `ldap:"dn"`
55	Name               *Field `ldap:"name"`
56	ObjectCategory     *Field `ldap:"objectCategory"`
57	ObjectClass        *Field `ldap:"objectClass"`
58	ObjectGUID         *Field `ldap:"objectGUID"`
59	ObjectSID          *Field `ldap:"objectSid"`
60	OrganizationalUnit *Field `ldap:"ou"`
61	PasswordLastSet    *Field `ldap:"passwordLastSet"`
62	UnicodePassword    *Field `ldap:"unicodePwd"`
63	UserPassword       *Field `ldap:"userPassword"`
64	UserPrincipalName  *Field `ldap:"userPrincipalName"`
65
66	fieldList []*Field
67}
68
69func (r *fieldRegistry) List() []*Field {
70	return r.fieldList
71}
72
73func (r *fieldRegistry) Parse(s string) *Field {
74	for _, f := range r.List() {
75		if f.String() == s {
76			return f
77		}
78	}
79	return nil
80}
81
82type Field struct {
83	str string
84}
85
86func (f *Field) String() string {
87	return f.str
88}
89