This repository has been archived by the owner on Apr 29, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
schema.clj
116 lines (94 loc) · 3.33 KB
/
schema.clj
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
(ns oc.lib.schema
"Prismatic schema common data schema fragments."
(:require [clojure.string :as s]
[schema.core :as schema]))
;; ----- Utility functions -----
(defn valid?
"Wrap Prismatic Schema's exception throwing validation, returning true or false instead."
[data-schema value]
(try
(schema/validate data-schema value)
true
(catch Exception e
false)))
(defn uuid-string?
"Is this string a UUID e.g. ce257963-843b-4dbb-91d3-a96ef6479b81"
[s]
(if (and s (string? s) (re-matches #"^(\d|[a-f]){8}-(\d|[a-f]){4}-(\d|[a-f]){4}-(\d|[a-f]){4}-(\d|[a-f]){12}$" s))
true
false))
(defn unique-id?
"Is this a 12 character string fragment from a UUID e.g. 51ab-4c86-a474"
[s]
(if (and s (string? s) (re-matches #"^(\d|[a-f]){4}-(\d|[a-f]){4}-(\d|[a-f]){4}$" s)) true false))
(defn valid-email-address?
"Return true if this is a valid email address according to the regex, otherwise false."
[email-address]
(if (and (string? email-address)
(re-matches #"^[^@]+@[^@\\.]+[\\.].+" email-address))
true
false))
(defn valid-email-domain?
"Return true if this is a valid email domain according to the regex, otherwise false."
[email-domain]
(if (and (string? email-domain)
(re-matches #"^[^@\\.]+[\\.].+" email-domain))
true
false))
(defn valid-password?
"Return true if the password is valid, false if not."
[password]
(and (string? password)
(>= (count password) 8)))
(defn conn?
"Check if a var is a valid RethinkDB connection map/atom."
[conn]
(try
(if (and
(map? conn)
(:client @conn)
(:db @conn)
(:token @conn))
true
false)
(catch Exception e
false)))
(declare Author)
(defn author-for-user
"Extract the author from the JWToken claims."
[user]
(select-keys user (keys Author)))
;; ----- Schema -----
(def NonBlankStr (schema/pred #(and (string? %) (not (s/blank? %)))))
(def UUIDStr (schema/pred uuid-string?))
(def UniqueID (schema/pred unique-id?))
(def ISO8601 (schema/pred #(and (string? %)
(re-matches #"(?i)^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d+)?(([+-]\d\d:\d\d)|Z)?$" %))))
(def EmailAddress (schema/pred valid-email-address?))
(def EmailDomain (schema/pred valid-email-domain?))
(def Author {
:name NonBlankStr
:user-id UniqueID
:avatar-url (schema/maybe schema/Str)})
(def SlackChannel {
:slack-org-id NonBlankStr
:channel-name NonBlankStr
:channel-id NonBlankStr})
(def SlackThread (merge SlackChannel {
:thread NonBlankStr
(schema/optional-key :bot-token) NonBlankStr}))
(def Conn (schema/pred conn?))
(def User
"The portion of JWT properties that we care about for authorship attribution"
{
:user-id UniqueID
:name NonBlankStr
:avatar-url (schema/maybe schema/Str)
schema/Keyword schema/Any ; and whatever else is in the JWT map
})
(def slack-users
"`:slack-users` map with entries for each Slack team, keyed by Slack team ID, e.g. `:T1N0ASD`"
{(schema/optional-key :slack-users) {schema/Keyword {:slack-org-id NonBlankStr
:id NonBlankStr
:token NonBlankStr
(schema/optional-key :display-name) NonBlankStr}}})