@@ -2,17 +2,19 @@ package main
22
33import (
44 "crypto/tls"
5+ "flag"
56 "fmt"
67 "log"
78 "net/url"
89 "os"
910 "strconv"
1011 "strings"
1112 "time"
12- )
1313
14- import "gopkg.in/ldap.v3"
15- import "github.com/robfig/cron/v3"
14+ "github.com/robfig/cron/v3"
15+ "gopkg.in/ldap.v3"
16+ "gopkg.in/yaml.v2"
17+ )
1618
1719func AddUsersToTeam (apiKeys GiteaKeys , users []Account , team int ) bool {
1820
@@ -50,8 +52,11 @@ func DelUsersFromTeam(apiKeys GiteaKeys, Users []Account, team int) bool {
5052 return true
5153}
5254
53- func main () {
55+ var configFlag = flag . String ( "config" , "config.yaml" , "Specify YAML Configuration File" )
5456
57+ func main () {
58+ // Parse flags of programm
59+ flag .Parse ()
5560 mainJob () // First run for check settings
5661
5762 var repTime string
@@ -66,109 +71,148 @@ func main() {
6671 c .Start ()
6772 fmt .Println (c .Entries ())
6873 for true {
69- time .Sleep (100 * time .Second )
74+ time .Sleep (100 * time .Second )
7075 }
7176}
7277
73- func mainJob () {
78+ // This Function parses the enviroment for application specific variables and returns a Config struct.
79+ // Used for setting all required settings in the application
80+ func importEnvVars () Config {
7481
75- //------------------------------
76- // Check and Set input settings
77- //------------------------------
82+ // Create temporary structs for creating the final config
83+ envConfig := Config {}
7884
79- var apiKeys GiteaKeys
85+ // ApiKeys
86+ envConfig .ApiKeys = GiteaKeys {}
87+ envConfig .ApiKeys .TokenKey = strings .Split (os .Getenv ("GITEA_TOKEN" ), "," )
88+ envConfig .ApiKeys .BaseUrl = os .Getenv ("GITEA_URL" )
8089
81- if len (os .Getenv ("GITEA_TOKEN" )) < 40 { // get on https://[web_site_url]/user/settings/applications
82- log .Println ("GITEA_TOKEN is empty or invalid." )
83- } else {
84- apiKeys .TokenKey = strings .Split (os .Getenv ("GITEA_TOKEN" ), "," )
85- }
86-
87- if len (os .Getenv ("GITEA_URL" )) == 0 {
88- log .Println ("GITEA_URL is empty" )
89- } else {
90- apiKeys .BaseUrl = os .Getenv ("GITEA_URL" )
91- }
90+ // LDAP Config
91+ envConfig .LdapURL = os .Getenv ("LDAP_URL" )
92+ envConfig .LdapBindDN = os .Getenv ("BIND_DN" )
93+ envConfig .LdapBindPassword = os .Getenv ("BIND_PASSWORD" )
94+ envConfig .LdapFilter = os .Getenv ("LDAP_FILTER" )
95+ envConfig .LdapUserSearchBase = os .Getenv ("LDAP_USER_SEARCH_BASE" )
9296
93- var ldapUrl string = "ucs.totalwebservices.net"
94- if len (os .Getenv ("LDAP_URL" )) == 0 {
95- log .Println ("LDAP_URL is empty" )
96- } else {
97- ldapUrl = os .Getenv ("LDAP_URL" )
98- }
99-
100- var ldapPort int
101- var ldapTls bool
97+ // Check TLS Settings
10298 if len (os .Getenv ("LDAP_TLS_PORT" )) > 0 {
10399 port , err := strconv .Atoi (os .Getenv ("LDAP_TLS_PORT" ))
104- ldapPort = port
105- ldapTls = true
106- log .Printf ("DialTLS:=%v:%d" , ldapUrl , ldapPort )
100+ envConfig . LdapPort = port
101+ envConfig . LdapTLS = true
102+ log .Printf ("DialTLS:=%v:%d" , envConfig . LdapURL , envConfig . LdapPort )
107103 if err != nil {
108104 log .Println ("LDAP_TLS_PORT is invalid." )
109105 }
110106 } else {
111107 if len (os .Getenv ("LDAP_PORT" )) > 0 {
112108 port , err := strconv .Atoi (os .Getenv ("LDAP_PORT" ))
113- ldapPort = port
114- ldapTls = false
115- log .Printf ("Dial:=%v:%d" , ldapUrl , ldapPort )
109+ envConfig . LdapPort = port
110+ envConfig . LdapTLS = false
111+ log .Printf ("Dial:=%v:%d" , envConfig . LdapURL , envConfig . LdapPort )
116112 if err != nil {
117113 log .Println ("LDAP_PORT is invalid." )
118114 }
119115 }
120- }
121-
122- var ldapbindDN string
123- if len ( os . Getenv ( "BIND_DN" )) == 0 {
124- log .Println ("BIND_DN is empty " )
116+ }
117+ // Set defaults for user Attributes
118+ if len ( os . Getenv ( "LDAP_USER_IDENTITY_ATTRIBUTE" )) == 0 {
119+ envConfig . LdapUserIdentityAttribute = "uid"
120+ log .Println ("By default LDAP_USER_IDENTITY_ATTRIBUTE = 'uid' " )
125121 } else {
126- ldapbindDN = os .Getenv ("BIND_DN " )
122+ envConfig . LdapUserIdentityAttribute = os .Getenv ("LDAP_USER_IDENTITY_ATTRIBUTE " )
127123 }
128124
129- var ldapbindPassword string
130- if len ( os . Getenv ( "BIND_PASSWORD" )) == 0 {
131- log .Println ("BIND_PASSWORD is empty " )
125+ if len ( os . Getenv ( "LDAP_USER_FULL_NAME" )) == 0 {
126+ envConfig . LdapUserFullName = "sn" //change to cn if you need it
127+ log .Println ("By default LDAP_USER_FULL_NAME = 'sn' " )
132128 } else {
133- ldapbindPassword = os .Getenv ("BIND_PASSWORD " )
129+ envConfig . LdapUserFullName = os .Getenv ("LDAP_USER_FULL_NAME " )
134130 }
135131
136- var ldapUserFilter string
137- if len (os .Getenv ("LDAP_FILTER" )) == 0 {
138- log .Println ("LDAP_FILTER is empty" )
139- } else {
140- ldapUserFilter = os .Getenv ("LDAP_FILTER" )
132+ return envConfig // return the config struct for use.
133+ }
134+
135+ func importYAMLConfig (path string ) (Config , error ) {
136+ // Open Config File
137+ f , err := os .Open (path )
138+ if err != nil {
139+ return Config {}, err // Aborting
141140 }
141+ defer f .Close ()
142142
143- var ldapUserSearchBase string
144- if len (os .Getenv ("LDAP_USER_SEARCH_BASE" )) == 0 {
145- log .Println ("LDAP_USER_SEARCH_BASE is empty" )
146- } else {
147- ldapUserSearchBase = os .Getenv ("LDAP_USER_SEARCH_BASE" )
143+ // Parse File into Config Struct
144+ var cfg Config
145+ decoder := yaml .NewDecoder (f )
146+ err = decoder .Decode (& cfg )
147+ if err != nil {
148+ return Config {}, err // Aborting
148149 }
150+ return cfg , nil
151+ }
149152
150- var ldapUserIdentityAttribute string
151- if len (os .Getenv ("LDAP_USER_IDENTITY_ATTRIBUTE" )) == 0 {
152- ldapUserIdentityAttribute = "uid"
153- log .Println ("By default LDAP_USER_IDENTITY_ATTRIBUTE = 'uid'" )
153+ func (c Config ) checkConfig () {
154+ if len (c .ApiKeys .TokenKey ) <= 0 {
155+ log .Println ("GITEA_TOKEN is empty or invalid." )
156+ }
157+ if len (c .ApiKeys .BaseUrl ) == 0 {
158+ log .Println ("GITEA_URL is empty" )
159+ }
160+ if len (c .LdapURL ) == 0 {
161+ log .Println ("LDAP_URL is empty" )
162+ }
163+ if c .LdapPort <= 0 {
164+ log .Println ("LDAP_TLS_PORT is invalid." )
154165 } else {
155- ldapUserIdentityAttribute = os . Getenv ( "LDAP_USER_IDENTITY_ATTRIBUTE" )
166+ log . Printf ( "DialTLS:=%v:%d" , c . LdapURL , c . LdapPort )
156167 }
157-
158- var ldapUserFullName string
159- if len (os .Getenv ("LDAP_USER_FULL_NAME" )) == 0 {
160- ldapUserFullName = "sn" //change to cn if you need it
168+ if len (c .LdapBindDN ) == 0 {
169+ log .Println ("BIND_DN is empty" )
170+ }
171+ if len (c .LdapBindPassword ) == 0 {
172+ log .Println ("BIND_PASSWORD is empty" )
173+ }
174+ if len (c .LdapFilter ) == 0 {
175+ log .Println ("LDAP_FILTER is empty" )
176+ }
177+ if len (c .LdapUserSearchBase ) == 0 {
178+ log .Println ("LDAP_USER_SEARCH_BASE is empty" )
179+ }
180+ if len (c .LdapUserIdentityAttribute ) == 0 {
181+ c .LdapUserIdentityAttribute = "uid"
182+ log .Println ("By default LDAP_USER_IDENTITY_ATTRIBUTE = 'uid'" )
183+ }
184+ if len (c .LdapUserFullName ) == 0 {
185+ c .LdapUserFullName = "sn" //change to cn if you need it
161186 log .Println ("By default LDAP_USER_FULL_NAME = 'sn'" )
187+ }
188+ }
189+
190+ func mainJob () {
191+
192+ //------------------------------
193+ // Check and Set input settings
194+ //------------------------------
195+ var cfg Config
196+
197+ cfg , importErr := importYAMLConfig (* configFlag )
198+ if importErr != nil {
199+ log .Println ("Fallback: Importing Settings from Enviroment Variables " )
200+ cfg = importEnvVars ()
162201 } else {
163- ldapUserFullName = os .Getenv ("LDAP_USER_FULL_NAME" )
202+ log .Println ("Successfully imported YAML Config from " + * configFlag )
203+ fmt .Println (cfg )
164204 }
205+ // Checks Config
206+ cfg .checkConfig ()
207+ log .Println ("Checked config elements" )
165208
209+ // Prepare LDAP Connection
166210 var l * ldap.Conn
167211 var err error
168- if ldapTls {
169- l , err = ldap .DialTLS ("tcp" , fmt .Sprintf ("%s:%d" , ldapUrl , ldapPort ), & tls.Config {InsecureSkipVerify : true })
212+ if cfg . LdapTLS {
213+ l , err = ldap .DialTLS ("tcp" , fmt .Sprintf ("%s:%d" , cfg . LdapURL , cfg . LdapPort ), & tls.Config {InsecureSkipVerify : true })
170214 } else {
171- l , err = ldap .Dial ("tcp" , fmt .Sprintf ("%s:%d" , ldapUrl , ldapPort ))
215+ l , err = ldap .Dial ("tcp" , fmt .Sprintf ("%s:%d" , cfg . LdapURL , cfg . LdapPort ))
172216 }
173217
174218 if err != nil {
@@ -178,16 +222,16 @@ func mainJob() {
178222 }
179223 defer l .Close ()
180224
181- err = l .Bind (ldapbindDN , ldapbindPassword )
225+ err = l .Bind (cfg . LdapBindDN , cfg . LdapBindPassword )
182226 if err != nil {
183227 log .Fatal (err )
184228 }
185229 page := 1
186- apiKeys .BruteforceTokenKey = 0
187- apiKeys .Command = "/api/v1/admin/orgs?page=" + fmt .Sprintf ("%d" , page ) + "&limit=20&access_token=" // List all organizations
188- organizationList := RequestOrganizationList (apiKeys )
230+ cfg . ApiKeys .BruteforceTokenKey = 0
231+ cfg . ApiKeys .Command = "/api/v1/admin/orgs?page=" + fmt .Sprintf ("%d" , page ) + "&limit=20&access_token=" // List all organizations
232+ organizationList := RequestOrganizationList (cfg . ApiKeys )
189233
190- log .Printf ("%d organizations were found on the server: %s" , len (organizationList ), apiKeys .BaseUrl )
234+ log .Printf ("%d organizations were found on the server: %s" , len (organizationList ), cfg . ApiKeys .BaseUrl )
191235
192236 for 1 < len (organizationList ) {
193237
@@ -197,21 +241,21 @@ func mainJob() {
197241
198242 log .Printf ("Begin an organization review: OrganizationName= %v, OrganizationId= %d \n " , organizationList [i ].Name , organizationList [i ].Id )
199243
200- apiKeys .Command = "/api/v1/orgs/" + organizationList [i ].Name + "/teams?access_token="
201- teamList := RequestTeamList (apiKeys )
244+ cfg . ApiKeys .Command = "/api/v1/orgs/" + organizationList [i ].Name + "/teams?access_token="
245+ teamList := RequestTeamList (cfg . ApiKeys )
202246 log .Printf ("%d teams were found in %s organization" , len (teamList ), organizationList [i ].Name )
203247 log .Printf ("Skip synchronization in the Owners team" )
204- apiKeys .BruteforceTokenKey = 0
248+ cfg . ApiKeys .BruteforceTokenKey = 0
205249
206250 for j := 1 ; j < len (teamList ); j ++ {
207251
208252 // preparing request to ldap server
209- filter := fmt .Sprintf (ldapUserFilter , teamList [j ].Name )
253+ filter := fmt .Sprintf (cfg . LdapFilter , teamList [j ].Name )
210254 searchRequest := ldap .NewSearchRequest (
211- ldapUserSearchBase , // The base dn to search
255+ cfg . LdapUserSearchBase , // The base dn to search
212256 ldap .ScopeWholeSubtree , ldap .NeverDerefAliases , 0 , 0 , false ,
213257 filter , // The filter to apply
214- []string {"cn" , "uid" , "mailPrimaryAddress, sn" , ldapUserIdentityAttribute }, // A list attributes to retrieve
258+ []string {"cn" , "uid" , "mailPrimaryAddress, sn" , cfg . LdapUserIdentityAttribute }, // A list attributes to retrieve
215259 nil ,
216260 )
217261 // make request to ldap server
@@ -223,45 +267,45 @@ func mainJob() {
223267 AccountsGitea := make (map [string ]Account )
224268 var addUserToTeamList , delUserToTeamlist []Account
225269 if len (sr .Entries ) > 0 {
226- log .Printf ("The LDAP %s has %d users corresponding to team %s" , ldapUrl , len (sr .Entries ), teamList [j ].Name )
270+ log .Printf ("The LDAP %s has %d users corresponding to team %s" , cfg . LdapURL , len (sr .Entries ), teamList [j ].Name )
227271 for _ , entry := range sr .Entries {
228272
229- AccountsLdap [entry .GetAttributeValue (ldapUserIdentityAttribute )] = Account {
230- Full_name : entry .GetAttributeValue (ldapUserFullName ),
231- Login : entry .GetAttributeValue (ldapUserIdentityAttribute ),
273+ AccountsLdap [entry .GetAttributeValue (cfg . LdapUserIdentityAttribute )] = Account {
274+ Full_name : entry .GetAttributeValue (cfg . LdapUserFullName ),
275+ Login : entry .GetAttributeValue (cfg . LdapUserIdentityAttribute ),
232276 }
233277 }
234278
235- apiKeys .Command = "/api/v1/teams/" + fmt .Sprintf ("%d" , teamList [j ].Id ) + "/members?access_token="
236- AccountsGitea , apiKeys . BruteforceTokenKey = RequestUsersList (apiKeys )
237- log .Printf ("The gitea %s has %d users corresponding to team %s Teamid=%d" , apiKeys .BaseUrl , len (AccountsGitea ), teamList [j ].Name , teamList [j ].Id )
279+ cfg . ApiKeys .Command = "/api/v1/teams/" + fmt .Sprintf ("%d" , teamList [j ].Id ) + "/members?access_token="
280+ AccountsGitea , cfg . ApiKeys . BruteforceTokenKey = RequestUsersList (cfg . ApiKeys )
281+ log .Printf ("The gitea %s has %d users corresponding to team %s Teamid=%d" , cfg . ApiKeys .BaseUrl , len (AccountsGitea ), teamList [j ].Name , teamList [j ].Id )
238282
239283 for k , v := range AccountsLdap {
240284 if AccountsGitea [k ].Login != v .Login {
241285 addUserToTeamList = append (addUserToTeamList , v )
242286 }
243287 }
244288 log .Printf ("can be added users list %v" , addUserToTeamList )
245- AddUsersToTeam (apiKeys , addUserToTeamList , teamList [j ].Id )
289+ AddUsersToTeam (cfg . ApiKeys , addUserToTeamList , teamList [j ].Id )
246290
247291 for k , v := range AccountsGitea {
248292 if AccountsLdap [k ].Login != v .Login {
249293 delUserToTeamlist = append (delUserToTeamlist , v )
250294 }
251295 }
252296 log .Printf ("must be del users list %v" , delUserToTeamlist )
253- DelUsersFromTeam (apiKeys , delUserToTeamlist , teamList [j ].Id )
297+ DelUsersFromTeam (cfg . ApiKeys , delUserToTeamlist , teamList [j ].Id )
254298
255299 } else {
256- log .Printf ("The LDAP %s not found users corresponding to team %s" , ldapUrl , teamList [j ].Name )
300+ log .Printf ("The LDAP %s not found users corresponding to team %s" , cfg . LdapURL , teamList [j ].Name )
257301 }
258302 }
259303 }
260304
261305 page ++
262- apiKeys .BruteforceTokenKey = 0
263- apiKeys .Command = "/api/v1/admin/orgs?page=" + fmt .Sprintf ("%d" , page ) + "&limit=20&access_token=" // List all organizations
264- organizationList = RequestOrganizationList (apiKeys )
265- log .Printf ("%d organizations were found on the server: %s" , len (organizationList ), apiKeys .BaseUrl )
306+ cfg . ApiKeys .BruteforceTokenKey = 0
307+ cfg . ApiKeys .Command = "/api/v1/admin/orgs?page=" + fmt .Sprintf ("%d" , page ) + "&limit=20&access_token=" // List all organizations
308+ organizationList = RequestOrganizationList (cfg . ApiKeys )
309+ log .Printf ("%d organizations were found on the server: %s" , len (organizationList ), cfg . ApiKeys .BaseUrl )
266310 }
267311}
0 commit comments