Skip to content

Commit dc731cf

Browse files
committed
feat: add regex support in user and oauth whitelist
1 parent ab4efdc commit dc731cf

4 files changed

Lines changed: 134 additions & 25 deletions

File tree

internal/auth/auth.go

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ package auth
33
import (
44
"fmt"
55
"regexp"
6-
"slices"
76
"strings"
87
"sync"
98
"time"
109
"tinyauth/internal/docker"
1110
"tinyauth/internal/types"
11+
"tinyauth/internal/utils"
1212

1313
"github.com/gin-gonic/gin"
1414
"github.com/gorilla/sessions"
@@ -278,27 +278,14 @@ func (auth *Auth) ResourceAllowed(c *gin.Context, context types.UserContext) (bo
278278

279279
// Check if oauth is allowed
280280
if context.OAuth {
281-
if len(labels.OAuthWhitelist) == 0 {
282-
return true, nil
283-
}
284281
log.Debug().Msg("Checking OAuth whitelist")
285-
if slices.Contains(labels.OAuthWhitelist, context.Username) {
286-
return true, nil
287-
}
282+
return utils.CheckWhitelist(labels.OAuthWhitelist, context.Username), nil
288283
}
289284

290-
// Check if user is allowed
291-
if len(labels.Users) != 0 {
292-
log.Debug().Msg("Checking users")
293-
if slices.Contains(labels.Users, context.Username) {
294-
return true, nil
295-
}
296-
} else {
297-
return true, nil
298-
}
285+
// Check users
286+
log.Debug().Msg("Checking users")
299287

300-
// Not allowed
301-
return false, nil
288+
return utils.CheckWhitelist(labels.Users, context.Username), nil
302289
}
303290

304291
func (auth *Auth) AuthEnabled(c *gin.Context) (bool, error) {

internal/types/types.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ type SessionCookie struct {
3131

3232
// TinyauthLabels is the labels for the tinyauth container
3333
type TinyauthLabels struct {
34-
OAuthWhitelist []string
35-
Users []string
34+
OAuthWhitelist string
35+
Users string
3636
Allowed string
3737
Headers map[string]string
3838
}

internal/utils/utils.go

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"errors"
55
"net/url"
66
"os"
7+
"regexp"
78
"slices"
89
"strings"
910
"tinyauth/internal/constants"
@@ -188,9 +189,9 @@ func GetTinyauthLabels(labels map[string]string) types.TinyauthLabels {
188189
// Add the label value to the tinyauth labels struct
189190
switch label {
190191
case "tinyauth.oauth.whitelist":
191-
tinyauthLabels.OAuthWhitelist = strings.Split(value, ",")
192+
tinyauthLabels.OAuthWhitelist = value
192193
case "tinyauth.users":
193-
tinyauthLabels.Users = strings.Split(value, ",")
194+
tinyauthLabels.Users = value
194195
case "tinyauth.allowed":
195196
tinyauthLabels.Allowed = value
196197
case "tinyauth.headers":
@@ -283,3 +284,42 @@ func ParseSecretFile(contents string) string {
283284
// Return an empty string
284285
return ""
285286
}
287+
288+
// Check if a string matches a regex or a whitelist
289+
func CheckWhitelist(whitelist string, str string) bool {
290+
// Check if the whitelist is empty
291+
if len(whitelist) == 0 {
292+
return true
293+
}
294+
295+
// Check if the whitelist is a regex
296+
if strings.HasPrefix(whitelist, "/") && strings.HasSuffix(whitelist, "/") {
297+
// Create regex
298+
re, err := regexp.Compile(whitelist[1 : len(whitelist)-1])
299+
300+
// Check if there was an error
301+
if err != nil {
302+
log.Error().Err(err).Msg("Error compiling regex")
303+
return false
304+
}
305+
306+
// Check if the string matches the regex
307+
if re.MatchString(str) {
308+
return true
309+
}
310+
}
311+
312+
// Split the whitelist by comma
313+
whitelistSplit := strings.Split(whitelist, ",")
314+
315+
// Loop through the whitelist
316+
for _, item := range whitelistSplit {
317+
// Check if the item matches with the string
318+
if strings.TrimSpace(item) == str {
319+
return true
320+
}
321+
}
322+
323+
// Return false if no match was found
324+
return false
325+
}

internal/utils/utils_test.go

Lines changed: 85 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,15 +286,19 @@ func TestGetTinyauthLabels(t *testing.T) {
286286
// Test the get tinyauth labels function with a valid map
287287
labels := map[string]string{
288288
"tinyauth.users": "user1,user2",
289-
"tinyauth.oauth.whitelist": "user1,user2",
289+
"tinyauth.oauth.whitelist": "/regex/",
290290
"tinyauth.allowed": "random",
291291
"random": "random",
292+
"tinyauth.headers": "X-Header=value",
292293
}
293294

294295
expected := types.TinyauthLabels{
295-
Users: []string{"user1", "user2"},
296-
OAuthWhitelist: []string{"user1", "user2"},
296+
Users: "user1,user2",
297+
OAuthWhitelist: "/regex/",
297298
Allowed: "random",
299+
Headers: map[string]string{
300+
"X-Header": "value",
301+
},
298302
}
299303

300304
result := utils.GetTinyauthLabels(labels)
@@ -385,3 +389,81 @@ func TestParseUser(t *testing.T) {
385389
t.Fatalf("Expected error parsing user")
386390
}
387391
}
392+
393+
// Test the whitelist function
394+
func TestCheckWhitelist(t *testing.T) {
395+
t.Log("Testing check whitelist with a comma whitelist")
396+
397+
// Create variables
398+
whitelist := "user1,user2,user3"
399+
str := "user1"
400+
expected := true
401+
402+
// Test the check whitelist function
403+
result := utils.CheckWhitelist(whitelist, str)
404+
405+
// Check if the result is equal to the expected
406+
if result != expected {
407+
t.Fatalf("Expected %v, got %v", expected, result)
408+
}
409+
410+
t.Log("Testing check whitelist with a regex whitelist")
411+
412+
// Create variables
413+
whitelist = "/^user[0-9]+$/"
414+
str = "user1"
415+
expected = true
416+
417+
// Test the check whitelist function
418+
result = utils.CheckWhitelist(whitelist, str)
419+
420+
// Check if the result is equal to the expected
421+
if result != expected {
422+
t.Fatalf("Expected %v, got %v", expected, result)
423+
}
424+
425+
t.Log("Testing check whitelist with an empty whitelist")
426+
427+
// Create variables
428+
whitelist = ""
429+
str = "user1"
430+
expected = true
431+
432+
// Test the check whitelist function
433+
result = utils.CheckWhitelist(whitelist, str)
434+
435+
// Check if the result is equal to the expected
436+
if result != expected {
437+
t.Fatalf("Expected %v, got %v", expected, result)
438+
}
439+
440+
t.Log("Testing check whitelist with an invalid regex whitelist")
441+
442+
// Create variables
443+
whitelist = "/^user[0-9+$/"
444+
str = "user1"
445+
expected = false
446+
447+
// Test the check whitelist function
448+
result = utils.CheckWhitelist(whitelist, str)
449+
450+
// Check if the result is equal to the expected
451+
if result != expected {
452+
t.Fatalf("Expected %v, got %v", expected, result)
453+
}
454+
455+
t.Log("Testing check whitelist with a non matching whitelist")
456+
457+
// Create variables
458+
whitelist = "user1,user2,user3"
459+
str = "user4"
460+
expected = false
461+
462+
// Test the check whitelist function
463+
result = utils.CheckWhitelist(whitelist, str)
464+
465+
// Check if the result is equal to the expected
466+
if result != expected {
467+
t.Fatalf("Expected %v, got %v", expected, result)
468+
}
469+
}

0 commit comments

Comments
 (0)