178 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			178 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Go
		
	
	
	
package basic
 | 
						|
 | 
						|
import (
 | 
						|
	"os"
 | 
						|
 | 
						|
	. "github.com/onsi/ginkgo/v2"
 | 
						|
	. "github.com/onsi/gomega"
 | 
						|
	"github.com/onsi/gomega/types"
 | 
						|
)
 | 
						|
 | 
						|
const (
 | 
						|
	adminUser     = "admin"
 | 
						|
	adminPassword = "Adm1n1str$t0r"
 | 
						|
	user1         = "user1"
 | 
						|
	user1Password = "UsErOn3P455"
 | 
						|
	user2         = "user2"
 | 
						|
	user2Password = "us3r2P455W0Rd!"
 | 
						|
)
 | 
						|
 | 
						|
var (
 | 
						|
	fileNames []string
 | 
						|
)
 | 
						|
 | 
						|
var _ = AfterSuite(func() {
 | 
						|
	for _, v := range fileNames {
 | 
						|
		err := os.Remove(v)
 | 
						|
		Expect(err).ToNot(HaveOccurred())
 | 
						|
	}
 | 
						|
})
 | 
						|
 | 
						|
var _ = Describe("HTPasswd Suite", func() {
 | 
						|
	Context("with an HTPassword Validator", func() {
 | 
						|
		assertHtpasswdMapFromFile := func(filePath string) {
 | 
						|
			var htpasswd *htpasswdMap
 | 
						|
			var err error
 | 
						|
 | 
						|
			BeforeEach(func() {
 | 
						|
				var validator Validator
 | 
						|
				validator, err = NewHTPasswdValidator(filePath)
 | 
						|
 | 
						|
				var ok bool
 | 
						|
				htpasswd, ok = validator.(*htpasswdMap)
 | 
						|
				Expect(ok).To(BeTrue())
 | 
						|
			})
 | 
						|
 | 
						|
			It("does not return an error", func() {
 | 
						|
				Expect(err).ToNot(HaveOccurred())
 | 
						|
			})
 | 
						|
 | 
						|
			It("has the correct number of users", func() {
 | 
						|
				Expect(htpasswd.users).To(HaveLen(3))
 | 
						|
			})
 | 
						|
 | 
						|
			It("accepts the correct passwords", func() {
 | 
						|
				Expect(htpasswd.Validate(adminUser, adminPassword)).To(BeTrue())
 | 
						|
				Expect(htpasswd.Validate(user1, user1Password)).To(BeTrue())
 | 
						|
				Expect(htpasswd.Validate(user2, user2Password)).To(BeTrue())
 | 
						|
			})
 | 
						|
 | 
						|
			It("rejects incorrect passwords", func() {
 | 
						|
				Expect(htpasswd.Validate(adminUser, "asvdfda")).To(BeFalse())
 | 
						|
				Expect(htpasswd.Validate(user1, "BHEdgbtr")).To(BeFalse())
 | 
						|
				Expect(htpasswd.Validate(user2, "12345")).To(BeFalse())
 | 
						|
			})
 | 
						|
 | 
						|
			It("rejects a non existent user", func() {
 | 
						|
				// Users are case sensitive
 | 
						|
				Expect(htpasswd.Validate("ADMIN", adminPassword)).To(BeFalse())
 | 
						|
			})
 | 
						|
		}
 | 
						|
 | 
						|
		Context("load from file", func() {
 | 
						|
			Context("with sha1 entries", func() {
 | 
						|
				const filePath = "./test/htpasswd-sha1.txt"
 | 
						|
 | 
						|
				assertHtpasswdMapFromFile(filePath)
 | 
						|
			})
 | 
						|
 | 
						|
			Context("with bcrypt entries", func() {
 | 
						|
				const filePath = "./test/htpasswd-bcrypt.txt"
 | 
						|
 | 
						|
				assertHtpasswdMapFromFile(filePath)
 | 
						|
			})
 | 
						|
 | 
						|
			Context("with mixed entries", func() {
 | 
						|
				const filePath = "./test/htpasswd-mixed.txt"
 | 
						|
 | 
						|
				assertHtpasswdMapFromFile(filePath)
 | 
						|
			})
 | 
						|
 | 
						|
			Context("with a non existent file", func() {
 | 
						|
				const filePath = "./test/htpasswd-doesnt-exist.txt"
 | 
						|
				var validator Validator
 | 
						|
				var err error
 | 
						|
 | 
						|
				BeforeEach(func() {
 | 
						|
					validator, err = NewHTPasswdValidator(filePath)
 | 
						|
				})
 | 
						|
 | 
						|
				It("returns an error", func() {
 | 
						|
					Expect(err).To(MatchError("could not load htpasswd file: could not open htpasswd file: open ./test/htpasswd-doesnt-exist.txt: no such file or directory"))
 | 
						|
				})
 | 
						|
 | 
						|
				It("returns a nil validator", func() {
 | 
						|
					Expect(validator).To(BeNil())
 | 
						|
				})
 | 
						|
			})
 | 
						|
 | 
						|
			Context("htpasswd file is updated", func() {
 | 
						|
				const filePathPrefix = "htpasswd-file-updated-"
 | 
						|
				const adminUserHtpasswdEntry = "admin:$2y$05$SXWrNM7ldtbRzBvUC3VXyOvUeiUcP45XPwM93P5eeGOEPIiAZmJjC"
 | 
						|
				const user1HtpasswdEntry = "user1:$2y$05$/sZYJOk8.3Etg4V6fV7puuXfCJLmV5Q7u3xvKpjBSJUka.t2YtmmG"
 | 
						|
 | 
						|
				type htpasswdUpdate struct {
 | 
						|
					testText              string
 | 
						|
					remove                bool
 | 
						|
					expectedLen           int
 | 
						|
					expectedGomegaMatcher types.GomegaMatcher
 | 
						|
				}
 | 
						|
 | 
						|
				assertHtpasswdMapUpdate := func(hu htpasswdUpdate) {
 | 
						|
					var validator Validator
 | 
						|
					var file *os.File
 | 
						|
					var err error
 | 
						|
 | 
						|
					// Create a temporary file with at least one entry
 | 
						|
					file, err = os.CreateTemp("", filePathPrefix)
 | 
						|
					Expect(err).ToNot(HaveOccurred())
 | 
						|
					_, err = file.WriteString(adminUserHtpasswdEntry + "\n")
 | 
						|
					Expect(err).ToNot(HaveOccurred())
 | 
						|
 | 
						|
					validator, err = NewHTPasswdValidator(file.Name())
 | 
						|
					Expect(err).ToNot(HaveOccurred())
 | 
						|
 | 
						|
					htpasswd, ok := validator.(*htpasswdMap)
 | 
						|
					Expect(ok).To(BeTrue())
 | 
						|
 | 
						|
					if hu.remove {
 | 
						|
						// Overwrite the original file with another entry
 | 
						|
						err = os.WriteFile(file.Name(), []byte(user1HtpasswdEntry+"\n"), 0644)
 | 
						|
						Expect(err).ToNot(HaveOccurred())
 | 
						|
					} else {
 | 
						|
						// Add another entry to the original file in append mode
 | 
						|
						_, err = file.WriteString(user1HtpasswdEntry + "\n")
 | 
						|
						Expect(err).ToNot(HaveOccurred())
 | 
						|
					}
 | 
						|
 | 
						|
					err = file.Close()
 | 
						|
					Expect(err).ToNot(HaveOccurred())
 | 
						|
 | 
						|
					fileNames = append(fileNames, file.Name())
 | 
						|
 | 
						|
					It("has the correct number of users", func() {
 | 
						|
						Expect(len(htpasswd.GetUsers())).To(Equal(hu.expectedLen))
 | 
						|
					})
 | 
						|
 | 
						|
					It(hu.testText, func() {
 | 
						|
						Expect(htpasswd.Validate(adminUser, adminPassword)).To(hu.expectedGomegaMatcher)
 | 
						|
					})
 | 
						|
 | 
						|
					It("new entry is present", func() {
 | 
						|
						Expect(htpasswd.Validate(user1, user1Password)).To(BeTrue())
 | 
						|
					})
 | 
						|
				}
 | 
						|
 | 
						|
				Context("htpasswd entry is added", func() {
 | 
						|
					assertHtpasswdMapUpdate(htpasswdUpdate{"initial entry is present", false, 2, BeTrue()})
 | 
						|
				})
 | 
						|
 | 
						|
				Context("htpasswd entry is removed", func() {
 | 
						|
					assertHtpasswdMapUpdate(htpasswdUpdate{"initial entry is removed", true, 1, BeFalse()})
 | 
						|
				})
 | 
						|
 | 
						|
			})
 | 
						|
		})
 | 
						|
	})
 | 
						|
})
 |