From 436399e8eacdb18c96fe60b9b37b55615be83ed3 Mon Sep 17 00:00:00 2001 From: Ralf Haferkamp Date: Wed, 2 Mar 2022 16:53:11 +0100 Subject: [PATCH 1/2] idm: Allow to create demo and service users on startup Uses go:embed to include the demo and service users from LDIF. Using a template file for the service users to be able to set custom passwords via config/env. In order to switch ocis to use idm instead of accounts/glauth it currently needs to be started with this env: GRAPH_IDENTITY_BACKEND=ldap GRAPH_LDAP_URI=ldaps://localhost:9235 GRAPH_LDAP_BIND_DN="uid=libregraph,ou=sysusers,o=libregraph-idm" GRAPH_LDAP_BIND_PASSWORD=idm GRAPH_LDAP_USER_EMAIL_ATTRIBUTE=mail GRAPH_LDAP_USER_NAME_ATTRIBUTE=uid GRAPH_LDAP_USER_BASE_DN="ou=users,o=libregraph-idm" GRAPH_LDAP_GROUP_BASE_DN="ou=groups,o=libregraph-idm" GRAPH_LDAP_SERVER_WRITE_ENABLED="true" IDP_LDAP_FILTER="(&(objectclass=inetOrgPerson)(objectClass=owncloud))" IDP_LDAP_URI=ldaps://localhost:9235 IDP_LDAP_BIND_DN="uid=idp,ou=sysusers,o=libregraph-idm" IDP_LDAP_BIND_PASSWORD="idp" IDP_LDAP_BASE_DN="ou=users,o=libregraph-idm" IDP_LDAP_LOGIN_ATTRIBUTE=uid IDP_LDAP_UUID_ATTRIBUTE="ownclouduuid" IDP_LDAP_UUID_ATTRIBUTE_TYPE=binary PROXY_ACCOUNT_BACKEND_TYPE=cs3 OCS_ACCOUNT_BACKEND_TYPE=cs3 STORAGE_LDAP_HOSTNAME=localhost STORAGE_LDAP_PORT=9235 STORAGE_LDAP_INSECURE="true" STORAGE_LDAP_BASE_DN="o=libregraph-idm" STORAGE_LDAP_BIND_DN="uid=reva,ou=sysusers,o=libregraph-idm" STORAGE_LDAP_BIND_PASSWORD=reva STORAGE_LDAP_LOGINFILTER='(&(objectclass=inetOrgPerson)(objectclass=owncloud)(|(uid={{login}})(mail={{login}})))' STORAGE_LDAP_USERFILTER='(&(objectclass=inetOrgPerson)(objectclass=owncloud)(|(ownclouduuid={{.OpaqueId}})(uid={{.OpaqueId}})))' STORAGE_LDAP_USERATTRIBUTEFILTER='(&(objectclass=owncloud)({{attr}}={{value}}))' STORAGE_LDAP_USERFINDFILTER='(&(objectclass=owncloud)(|(uid={{query}}*)(cn={{query}}*)(displayname={{query}}*)(mail={{query}}*)(description={{query}}*)))' STORAGE_LDAP_GROUPFILTER='(&(objectclass=groupOfNames)(objectclass=owncloud)(ownclouduuid={{.OpaqueId}}*))' OCIS_INSECURE=true --- idm/idm.go | 11 +++ idm/ldif/base.ldif.tmpl | 24 +++++ idm/ldif/demousers.ldif | 162 ++++++++++++++++++++++++++++++++ idm/pkg/command/server.go | 79 +++++++++------- idm/pkg/config/config.go | 20 ++-- idm/pkg/config/defaultconfig.go | 15 ++- 6 files changed, 266 insertions(+), 45 deletions(-) create mode 100644 idm/idm.go create mode 100644 idm/ldif/base.ldif.tmpl create mode 100644 idm/ldif/demousers.ldif diff --git a/idm/idm.go b/idm/idm.go new file mode 100644 index 0000000000..be4a60e545 --- /dev/null +++ b/idm/idm.go @@ -0,0 +1,11 @@ +package idm + +import ( + _ "embed" +) + +//go:embed ldif/base.ldif.tmpl +var BaseLDIF string + +//go:embed ldif/demousers.ldif +var DemoUsersLDIF string diff --git a/idm/ldif/base.ldif.tmpl b/idm/ldif/base.ldif.tmpl new file mode 100644 index 0000000000..5c290ad17a --- /dev/null +++ b/idm/ldif/base.ldif.tmpl @@ -0,0 +1,24 @@ +dn: o=libregraph-idm +o: libregraph-idm +objectClass: organization + +dn: ou=users,o=libregraph-idm +objectClass: organizationalUnit +ou: users + +dn: ou=sysusers,o=libregraph-idm +objectClass: organizationalUnit +ou: users + +dn: ou=groups,o=libregraph-idm +objectClass: organizationalUnit +ou: groups + +{{ range . -}} +dn: uid={{ .Name }},ou=sysusers,o=libregraph-idm +objectClass: account +objectClass: simpleSecurityObject +uid: {{ .Name }} +userPassword:: {{ .Password }} + +{{ end -}} diff --git a/idm/ldif/demousers.ldif b/idm/ldif/demousers.ldif new file mode 100644 index 0000000000..8bfdf2461b --- /dev/null +++ b/idm/ldif/demousers.ldif @@ -0,0 +1,162 @@ +dn: uid=einstein,ou=users,o=libregraph-idm +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: ownCloud +objectClass: person +objectClass: top +uid: einstein +givenName: Albert +sn: Einstein +cn: einstein +displayName: Albert Einstein +description: A German-born theoretical physicist who developed the theory of relativity, one of the two pillars of modern physics (alongside quantum mechanics). +mail: einstein@example.org +ownCloudUUID: 4c510ada-c86b-4815-8820-42cdf82c3d51 +userPassword:: e0FSR09OMn0kYXJnb24yaWQkdj0xOSRtPTY1NTM2LHQ9MSxwPTIkOFpyclR0NXA1a0VmVlhL + akNHaVBEUSRnemZCWWwrTHdzTUhXQWJSMEJ2NnRiZk1XZjZaOVJ0Mms5Z3VkSWJ5bzg4 + +dn: uid=marie,ou=users,o=libregraph-idm +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: ownCloud +objectClass: person +objectClass: top +uid: marie +givenName: Marie +sn: Curie +cn: marie +displayName: Marie Skłodowska Curie +description: A Polish and naturalized-French physicist and chemist who conducted pioneering research on radioactivity. +mail: marie@example.org +ownCloudUUID: f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c +userPassword:: e0FSR09OMn0kYXJnb24yaWQkdj0xOSRtPTY1NTM2LHQ9MSxwPTIkUHJzWkpQQW9pMkFwZHlJ + a2Q1NGkzQSRnalZzR3doTmk2K0djenJ4SVdPalN2UlBpWXhKSXpHVG4vcnpQZzkvSlZN + +dn: uid=richard,ou=users,o=libregraph-idm +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: ownCloud +objectClass: person +objectClass: top +uid: richard +givenName: Richard +sn: Feynman +cn: richard +displayName: Richard Phillips Feynman +description: An American theoretical physicist, known for his work in the path integral formulation of quantum mechanics, the theory of quantum electrodynamics, the physics of the superfluidity of supercooled liquid helium, as well as his work in particle physics for which he proposed the parton model. +mail: richard@example.org +ownCloudUUID: 932b4540-8d16-481e-8ef4-588e4b6b151c +userPassword:: e0FSR09OMn0kYXJnb24yaWQkdj0xOSRtPTY1NTM2LHQ9MSxwPTIkNjlNcUQxem5sUUZ2SUha + d2dxU00xQSRVQmNEa2NDZktMemVpQnlyb0JjOTdCSVRhTFo2WjZIL2dhbytSTVh6OHhn + +dn: uid=moss,ou=users,o=libregraph-idm +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: ownCloud +objectClass: person +objectClass: top +uid: moss +givenName: Maurice +sn: Moss +cn: moss +displayName: Maurice Moss +description: A worker in the IT Department of Reynholm Industries. Of all the working staff in the IT Department, he is the most hard-working, the most experienced, and the most capable of doing his job well. He puts a lot of effort into his work, however he does not get the credit he deserves. +mail: moss@example.org +ownCloudUUID: 058bff95-6708-4fe5-91e4-9ea3d377588b +userPassword:: e0FSR09OMn0kYXJnb24yaWQkdj0xOSRtPTY1NTM2LHQ9MSxwPTIkZU0xaXR6amQ2dlNSSERx + NlZCbXBlQSQxNzBhcTB3YjJZZ2NLU2cwWDhHY3l6ckZwMUllcGplMTNraDdVNjUyNXk4 + +dn: uid=admin,ou=users,o=libregraph-idm +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: ownCloud +objectClass: person +objectClass: top +uid: admin +givenName: Admin +sn: Admin +cn: admin +displayName: Admin +description: An admin for this oCIS instance. +mail: admin@example.org +ownCloudUUID: ddc2004c-0977-11eb-9d3f-a793888cd0f8 +userPassword:: e0FSR09OMn0kYXJnb24yaWQkdj0xOSRtPTY1NTM2LHQ9MSxwPTIkRXdwYUhJeVErcG9wdkcv + Tk81R0o2USRNWHp4czNvdHBhOWp3S0hxc1lLMlZodzAralUxSFowMUNpOXducWZlT1pn + +dn: cn=users,ou=groups,o=libregraph-idm +objectClass: groupOfNames +objectClass: ownCloud +objectClass: top +cn: users +description: Users +ownCloudUUID: 509a9dcd-bb37-4f4f-a01a-19dca27d9cfa +member: uid=einstein,ou=users,o=libregraph-idm +member: uid=marie,ou=users,o=libregraph-idm +member: uid=richard,ou=users,o=libregraph-idm +member: uid=moss,ou=users,o=libregraph-idm +member: uid=admin,ou=users,o=libregraph-idm + +dn: cn=sailing-lovers,ou=groups,o=libregraph-idm +objectClass: groupOfNames +objectClass: ownCloud +objectClass: top +cn: sailing-lovers +description: Sailing lovers +ownCloudUUID: 6040aa17-9c64-4fef-9bd0-77234d71bad0 +member: uid=einstein,ou=users,o=libregraph-idm + +dn: cn=violin-haters,ou=groups,o=libregraph-idm +objectClass: groupOfNames +objectClass: ownCloud +objectClass: top +cn: violin-haters +description: Violin haters +ownCloudUUID: dd58e5ec-842e-498b-8800-61f2ec6f911f +member: uid=einstein,ou=users,o=libregraph-idm + +dn: cn=radium-lovers,ou=groups,o=libregraph-idm +objectClass: groupOfNames +objectClass: ownCloud +objectClass: top +cn: radium-lovers +description: Radium lovers +ownCloudUUID: 7b87fd49-286e-4a5f-bafd-c535d5dd997a +member: uid=marie,ou=users,o=libregraph-idm + +dn: cn=polonium-lovers,ou=groups,o=libregraph-idm +objectClass: groupOfNames +objectClass: ownCloud +objectClass: top +cn: polonium-lovers +description: Polonium lovers +ownCloudUUID: cedc21aa-4072-4614-8676-fa9165f598ff +member: uid=marie,ou=users,o=libregraph-idm + +dn: cn=quantum-lovers,ou=groups,o=libregraph-idm +objectClass: groupOfNames +objectClass: ownCloud +objectClass: top +cn: quantum-lovers +description: Quantum lovers +ownCloudUUID: a1726108-01f8-4c30-88df-2b1a9d1cba1a +member: uid=richard,ou=users,o=libregraph-idm + +dn: cn=philosophy-haters,ou=groups,o=libregraph-idm +objectClass: groupOfNames +objectClass: ownCloud +objectClass: top +cn: philosophy-haters +description: Philosophy haters +ownCloudUUID: 167cbee2-0518-455a-bfb2-031fe0621e5d +member: uid=richard,ou=users,o=libregraph-idm + +dn: cn=physics-lovers,ou=groups,o=libregraph-idm +objectClass: groupOfNames +objectClass: ownCloud +objectClass: top +cn: physics-lovers +description: Physics lovers +ownCloudUUID: 262982c1-2362-4afa-bfdf-8cbfef64a06e +member: uid=einstein,ou=users,o=libregraph-idm +member: uid=marie,ou=users,o=libregraph-idm +member: uid=richard,ou=users,o=libregraph-idm diff --git a/idm/pkg/command/server.go b/idm/pkg/command/server.go index adfe31850a..6306767c67 100644 --- a/idm/pkg/command/server.go +++ b/idm/pkg/command/server.go @@ -13,6 +13,7 @@ import ( "github.com/libregraph/idm/pkg/ldappassword" "github.com/libregraph/idm/pkg/ldbbolt" "github.com/libregraph/idm/server" + "github.com/owncloud/ocis/idm" "github.com/owncloud/ocis/idm/pkg/config" "github.com/owncloud/ocis/idm/pkg/config/parser" "github.com/owncloud/ocis/idm/pkg/logging" @@ -53,7 +54,7 @@ func start(ctx context.Context, logger log.Logger, cfg *config.Config) error { TLSCertFile: cfg.IDM.Cert, TLSKeyFile: cfg.IDM.Key, LDAPBaseDN: "o=libregraph-idm", - LDAPAdminDN: "uid=libregrah,o=libregraph-idm", + LDAPAdminDN: "uid=libregraph,ou=sysusers,o=libregraph-idm", BoltDBFile: cfg.IDM.DatabasePath, } @@ -80,15 +81,26 @@ func start(ctx context.Context, logger log.Logger, cfg *config.Config) error { func bootstrap(logger log.Logger, cfg *config.Config, srvcfg server.Config) error { // Hash password if the config does not supply a hash already - var pwhash string var err error - if strings.HasPrefix(cfg.IDM.AdminPassword, "$argon2id$") { - // password is alread hashed - pwhash = "{ARGON2}" + cfg.IDM.AdminPassword - } else { - if pwhash, err = ldappassword.Hash(cfg.IDM.AdminPassword, "{ARGON2}"); err != nil { - return err - } + + type svcUser struct { + Name string + Password string + } + + serviceUsers := []svcUser{ + { + Name: "libregraph", + Password: cfg.ServiceUserPasswords.IdmAdmin, + }, + { + Name: "idp", + Password: cfg.ServiceUserPasswords.Idp, + }, + { + Name: "reva", + Password: cfg.ServiceUserPasswords.Reva, + }, } bdb := &ldbbolt.LdbBolt{} @@ -103,22 +115,38 @@ func bootstrap(logger log.Logger, cfg *config.Config, srvcfg server.Config) erro } // Prepare the initial Data from template. To be able to set the - // supplied admin password - tmpl, err := template.New("baseldif").Parse(baseldif) + // supplied service user passwords + tmpl, err := template.New("baseldif").Parse(idm.BaseLDIF) if err != nil { return err } + for i := range serviceUsers { + if strings.HasPrefix(serviceUsers[i].Password, "$argon2id$") { + // password is alread hashed + serviceUsers[i].Password = "{ARGON2}" + serviceUsers[i].Password + } else { + if serviceUsers[i].Password, err = ldappassword.Hash(serviceUsers[i].Password, "{ARGON2}"); err != nil { + return err + } + } + // We need to treat the hash as binary in the LDIF template to avoid + // go-ldap/ldif to to any fancy escaping + serviceUsers[i].Password = base64.StdEncoding.EncodeToString([]byte(serviceUsers[i].Password)) + } var tmplWriter strings.Builder - // We need to treat the hash as binary in the LDIF template to avoid - // go-ldap/ldif to to any fancy escaping - b64 := base64.StdEncoding.EncodeToString([]byte(pwhash)) - err = tmpl.Execute(&tmplWriter, b64) + err = tmpl.Execute(&tmplWriter, serviceUsers) if err != nil { return err } - s := strings.NewReader(tmplWriter.String()) + bootstrapData := tmplWriter.String() + + if cfg.CreateDemoUsers { + bootstrapData = bootstrapData + "\n" + idm.DemoUsersLDIF + } + + s := strings.NewReader(bootstrapData) lf := &ldif.LDIF{} err = ldif.Unmarshal(s, lf) if err != nil { @@ -131,23 +159,6 @@ func bootstrap(logger log.Logger, cfg *config.Config, srvcfg server.Config) erro return fmt.Errorf("error adding Entry '%s': %w", entry.DN, err) } } + return nil } - -var baseldif string = `dn: o=libregraph-idm -o: libregraph-idm -objectClass: organization - -dn: ou=users,o=libregraph-idm -objectClass: organizationalUnit -ou: users - -dn: ou=groups,o=libregraph-idm -objectClass: organizationalUnit -ou: groups - -dn: uid=libregraph,o=libregraph-idm -objectClass: account -objectClass: simpleSecurityObject -uid: libregraph -userPassword:: {{.}}` diff --git a/idm/pkg/config/config.go b/idm/pkg/config/config.go index da0fd1bcab..44a97887c8 100644 --- a/idm/pkg/config/config.go +++ b/idm/pkg/config/config.go @@ -16,15 +16,23 @@ type Config struct { Log *Log `ocisConfig:"log"` Debug Debug `ocisConfig:"debug"` - IDM Settings `ocisConfig:"idm"` + IDM Settings `ocisConfig:"idm"` + CreateDemoUsers bool `ocisConfig:"create_demo_users" env:"IDM_CREATE_DEMO_USERS;ACCOUNTS_DEMO_USERS_AND_GROUPS" desc:"Flag to enabe/disable the creation of the demo users"` + + ServiceUserPasswords ServiceUserPasswords `ocisConfig:"service_user_passwords"` Context context.Context } type Settings struct { - LDAPSAddr string `ocisConfig:"ldaps_addr" env:"IDM_LDAPS_ADDR"` - Cert string `ocisConfig:"cert" env:"IDM_LDAPS_CERT"` - Key string `ocisConfig:"cert" env:"IDM_LDAPS_KEY"` - DatabasePath string `ocisConfig:"database" env:"IDM_DATABASE_PATH"` - AdminPassword string `ocisConfig:"admin_password" env:"IDM_ADMIN_PASSWORD"` + LDAPSAddr string `ocisConfig:"ldaps_addr" env:"IDM_LDAPS_ADDR" desc:"Listen address for the ldaps listener (ip-addr:port)"` + Cert string `ocisConfig:"cert" env:"IDM_LDAPS_CERT" desc:"File name of the TLS server certificate for the ldaps listener"` + Key string `ocisConfig:"cert" env:"IDM_LDAPS_KEY" desc:"File name for the TLS certificate key for the server certificate"` + DatabasePath string `ocisConfig:"database" env:"IDM_DATABASE_PATH" desc:"Full path to the idm backend database"` +} + +type ServiceUserPasswords struct { + IdmAdmin string `ocisConfig:"admin_password" env:"IDM_ADMIN_PASSWORD" desc:"Password to set for the \"idm\" service users. Either cleartext or an argon2id hash"` + Reva string `ocisConfig:"reva_password" env:"IDM_REVASVC_PASSWORD" desc:"Password to set for the \"reva\" service users. Either cleartext or an argon2id hash"` + Idp string `ocisConfig:"idp_password" env:"IDM_IDPSVC_PASSWORD" desc:"Password to set for the \"idp\" service users. Either cleartext or an argon2id hash"` } diff --git a/idm/pkg/config/defaultconfig.go b/idm/pkg/config/defaultconfig.go index aaec93bdea..b82869425f 100644 --- a/idm/pkg/config/defaultconfig.go +++ b/idm/pkg/config/defaultconfig.go @@ -11,12 +11,17 @@ func DefaultConfig() *Config { Service: Service{ Name: "idm", }, + CreateDemoUsers: true, + ServiceUserPasswords: ServiceUserPasswords{ + IdmAdmin: "idm", + Idp: "idp", + Reva: "reva", + }, IDM: Settings{ - LDAPSAddr: "127.0.0.1:9235", - Cert: path.Join(defaults.BaseDataPath(), "idm", "ldap.crt"), - Key: path.Join(defaults.BaseDataPath(), "idm", "ldap.key"), - DatabasePath: path.Join(defaults.BaseDataPath(), "idm", "ocis.boltdb"), - AdminPassword: "admin", + LDAPSAddr: "127.0.0.1:9235", + Cert: path.Join(defaults.BaseDataPath(), "idm", "ldap.crt"), + Key: path.Join(defaults.BaseDataPath(), "idm", "ldap.key"), + DatabasePath: path.Join(defaults.BaseDataPath(), "idm", "ocis.boltdb"), }, } } From 26abb6361bc92b71f52695317d1ecf82551ad782 Mon Sep 17 00:00:00 2001 From: Ralf Haferkamp Date: Wed, 9 Mar 2022 12:33:48 +0100 Subject: [PATCH 2/2] bump libregraph/idm to lastest master --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 3f0e352d70..98d274fb74 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,7 @@ require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.8.0 github.com/iancoleman/strcase v0.2.0 github.com/justinas/alice v1.2.0 - github.com/libregraph/idm v0.3.1-0.20220222123017-f9d520ac1f11 + github.com/libregraph/idm v0.3.1-0.20220309072604-7a05922a056f github.com/libregraph/lico v0.53.1 github.com/mennanov/fieldmask-utils v0.5.0 github.com/mitchellh/mapstructure v1.4.3 diff --git a/go.sum b/go.sum index 1d924b2c00..a622e4d185 100644 --- a/go.sum +++ b/go.sum @@ -939,8 +939,8 @@ github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.3/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk= github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/libregraph/idm v0.3.1-0.20220222123017-f9d520ac1f11 h1:ReFrghRLQhQdt5BW7HXtEzySmsgUCXL1U36gnmka73U= -github.com/libregraph/idm v0.3.1-0.20220222123017-f9d520ac1f11/go.mod h1:wB8ApGAQsXDXXGWEeFimK/3q8Z/jRa+m3nqnvoYjBsQ= +github.com/libregraph/idm v0.3.1-0.20220309072604-7a05922a056f h1:FKa0JYnkhto9Z4UsQHdEM/bxRklqiICaOHhGN+s9cnI= +github.com/libregraph/idm v0.3.1-0.20220309072604-7a05922a056f/go.mod h1:wB8ApGAQsXDXXGWEeFimK/3q8Z/jRa+m3nqnvoYjBsQ= github.com/libregraph/lico v0.53.1 h1:c5JYFg0mrIgk6Ktj77rNJ2K8X01hs28JJ9Vw1N1iMAk= github.com/libregraph/lico v0.53.1/go.mod h1:EXf6Y9s9TygW6unSXosBpVXWUURoN2sPX0053o4zVfQ= github.com/linode/linodego v0.25.3/go.mod h1:GSBKPpjoQfxEfryoCRcgkuUOCuVtGHWhzI8OMdycNTE=