search.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package shell
  15. import (
  16. "fmt"
  17. "strings"
  18. "github.com/go-ldap/ldap/v3"
  19. "yunion.io/x/pkg/util/shellutils"
  20. api "yunion.io/x/onecloud/pkg/apis/identity"
  21. "yunion.io/x/onecloud/pkg/util/ldaputils"
  22. )
  23. func queryScope(scope string) int {
  24. if scope == api.QueryScopeOne {
  25. return ldap.ScopeSingleLevel
  26. } else {
  27. return ldap.ScopeWholeSubtree
  28. }
  29. }
  30. func init() {
  31. type LdapSearchOptions struct {
  32. Base string `help:"base DN, e.g. OU=tech,DC=example,DC=com"`
  33. Objectclass string `help:"objectclass, e.g. organizationalPerson"`
  34. Search []string `help:"search conditions, in format of field:value"`
  35. Field []string `help:"retrieve field info"`
  36. Scope string `help:"query scope" choices:"one|sub" default:"sub"`
  37. PageLimit uint32 `help:"page size" default:"100"`
  38. Limit uint32 `help:"maximal output items"`
  39. }
  40. shellutils.R(&LdapSearchOptions{}, "search", "search ldap", func(cli *ldaputils.SLDAPClient, args *LdapSearchOptions) error {
  41. search := make(map[string]string)
  42. for _, s := range args.Search {
  43. colonPos := strings.IndexByte(s, ':')
  44. if colonPos <= 0 {
  45. return fmt.Errorf("invalid search condition %s", s)
  46. }
  47. search[s[:colonPos]] = s[(colonPos + 1):]
  48. }
  49. total, err := cli.Search(args.Base, args.Objectclass, search, "", args.Field, queryScope(args.Scope), args.PageLimit, args.Limit, func(offset uint32, entry *ldap.Entry) error {
  50. entry.PrettyPrint(2)
  51. return nil
  52. })
  53. if err != nil {
  54. return err
  55. }
  56. fmt.Println("Total:", total)
  57. return nil
  58. })
  59. type LdapAuthOptions struct {
  60. Base string `help:"base DN, e.g. OU=tech,DC=example,DC=com"`
  61. Objectclass string `help:"objectclass, e.g. organizationalPerson"`
  62. ATTR string `help:"account attribute name"`
  63. ACCOUNT string `help:"account name to auth"`
  64. PASSWORD string `help:"Password to auth"`
  65. Field []string `help:"retrieve field info"`
  66. Scope string `help:"query scope" choices:"one|sub" default:"sub"`
  67. }
  68. shellutils.R(&LdapAuthOptions{}, "auth", "authenticate against ldap", func(cli *ldaputils.SLDAPClient, args *LdapAuthOptions) error {
  69. entry, err := cli.Authenticate(args.Base, args.Objectclass, args.ATTR, args.ACCOUNT, args.PASSWORD, "", args.Field, queryScope(args.Scope))
  70. if err != nil {
  71. return err
  72. }
  73. entry.PrettyPrint(2)
  74. return nil
  75. })
  76. }