summaryrefslogtreecommitdiff
path: root/contrib/tlsauth/auth.go
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tlsauth/auth.go')
-rw-r--r--contrib/tlsauth/auth.go46
1 files changed, 46 insertions, 0 deletions
diff --git a/contrib/tlsauth/auth.go b/contrib/tlsauth/auth.go
new file mode 100644
index 0000000..38ec3a3
--- /dev/null
+++ b/contrib/tlsauth/auth.go
@@ -0,0 +1,46 @@
+package tlsauth
+
+import (
+ "context"
+ "crypto/x509"
+
+ "tildegit.org/tjp/gus"
+)
+
+// Identity returns the client certificate for the request or nil if there is none.
+func Identity(request *gus.Request) *x509.Certificate {
+ if request.TLSState == nil || len(request.TLSState.PeerCertificates) == 0 {
+ return nil
+ }
+ return request.TLSState.PeerCertificates[0]
+}
+
+// RequiredAuth produces an auth predicate.
+//
+// The check requires both that there is a client certificate associated with the
+// request and that it passes the provided approver.
+func RequiredAuth(approve Approver) func(context.Context, *gus.Request) bool {
+ return func(_ context.Context, request *gus.Request) bool {
+ identity := Identity(request)
+ if identity == nil {
+ return false
+ }
+
+ return approve(identity)
+ }
+}
+
+// OptionalAuth produces an auth predicate.
+//
+// The check allows through any request with no client certificate, but if
+// there is one present then it requires that it pass the provided approver.
+func OptionalAuth(approve Approver) func(context.Context, *gus.Request) bool {
+ return func(_ context.Context, request *gus.Request) bool {
+ identity := Identity(request)
+ if identity == nil {
+ return true
+ }
+
+ return approve(identity)
+ }
+}