-
Notifications
You must be signed in to change notification settings - Fork 5
/
cric.go
131 lines (120 loc) · 3.38 KB
/
cric.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package cric
// cric module
//
// Copyright (c) 2020 - Valentin Kuznetsov <vkuznet@gmail.com>
//
import (
"errors"
"fmt"
"log"
"os"
"reflect"
"regexp"
"sync"
"time"
"github.com/dmwm/cmsauth"
)
// CricRecords list to hold CMS CRIC entries
var CricRecords cmsauth.CricRecords
// cmsRecords holds map of CricRecords for CMS users
var cmsRecords cmsauth.CricRecords
// mutex keeps lock for cmsRecords updates
var mutex sync.RWMutex
// int pattern
var intPattern = regexp.MustCompile(`^\d+$`)
// helper function to update cric records
func updateCricRecords(key, cricFile, cricURL string, verbose bool) {
cricRecords := make(cmsauth.CricRecords)
var err error
// use cricFile first if it exists, otherwise use cricURL if it is given
if _, e := os.Stat(cricFile); e == nil {
if key == "id" {
cricRecords, err = cmsauth.ParseCricByKey(cricFile, "id", verbose)
} else {
cricRecords, err = cmsauth.ParseCric(cricFile, verbose)
}
log.Printf("obtain CRIC records from %s using key %s, error %v", cricFile, key, err)
} else if cricURL != "" {
if key == "id" {
cricRecords, err = cmsauth.GetCricDataByKey(cricURL, "id", verbose)
} else {
cricRecords, err = cmsauth.GetCricData(cricURL, verbose)
}
log.Printf("obtain CRIC records from %s using key %s, error %v", cricURL, key, err)
} else {
log.Println("Unable to get CRIC records no file or no url was provided")
}
if err != nil {
log.Printf("Unable to update CRIC records: %v", err)
} else {
CricRecords = cricRecords
keys := reflect.ValueOf(CricRecords).MapKeys()
log.Println("Updated CRIC records", len(keys))
if key == "id" {
cmsRecords = cricRecords
} else {
UpdateCMSRecords(cricRecords)
}
}
}
// UpdateCricRecords periodically updates cric records
// should be run as goroutine
func UpdateCricRecords(key, cricFile, cricURL string, cricUpdateInterval int64, cricVerbose int) {
log.Println("update cric records with", key, "as a key")
verbose := false
if cricVerbose > 0 {
verbose = true
}
iter := 0
for {
interval := cricUpdateInterval
if interval == 0 {
interval = 3600
}
updateCricRecords(key, cricFile, cricURL, verbose)
log.Println("Updated cms records", len(cmsRecords))
if cricVerbose > 2 {
for k, v := range cmsRecords {
log.Printf("key=%s value=%s record=%+v\n", key, k, v)
}
} else if cricVerbose > 0 {
for k, v := range cmsRecords {
log.Printf("key=%s value=%s record=%+v\n", key, k, v)
break // break to avoid lots of CRIC record printous
}
}
d := time.Duration(interval) * time.Second
time.Sleep(d) // sleep for next iteration
iter += 1
}
}
// UpdateCMSRecords updates CMS Records
func UpdateCMSRecords(cricRecords cmsauth.CricRecords) {
if cmsRecords == nil {
cmsRecords = make(cmsauth.CricRecords)
}
// create new local copy of cric records map
recordMap := make(cmsauth.CricRecords)
for _, r := range cricRecords {
for _, dn := range r.DNs {
sortedDN := cmsauth.GetSortedDN(dn)
mutex.Lock()
recordMap[sortedDN] = r
mutex.Unlock()
}
}
// update cmsRecords with new recordMap
cmsRecords = recordMap
}
// FindUser finds user info in cric records for given DN
func FindUser(dn string) (cmsauth.CricEntry, error) {
sortedDN := cmsauth.GetSortedDN(dn)
mutex.RLock()
r, ok := cmsRecords[sortedDN]
mutex.RUnlock()
if ok {
return r, nil
}
msg := fmt.Sprintf("user not found: %v\n", sortedDN)
return cmsauth.CricEntry{}, errors.New(msg)
}