added docs for db_sanity_check
parent
9083ed9355
commit
03939fdca5
|
@ -134,7 +134,7 @@ or can be ommitted to send no data."
|
||||||
(re-search-forward "^$" nil t)
|
(re-search-forward "^$" nil t)
|
||||||
(condition-case nil
|
(condition-case nil
|
||||||
(setq json (json-read))
|
(setq json (json-read))
|
||||||
(json-readtable-error
|
(error
|
||||||
(user-error "BBJ response error"))))
|
(user-error "BBJ response error"))))
|
||||||
|
|
||||||
(case (setq error (alist-get 'error json)
|
(case (setq error (alist-get 'error json)
|
||||||
|
@ -156,16 +156,18 @@ is the only thing returned (not the usermap or error field)"
|
||||||
(defun bbj-sane-value (prompt key)
|
(defun bbj-sane-value (prompt key)
|
||||||
"Opens an input loop with the user, where the response is
|
"Opens an input loop with the user, where the response is
|
||||||
passed to the server to check it for validity before the
|
passed to the server to check it for validity before the
|
||||||
user is allowed to continue."
|
user is allowed to continue. Will recurse until the input
|
||||||
(let (response value done)
|
is valid, then it is returned."
|
||||||
(while (not done)
|
(let (response value)
|
||||||
(setq value (read-from-minibuffer prompt)
|
(setq value (read-from-minibuffer prompt)
|
||||||
response (bbj-data (bbj-request 'db_sanity_check
|
response (bbj-request! 'db_sanity_check
|
||||||
'key key 'value value)))
|
'value value
|
||||||
(unless (setq done (alist-get 'bool response))
|
'key key))
|
||||||
(message (alist-get 'description response))
|
(if (alist-get 'bool response)
|
||||||
(sit-for 2)))
|
value
|
||||||
value))
|
(message (alist-get 'description response))
|
||||||
|
(sit-for 2)
|
||||||
|
(bbj-sane-value prompt key))))
|
||||||
|
|
||||||
|
|
||||||
(defun bbj-descend (alist &rest keys)
|
(defun bbj-descend (alist &rest keys)
|
||||||
|
@ -195,11 +197,10 @@ You can restore anon status on demand by using `bbj-logout'"
|
||||||
"user_name"))
|
"user_name"))
|
||||||
(cond
|
(cond
|
||||||
((bbj-request! 'user_is_registered 'target_user bbj-user)
|
((bbj-request! 'user_is_registered 'target_user bbj-user)
|
||||||
(setq check
|
(if (bbj-request! 'check_auth
|
||||||
(bbj-request! 'check_auth
|
'target_user bbj-user
|
||||||
'target_user bbj-user
|
'target_hash (bbj-sethash))
|
||||||
'target_hash (bbj-sethash)))
|
(message "Logged in as %s!" bbj-user)
|
||||||
(if check (message "Logged in as %s!" bbj-user)
|
|
||||||
(setq bbj-hash nil)
|
(setq bbj-hash nil)
|
||||||
(if (y-or-n-p (format "Invalid credentials for %s. Try again? " bbj-user))
|
(if (y-or-n-p (format "Invalid credentials for %s. Try again? " bbj-user))
|
||||||
(bbj-login)
|
(bbj-login)
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
The server has an endpoint called `db_sanity_check`. What this does is take
|
||||||
|
a `key` and a `value` and compares `value` to a set of rules specified by
|
||||||
|
`key`. This is the same function used internally by the database to scan
|
||||||
|
values before committing them to the database. By default it returns a
|
||||||
|
descriptive object under `data`, but you can specify the key/value pair
|
||||||
|
`"error": True` to get a standard error response back. A standard call
|
||||||
|
to `db_sanity_check` will look like this.
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"key": "title",
|
||||||
|
"value": "this title\nis bad \nbecause it contains \nnewlines"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
and the server will respond like this when the input should be corrected.
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"bool": False,
|
||||||
|
"description": "Titles cannot contain whitespace characters besides spaces."
|
||||||
|
},
|
||||||
|
"error": False,
|
||||||
|
"usermap": {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
if everything is okay, the data object will look like this instead.
|
||||||
|
|
||||||
|
```
|
||||||
|
"data": {
|
||||||
|
"bool": True,
|
||||||
|
"description": null
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively, you can supply `"error": True` in the request.
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"error": True,
|
||||||
|
"key": "title",
|
||||||
|
"value": "this title\nis bad \nbecause it contains \nnewlines"
|
||||||
|
}
|
||||||
|
// and you get...
|
||||||
|
{
|
||||||
|
"data": null,
|
||||||
|
"usermap": {},
|
||||||
|
"error": {
|
||||||
|
"code": 4,
|
||||||
|
"description": "Titles cannot contain whitespace characters besides spaces."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The following keys are currently available.
|
||||||
|
|
||||||
|
* "user_name"
|
||||||
|
* "auth_hash"
|
||||||
|
* "quip"
|
||||||
|
* "bio"
|
||||||
|
* "title"
|
||||||
|
* "body"
|
||||||
|
* "color"
|
||||||
|
|
||||||
|
The descriptions returned are friendly, descriptive, and should be shown
|
||||||
|
directly to users
|
||||||
|
|
||||||
|
## Implementing good sanity checks in your client
|
||||||
|
|
||||||
|
By using this endpoint, you will never have to validate values in your
|
||||||
|
own code before sending them to the server. This means you can do things
|
||||||
|
like implement an interactive prompt which will not allow the user to
|
||||||
|
submit it unless the value is correct.
|
||||||
|
|
||||||
|
This is used in the elisp client when registering users and for the thread
|
||||||
|
title prompt which is shown before opening a composure window. The reason
|
||||||
|
for rejection is displayed clearly to the user and input window is restored.
|
||||||
|
|
||||||
|
```
|
||||||
|
(defun bbj-sane-value (prompt key)
|
||||||
|
"Opens an input loop with the user, where the response is
|
||||||
|
passed to the server to check it for validity before the
|
||||||
|
user is allowed to continue. Will recurse until the input
|
||||||
|
is valid, then it is returned."
|
||||||
|
(let (response value)
|
||||||
|
(setq value (read-from-minibuffer prompt)
|
||||||
|
response (bbj-request! 'db_sanity_check
|
||||||
|
'value value
|
||||||
|
'key key))
|
||||||
|
(if (alist-get 'bool response)
|
||||||
|
value
|
||||||
|
(message (alist-get 'description response))
|
||||||
|
(sit-for 2)
|
||||||
|
(bbj-sane-value prompt key))))
|
||||||
|
```
|
|
@ -308,7 +308,7 @@ def validate(keys_and_values):
|
||||||
|
|
||||||
elif contains_nonspaces(value):
|
elif contains_nonspaces(value):
|
||||||
raise BBJUserError(
|
raise BBJUserError(
|
||||||
"Username cannot contain whitespace chars besides spaces.")
|
"Username cannot contain whitespace characters besides spaces.")
|
||||||
|
|
||||||
elif not value.strip():
|
elif not value.strip():
|
||||||
raise BBJUserError(
|
raise BBJUserError(
|
||||||
|
@ -330,7 +330,7 @@ def validate(keys_and_values):
|
||||||
elif key == "quip":
|
elif key == "quip":
|
||||||
if contains_nonspaces(value):
|
if contains_nonspaces(value):
|
||||||
raise BBJUserError(
|
raise BBJUserError(
|
||||||
"Quip cannot contain whitespace chars besides spaces.")
|
"Quip cannot contain whitespace characters besides spaces.")
|
||||||
|
|
||||||
elif len(value) > 120:
|
elif len(value) > 120:
|
||||||
raise BBJUserError(
|
raise BBJUserError(
|
||||||
|
@ -348,7 +348,7 @@ def validate(keys_and_values):
|
||||||
|
|
||||||
elif contains_nonspaces(value):
|
elif contains_nonspaces(value):
|
||||||
raise BBJUserError(
|
raise BBJUserError(
|
||||||
"Titles cannot contain whitespace chars besides spaces.")
|
"Titles cannot contain whitespace characters besides spaces.")
|
||||||
|
|
||||||
elif not value.strip():
|
elif not value.strip():
|
||||||
raise BBJUserError(
|
raise BBJUserError(
|
||||||
|
|
Loading…
Reference in New Issue