added docs for db_sanity_check

pull/4/head
Blake DeMarcy 2017-04-04 22:10:48 -05:00
parent 9083ed9355
commit 03939fdca5
3 changed files with 117 additions and 19 deletions

View File

@ -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))
(if (alist-get 'bool response)
value
(message (alist-get 'description response)) (message (alist-get 'description response))
(sit-for 2))) (sit-for 2)
value)) (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))
(if check (message "Logged in as %s!" bbj-user) (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)

View File

@ -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))))
```

View File

@ -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(