Richard van der Hoff
1a64dffb00
Preserve device_id from first call to /register
...
device_id may only be passed in the first call to /register, so make sure we
fish it out of the register `params` rather than the body of the final call.
2016-07-21 11:34:16 +01:00
Erik Johnston
081e5d55e6
Send the correct host header when fetching keys
2016-07-21 11:14:54 +01:00
Erik Johnston
248e6770ca
Cache federation state responses
2016-07-21 10:30:12 +01:00
Richard van der Hoff
7314bf4682
Merge branch 'develop' into rav/get_devices_api
...
(pick up PR #938 in the hope of fixing the UTs)
2016-07-20 17:40:00 +01:00
Richard van der Hoff
e9e3eaa67d
Merge pull request #938 from matrix-org/rav/add_device_id_to_client_ips
...
Record device_id in client_ips
2016-07-20 17:38:45 +01:00
Erik Johnston
d36b1d849d
Don't explode if we have no snapshots yet
2016-07-20 16:59:52 +01:00
David Baker
742056be0d
Merge pull request #937 from matrix-org/rav/register_device_on_register
...
Register a device_id in the /v2/register flow.
2016-07-20 16:51:27 +01:00
Richard van der Hoff
bc8f265f0a
GET /devices endpoint
...
implement a GET /devices endpoint which lists all of the user's devices.
It also returns the last IP where we saw that device, so there is some dancing
to fish that out of the user_ips table.
2016-07-20 16:42:32 +01:00
Richard van der Hoff
ec041b335e
Record device_id in client_ips
...
Record the device_id when we add a client ip; it's somewhat redundant as we
could get it via the access_token, but it will make querying rather easier.
2016-07-20 16:41:03 +01:00
Richard van der Hoff
053e83dafb
More doc-comments
...
Fix some more comments on some things
2016-07-20 16:40:28 +01:00
Richard van der Hoff
b97a1356b1
Register a device_id in the /v2/register flow.
...
This doesn't cover *all* of the registration flows, but it does cover the most
common ones: in particular: shared_secret registration, appservice
registration, and normal user/pass registration.
Pull device_id from the registration parameters. Register the device in the
devices table. Associate the device with the returned access and refresh
tokens. Profit.
2016-07-20 16:38:27 +01:00
Erik Johnston
b73dc0ef4d
Merge pull request #936 from matrix-org/erikj/log_rss
...
Add metrics for psutil derived memory usage
2016-07-20 16:32:38 +01:00
Erik Johnston
66868119dc
Add metrics for psutil derived memory usage
2016-07-20 16:00:21 +01:00
Erik Johnston
aba0b2a39b
Merge pull request #935 from matrix-org/erikj/backfill_notifs
...
Don't notify pusher pool for backfilled events
2016-07-20 13:39:16 +01:00
Erik Johnston
57dca35692
Don't notify pusher pool for backfilled events
2016-07-20 13:25:06 +01:00
Richard van der Hoff
c68518dfbb
Merge pull request #933 from matrix-org/rav/type_annotations
...
Type annotations
2016-07-20 12:26:32 +01:00
David Baker
e967bc86e7
Merge pull request #932 from matrix-org/rav/register_refactor
...
Further registration refactoring
2016-07-20 11:03:33 +01:00
Erik Johnston
1e2a7f18a1
Merge pull request #922 from matrix-org/erikj/file_api2
...
Feature: Add filter to /messages. Add 'contains_url' to filter.
2016-07-20 10:40:48 +01:00
Erik Johnston
f91faf09b3
Comment
2016-07-20 10:18:09 +01:00
Richard van der Hoff
3413f1e284
Type annotations
...
Add some type annotations to help PyCharm (in particular) to figure out the
types of a bunch of things.
2016-07-19 18:56:16 +01:00
Richard van der Hoff
40cbffb2d2
Further registration refactoring
...
* `RegistrationHandler.appservice_register` no longer issues an access token:
instead it is left for the caller to do it. (There are two of these, one in
`synapse/rest/client/v1/register.py`, which now simply calls
`AuthHandler.issue_access_token`, and the other in
`synapse/rest/client/v2_alpha/register.py`, which is covered below).
* In `synapse/rest/client/v2_alpha/register.py`, move the generation of
access_tokens into `_create_registration_details`. This means that the normal
flow no longer needs to call `AuthHandler.issue_access_token`; the
shared-secret flow can tell `RegistrationHandler.register` not to generate a
token; and the appservice flow continues to work despite the above change.
2016-07-19 18:46:19 +01:00
David Baker
b9e997f561
Merge pull request #931 from matrix-org/rav/refactor_register
...
rest/client/v2_alpha/register.py: Refactor flow somewhat.
2016-07-19 16:13:45 +01:00
Richard van der Hoff
9a7a77a22a
Merge pull request #929 from matrix-org/rav/support_deviceid_in_login
...
Add device_id support to /login
2016-07-19 15:53:04 +01:00
Richard van der Hoff
8f6281ab0c
Don't bind email unless threepid contains expected fields
2016-07-19 15:50:01 +01:00
Richard van der Hoff
0da0d0a29d
rest/client/v2_alpha/register.py: Refactor flow somewhat.
...
This is meant to be an *almost* non-functional change, with the exception that
it fixes what looks a lot like a bug in that it only calls
`auth_handler.add_threepid` and `add_pusher` once instead of three times.
The idea is to move the generation of the `access_token` out of
`registration_handler.register`, because `access_token`s now require a
device_id, and we only want to generate a device_id once registration has been
successful.
2016-07-19 13:12:22 +01:00
Richard van der Hoff
022b9176fe
schema fix
...
device_id should be text, not bigint.
2016-07-19 11:44:05 +01:00
Mark Haines
c41d52a042
Summary line
2016-07-19 10:28:27 +01:00
Mark Haines
7e554aac86
Update docstring on Handlers.
...
To indicate it is deprecated.
2016-07-19 10:20:58 +01:00
Richard van der Hoff
f863a52cea
Add device_id support to /login
...
Add a 'devices' table to the storage, as well as a 'device_id' column to
refresh_tokens.
Allow the client to pass a device_id, and initial_device_display_name, to
/login. If login is successful, then register the device in the devices table
if it wasn't known already. If no device_id was supplied, make one up.
Associate the device_id with the access token and refresh token, so that we can
get at it again later. Ensure that the device_id is copied from the refresh
token to the access_token when the token is refreshed.
2016-07-18 16:39:44 +01:00
Richard van der Hoff
93efcb8526
Merge pull request #928 from matrix-org/rav/refactor_login
...
Refactor login flow
2016-07-18 16:12:35 +01:00
Richard van der Hoff
dcfd71aa4c
Refactor login flow
...
Make sure that we have the canonical user_id *before* calling
get_login_tuple_for_user_id.
Replace login_with_password with a method which just validates the password,
and have the caller call get_login_tuple_for_user_id. This brings the password
flow into line with the other flows, and will give us a place to register the
device_id if necessary.
2016-07-18 15:23:54 +01:00
Erik Johnston
fca90b3445
Merge pull request #924 from matrix-org/erikj/purge_history
...
Fix /purge_history bug
2016-07-18 15:11:11 +01:00
Mark Haines
a292454aa1
Merge pull request #925 from matrix-org/markjh/auth_fix
...
Fix 500 ISE when sending alias event without a state_key
2016-07-18 15:04:47 +01:00
Erik Johnston
4f81edbd4f
Merge pull request #927 from Half-Shot/develop
...
Fall back to 'username' if 'user' is not given for appservice registration.
2016-07-18 10:44:56 +01:00
Richard van der Hoff
6344db659f
Fix a doc-comment
...
The `store` in a handler is a generic DataStore, not just an events.StateStore.
2016-07-18 09:48:10 +01:00
Will Hunt
511a52afc8
Use body.get to check for 'user'
2016-07-16 18:44:08 +01:00
Will Hunt
e885e2a623
Fall back to 'username' if 'user' is not given for appservice reg.
2016-07-16 18:33:48 +01:00
Mark Haines
d137e03231
Fix 500 ISE when sending alias event without a state_key
2016-07-15 18:58:25 +01:00
Erik Johnston
f52565de50
Fix /purge_history bug
...
This was caused by trying to insert duplicate backward extremeties
2016-07-15 14:23:15 +01:00
Erik Johnston
a2d288c6a9
Merge pull request #923 from matrix-org/erikj/purge_history
...
Various purge_history fixes
2016-07-15 13:23:29 +01:00
Erik Johnston
bd7c51921d
Merge pull request #919 from matrix-org/erikj/auth_fix
...
Various auth.py fixes.
2016-07-15 11:38:33 +01:00
Erik Johnston
978fa53cc2
Pull out min stream_ordering from ex_outlier_stream
2016-07-15 10:22:30 +01:00
Erik Johnston
eec9609e96
event_backwards_extremeties may not be empty
2016-07-15 10:22:09 +01:00
Erik Johnston
9e1b43bcbf
Comment
2016-07-15 09:29:54 +01:00
Erik Johnston
a3036ac37e
Merge pull request #921 from matrix-org/erikj/account_deactivate
...
Feature: Add an /account/deactivate endpoint
2016-07-14 17:25:15 +01:00
Erik Johnston
ebdafd8114
Check sender signed event
2016-07-14 17:03:24 +01:00
Erik Johnston
a98d215204
Add filter param to /messages API
2016-07-14 16:30:56 +01:00
Erik Johnston
d554ca5e1d
Add support for filters in paginate_room_events
2016-07-14 15:59:04 +01:00
Erik Johnston
209e04fa11
Merge pull request #918 from negzi/bugfix_for_token_expiry
...
Bug fix: expire invalid access tokens
2016-07-14 15:51:52 +01:00
Erik Johnston
e5142f65a6
Add 'contains_url' to filter
2016-07-14 15:35:48 +01:00
Erik Johnston
b64aa6d687
Add sender and contains_url field to events table
2016-07-14 15:35:43 +01:00
Erik Johnston
848d3bf2e1
Add hs object
2016-07-14 10:25:52 +01:00
Erik Johnston
b55c770271
Only accept password auth
2016-07-14 10:00:38 +01:00
Erik Johnston
d543b72562
Add an /account/deactivate endpoint
2016-07-14 09:56:53 +01:00
Negar Fazeli
0136a522b1
Bug fix: expire invalid access tokens
2016-07-13 15:00:37 +02:00
Erik Johnston
2cb758ac75
Check if alias event's state_key matches sender's domain
2016-07-13 13:12:25 +01:00
Erik Johnston
560c71c735
Check creation event's room_id domain matches sender's
2016-07-13 13:07:19 +01:00
David Baker
a37ee2293c
Merge pull request #915 from matrix-org/dbkr/more_requesttokens
...
Add requestToken endpoints
2016-07-13 11:51:46 +01:00
David Baker
c55ad2e375
be more pythonic
2016-07-12 14:15:10 +01:00
David Baker
aaa9d9f0e1
on_OPTIONS isn't neccessary
2016-07-12 14:13:14 +01:00
David Baker
75fa7f6b3c
Remove other debug logging
2016-07-12 14:08:57 +01:00
David Baker
a5db0026ed
Separate out requestTokens to separate handlers
2016-07-11 09:57:07 +01:00
David Baker
9c491366c5
Oops, remove debug logging
2016-07-11 09:07:40 +01:00
David Baker
385aec4010
Implement https://github.com/matrix-org/matrix-doc/pull/346/files
2016-07-08 17:42:48 +01:00
Mark Haines
dfde67a6fe
Add a comment explaining allow_none
2016-07-08 15:57:06 +01:00
Mark Haines
10c843fcfb
Ensure that the guest user is in the database when upgrading accounts
2016-07-08 15:15:55 +01:00
Erik Johnston
58930da52b
Merge branch 'master' of github.com:matrix-org/synapse into develop
2016-07-08 14:11:37 +01:00
Erik Johnston
0870588c20
Merge branch 'hotfixes-v0.16.1'
2016-07-08 13:22:32 +01:00
Erik Johnston
f90cf150e2
Bump version and changelog
2016-07-07 16:33:00 +01:00
Erik Johnston
067596d341
Fix bug where we did not correctly explode when multiple user_ids were set in macaroon
2016-07-07 16:22:24 +01:00
Erik Johnston
b92e7955be
Comment
2016-07-07 11:42:15 +01:00
Erik Johnston
c98e1479bd
Return 400 rather than 500
2016-07-07 11:41:07 +01:00
Erik Johnston
67f2c901ea
Add rest servlet. Fix SQL.
2016-07-06 15:56:59 +01:00
Erik Johnston
eef7778af9
Merge branch 'develop' of github.com:matrix-org/synapse into erikj/test2
2016-07-06 14:50:22 +01:00
Erik Johnston
a17e7caeb7
Merge branch 'erikj/shared_secret' into erikj/test2
2016-07-06 14:46:31 +01:00
Erik Johnston
f0c06ac65c
Merge pull request #909 from matrix-org/erikj/shared_secret
...
Add an admin option to shared secret registration (breaks backwards compat)
2016-07-06 14:08:51 +01:00
Erik Johnston
76b18df3d9
Check that there are no null bytes in user and passsword
2016-07-06 11:17:53 +01:00
Erik Johnston
0da24cac8b
Add null separator to hmac
2016-07-06 11:05:16 +01:00
Kent Shikama
8d9a884cee
Update password config comment
...
Signed-off-by: Kent Shikama <kent@kentshikama.com>
2016-07-06 12:18:19 +09:00
Erik Johnston
be3548f7e1
Remove spurious txn
2016-07-05 17:46:51 +01:00
Erik Johnston
4adf93e0f7
Fix for postgres
2016-07-05 17:34:25 +01:00
Erik Johnston
651faee698
Add an admin option to shared secret registration
2016-07-05 17:30:22 +01:00
Erik Johnston
caf33b2d9b
Protect password when registering using shared secret
2016-07-05 17:18:19 +01:00
Erik Johnston
8f8798bc0d
Add ReadWriteLock for pagination and history prune
2016-07-05 15:30:25 +01:00
Erik Johnston
7335f0adda
Add ReadWriteLock
2016-07-05 15:23:17 +01:00
David Baker
ef535178ff
Merge pull request #904 from matrix-org/dbkr/register_email_no_untrusted_id_server
...
requestToken update
2016-07-05 15:13:34 +01:00
Mark Haines
04dee11e97
Merge pull request #906 from matrix-org/markjh/faster_events_around
...
Use a query that postgresql optimises better for get_events_around
2016-07-05 14:48:34 +01:00
Mark Haines
dd2ccee27d
Fix typo
2016-07-05 14:06:07 +01:00
Mark Haines
b6b0132ac7
Make get_events_around more efficient on sqlite3
2016-07-05 13:55:18 +01:00
Kent Shikama
252ee2d979
Remove default password pepper string
2016-07-05 19:15:51 +09:00
Kent Shikama
14362bf359
Fix password config
2016-07-05 19:12:53 +09:00
Kent Shikama
1ee2584307
Fix pep8
2016-07-05 19:01:00 +09:00
Kent Shikama
507b8bb091
Add comment to prompt changing of pepper
2016-07-05 18:42:35 +09:00
Mark Haines
d44d11d864
Use true/false for boolean parameter inclusive to avoid potential for sqli, and possibly make the code clearer
2016-07-05 10:39:13 +01:00
Erik Johnston
2d21d43c34
Add purge_history API
2016-07-05 10:28:51 +01:00
Mark Haines
0fb76c71ac
Use different SQL for postgres and sqlite3 for when using multicolumn indexes
2016-07-04 19:44:55 +01:00
Kent Shikama
8bdaf5f7af
Add pepper to password hashing
...
Signed-off-by: Kent Shikama <kent@kentshikama.com>
2016-07-05 02:13:52 +09:00
Erik Johnston
a67bf0b074
Add storage function to purge history for a room
2016-07-04 16:02:50 +01:00
Mark Haines
f18d7546c6
Use a query that postgresql optimises better for get_events_around
2016-07-04 15:48:25 +01:00
Kent Shikama
bb069079bb
Fix style violations
...
Signed-off-by: Kent Shikama <kent@kentshikama.com>
2016-07-04 22:07:11 +09:00
Kent Shikama
2e5a31f197
Use .get() instead of [] to access password_hash
2016-07-04 22:00:13 +09:00
Kent Shikama
fc8007dbec
Optionally include password hash in createUser endpoint
...
Signed-off-by: Kent Shikama <kent@kentshikama.com>
2016-07-03 15:08:15 +09:00
David Baker
be8be535f7
requestToken update
...
Don't send requestToken request to untrusted ID servers
Also correct the THREEPID_IN_USE error to add the M_ prefix. This is a backwards incomaptible change, but the only thing using this is the angular client which is now unmaintained, so it's probably better to just do this now.
2016-06-30 17:51:28 +01:00
Erik Johnston
f328d95cef
Feature: Add deactivate account admin API
...
Allows server admins to "deactivate" accounts, which:
- Revokes all access tokens
- Removes all threepids
- Removes password
The API is a POST to `/admin/deactivate/<user_id>`
2016-06-30 15:40:58 +01:00
Erik Johnston
f52cb4cd78
Remove race
2016-06-29 15:24:50 +01:00
Mark Haines
6783534a0f
Merge pull request #886 from matrix-org/markjh/async_commit
...
Optionally make committing to postgres asynchronous.
2016-06-29 15:21:58 +01:00
Erik Johnston
a70688445d
Implement purge_media_cache admin API
2016-06-29 14:57:59 +01:00
Erik Johnston
314b146b2e
Track approximate last access time for remote media
2016-06-29 11:41:20 +01:00
David Baker
db74dcda5b
Merge pull request #894 from matrix-org/dbkr/push_room_naming
...
Use similar naming we use in email notifs for push
2016-06-28 10:12:24 +01:00
Matthew Hodgson
63bb8f0df9
remove vector.im from default secondary DS list
2016-06-27 13:13:33 +04:00
David Baker
0b640aa56b
even more pep8
2016-06-24 11:47:11 +01:00
David Baker
aa3a4944d5
more pep8
2016-06-24 11:45:23 +01:00
David Baker
46b7362304
pep8
2016-06-24 11:44:57 +01:00
David Baker
870c45913e
Use similar naming we use in email notifs for push
...
Fixes https://github.com/vector-im/vector-web/issues/1654
2016-06-24 11:41:11 +01:00
Mark Haines
05f1a4596a
Merge branch 'master' into develop
2016-06-23 11:17:48 +01:00
David Baker
b5fb7458d5
Actually we need to order these properly
...
otherwise we'll end up returning the wrong 20
2016-06-22 18:07:14 +01:00
David Baker
f73fdb04a6
Style
2016-06-22 17:51:40 +01:00
David Baker
3a4120e49a
Put most recent 20 messages in notif
...
Fixes https://github.com/vector-im/vector-web/issues/1648
2016-06-22 17:47:18 +01:00
Martin Weinelt
0a32208e5d
Rework ldap integration with ldap3
...
Use the pure-python ldap3 library, which eliminates the need for a
system dependency.
Offer both a `search` and `simple_bind` mode, for more sophisticated
ldap scenarios.
- `search` tries to find a matching DN within the `user_base` while
employing the `user_filter`, then tries the bind when a single
matching DN was found.
- `simple_bind` tries the bind against a specific DN by combining the
localpart and `user_base`
Offer support for STARTTLS on a plain connection.
The configuration was changed to reflect these new possibilities.
Signed-off-by: Martin Weinelt <hexa@darmstadt.ccc.de>
2016-06-22 17:51:59 +02:00
Mark Haines
774f3a692c
Merge pull request #889 from matrix-org/markjh/synctl_workers
...
Optionally start or stop workers in synctl.
2016-06-21 17:58:19 +01:00
Mark Haines
5cc7564c5c
Optionally start or stop workers in synctl.
...
Optionally start or stop an individual worker by passing -w with
the path to the worker config.
Optionally start or stop every worker and the main synapse by
passing -a with a path to a directory containing worker configs.
The "-w" is intended to be used to bounce individual workers proceses.
THe "-a" is intended for when you want to restart all the workers
simultaneuously, for example when performing database upgrades.
2016-06-21 16:38:05 +01:00
Mark Haines
0fe0b0eeb6
Merge pull request #888 from matrix-org/markjh/content_repo
...
Remove the legacy v0 content upload API.
2016-06-21 14:01:01 +01:00
Mark Haines
13e334506c
Remove the legacy v0 content upload API.
...
The existing content can still be downloaded. The last upload to the
matrix.org server was in January 2015, so it is probably safe to remove
the upload API.
2016-06-21 11:47:39 +01:00
Mark Haines
d5fb561709
Optionally make committing to postgres asynchronous.
...
Useful when running tests when you don't care whether the server
will lose data that it claims that it has committed.
2016-06-20 17:53:38 +01:00
Erik Johnston
d8ec81cc31
Merge pull request #879 from matrix-org/erikj/linearize_fed_server
...
Linearize some federation endpoints based on (origin, room_id)
2016-06-20 17:34:29 +01:00
Erik Johnston
bc72d381b2
Merge branch 'release-v0.16.1' of github.com:matrix-org/synapse
2016-06-20 14:18:04 +01:00
Erik Johnston
4d362a61ea
Bump version and changelog
2016-06-20 14:17:42 +01:00
Mark Haines
41e4b2efea
Add the create_profile method back since the tests use it
2016-06-17 19:20:47 +01:00
Mark Haines
0c13d45522
Add a comment on why we don't create a profile for upgrading users
2016-06-17 19:18:53 +01:00
Mark Haines
9f1800fba8
Remove registered_users from the distributor.
...
The only place that was observed was to set the profile. I've made it
so that the profile is set within store.register in the same transaction
that creates the user.
This required some slight changes to the registration code for upgrading
guest users, since it previously relied on the distributor swallowing errors
if the profile already existed.
2016-06-17 19:14:16 +01:00
Erik Johnston
8f4a9bbc16
Linearize some federation endpoints based on (origin, room_id)
2016-06-17 16:43:45 +01:00
Erik Johnston
9ba2bf1570
Merge pull request #878 from matrix-org/erikj/ujson
...
Disable responding with canonical json for federation
2016-06-17 16:22:12 +01:00
Erik Johnston
120c238705
Disable responding with canonical json for federation
2016-06-17 16:10:37 +01:00
Erik Johnston
1c1f633b13
Merge pull request #877 from matrix-org/erikj/frozen_default
...
Turn use_frozen_events off by default
2016-06-17 15:33:55 +01:00
Erik Johnston
6660f37558
Merge pull request #876 from matrix-org/erikj/sign_own
...
Only re-sign our own events
2016-06-17 15:23:20 +01:00
Erik Johnston
3e41de05cc
Turn use_frozen_events off by default
2016-06-17 15:11:22 +01:00
Erik Johnston
2884712ca7
Only re-sign our own events
2016-06-17 14:47:33 +01:00
Mark Haines
ded01c3bf6
Fix `KeyError: 'msgtype'
. Use
.get
`
...
Fixes a key error where the mailer tried to get the ``msgtype`` of an
event that was missing a ``msgtype``.
```
File "synapse/push/mailer.py", line 264, in get_notif_vars
File "synapse/push/mailer.py", line 285, in get_message_vars
File ".../frozendict/__init__.py", line 10, in __getitem__
return self.__dict[key]
KeyError: 'msgtype'
```
2016-06-17 13:49:16 +01:00
Mark Haines
8c75040c25
Fix setting gc thresholds in the workers
2016-06-17 11:48:12 +01:00
Mark Haines
a352b68acf
Use worker_ prefixes for worker config, use existing support for multiple config files
2016-06-16 17:29:50 +01:00
Mark Haines
364d616792
Access the event_cache_size directly from the server object.
...
This means that the workers can override the event_cache_size
directly without clobbering the value in the main synapse config.
2016-06-16 12:53:15 +01:00
Mark Haines
bde13833cb
Access replication_url from the worker config directly
2016-06-16 12:44:40 +01:00
Mark Haines
80a1bc7db5
Comment on what's going on in clobber_with_worker_config
2016-06-16 11:29:45 +01:00
Mark Haines
f1f70bf4b5
Merge remote-tracking branch 'origin/develop' into markjh/worker_config
2016-06-16 11:20:17 +01:00
Mark Haines
dbb5a39b64
Add worker config module
2016-06-16 11:09:15 +01:00
Mark Haines
885ee861f7
Inline the synchrotron and pusher configs into the main config
2016-06-16 11:06:12 +01:00
Erik Johnston
486b9a6a2d
Merge pull request #873 from vt0r/bugfix/bcrypt-utf8-encode
...
Fix TypeError in call to bcrypt.hashpw
2016-06-16 10:12:17 +01:00
Salvatore LaMendola
ed5f43a55a
Fix TypeError in call to bcrypt.hashpw
...
- At the very least, this TypeError caused logins to fail on my own
running instance of Synapse, and the simple (explicit) UTF-8
conversion resolved login errors for me.
Signed-off-by: Salvatore LaMendola <salvatore.lamendola@gmail.com>
2016-06-16 00:43:42 -04:00
Erik Johnston
09a17f965c
Line lengths
2016-06-15 16:58:12 +01:00
Erik Johnston
1e9026e484
Handle floats as img widths
2016-06-15 16:58:05 +01:00