Compare commits

..

2053 Commits

Author SHA1 Message Date
Tim Abbott
726ab9c4fa Release Zulip Server 2.0.8. 2019-12-12 17:15:53 -08:00
Anders Kaseorg
b7c87a4d82 CVE-2019-19775: Close open redirect in thumbnail view.
This closes an open redirect vulnerability, one case of which was
found by Graham Bleaney and Ibrahim Mohamed using Pysa.

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-12-12 17:14:00 -08:00
Tim Abbott
1bf0a92eb6 Release Zulip Server 2.0.7. 2019-11-20 23:22:23 -08:00
Mateusz Mandera
63eece23a9 auth: Use zxcvbn to ensure password strength on server side.
Backported for 2.0.7 security release.

For a long time, we've been only doing the zxcvbn password strength
checks on the browser, which is helpful, but means users could through
hackery (or a bug in the frontend validation code) manage to set a
too-weak password.  We fix this by running our password strength
validation on the backend as well, using python-zxcvbn.

In theory, a bug in python-zxcvbn could result in it producing a
different opinion than the frontend version; if so, it'd be a pretty
bad bug in the library, and hopefully we'd hear about it from users,
report upstream, and get it fixed that way. Alternatively, we can
switch to shelling out to node like we do for KaTeX.

Fixes #6880.
2019-11-20 23:22:23 -08:00
Mateusz Mandera
1cdec46aa9 CVE-2019-18933: Fix insecure account creation via social authentication.
Backported for 2.0.7 security release.

A bug in Zulip's new user signup process meant that users who
registered their account using social authentication (e.g. GitHub or
Google SSO) in an organization that also allows password
authentication could have their personal API key stolen by an
unprivileged attacker, allowing nearly full access to the user's
account.

Zulip versions between 1.7.0 and 2.0.6 were affected.

This commit fixes the original bug and also contains a database
migration to fix any users with corrupt `password` fields in the
database as a result of the bug.

Out of an abundance of caution (and to protect the users of any
installations that delay applying this commit), the migration also
resets the API keys of any users where Zulip's logs cannot prove the
user's API key was not previously stolen via this bug.  Resetting
those API keys will be inconvenient for users:

* Users of the Zulip mobile and terminal apps whose API keys are reset
  will be logged out and need to login again.
* Users using their personal API keys for any other reason will need
  to re-fetch their personal API key.

We discovered this bug internally and don't believe it was disclosed
prior to our publishing it through this commit.  Because the algorithm
for determining which users might have been affected is very
conservative, many users who were never at risk will have their API
keys reset by this migration.

To avoid this on self-hosted installations that have always used
e.g. LDAP authentication, we skip resetting API keys on installations
that don't have password authentication enabled.  System
administrators on installations that used to have email authentication
enabled, but no longer do, should temporarily enable EmailAuthBackend
before applying this migration.

The migration also records which users had their passwords or API keys
reset in the usual RealmAuditLog table.
2019-11-20 23:22:22 -08:00
Tim Abbott
c47039dfb6 push_notifications: Clear PushDeviceToken on API key change.
Backported for 2.0.7 security release.

This includes adding a new endpoint to the push notification bouncer
interface, and code to call it appropriately after resetting a user's
personal API key.

When we add support for a user having multiple API keys, we may need
to add an additional key here to support removing keys associated with
just one client.
2019-11-20 23:09:41 -08:00
Tim Abbott
bccec80062 Release Zulip Server 2.0.6. 2019-09-23 16:08:57 -07:00
Anders Kaseorg
6e287db98e setup-apt-repo: Install groonga-keyring.
This allows the system to get updates to the Groonga repository
signing key, so `apt update` doesn’t start failing when the key
changes (like it recently did).

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-09-23 16:03:19 -07:00
Anders Kaseorg
9489d2d850 setup: Update groonga APT repository signing key.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-09-23 16:03:10 -07:00
Tim Abbott
226a96bdb8 message_list: Replace buggy rerender_the_whole_thing.
As it turns out, our rerender_the_whole_thing function (used whenever
we were adding messages and discovered that the resulting message list
would be out-of-order) was just broken and scrolled the browser to a
random location.

This caused two user-facing bugs:

* On very fast networks, if two users sent messages at very close to
  the same time, we could end up with out-of-order message deliveries,
  triggering this code path, which was intended to silently correct
  the situation, but failed.

* In some narrows to streams with muted topics in the history but some
  recent traffic, the user's browser-cached history might have some
  gaps that mean the server fetch we do after narrowing discovers the
  history is out-of-order, again triggering the
  rerender_the_whole_thing code path.

The fix is to just remove that function, adding a new option to the
well-tested rerender_preserving_scrolltop (which has explicit logic to
preserve the scroll position) instead.

Fixes #12067.  Likely also fixes #12498.
2019-09-18 11:44:27 -07:00
Tim Abbott
a4bf15bbc7 realm_filters: Allows more use of & and friends in URLs.
We had some excessively tight rules about what characters were
allowed, which in particular prevented using `?foo=bar&baz=quux`
structures in the realm filters URLs.

Fixes #12239.
2019-09-17 13:10:49 -07:00
Tim Abbott
2bb3af1ade Release Zulip Server 2.0.5. 2019-09-11 15:48:06 -07:00
Anders Kaseorg
5797f013b3 CVE-2019-16215: Fix DoS vulnerability in Markdown LINK_RE.
Any regex including a match-everything subpattern (.*, .*?, .+, or
.+?) is almost automatically wrong because it fails to disambiguate
when one subpattern should end and another should begin.  Among other
bugs, these kind of regexes tend to be especially prone to denial of
service vulnerabilities through catastrophic backtracking on strings
that fail to match in a large (in this case, exponential) number of
ways.

Lacking a specification to say what characters should actually be
allowed in these subpatterns (this syntax is too different from
CommonMark to be able to precisely apply those rules), I’ve tried to
make reasonable guesses and avoid changing much else.

Because Zulip doesn't store messages until they have successfully been
processed by the Markdown processor, this is not a stored DoS issue.

In general, Zulip protects against the broad category of DoS issues in
Markdown rendering via a timeout managed by another thread.  However,
details of Python's regular expression implementation mean that this
particular issue could prevent the timeout thread from being
scheduled, resulting in this being a DoS issue.

This was fixed in master a few months ago as a side effect of
abe2dab88c (#12979).

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-09-11 15:47:02 -07:00
Anders Kaseorg
1195841dfb CVE-2019-16216: Fix MIME type validation.
* Whitelist a small number of image/ types to be served as
  non-attachments.
* Serve the file using the type that we validated rather than relying
  on an independent guess to match.

This issue can lead to a stored XSS security vulnerability for older
browsers that don't support Content-Security-Policy.

It primarily affects servers using Zulip's local file uploads backend
for servers running Ubuntu 16.04 Xenial or newer; the legacy local
file upload backend for (now EOL) Ubuntu 14.04 Trusty was not affected
and it has limited impact for the S3 upload backend (which uses an
unprivileged S3 bucket domain to serve files).

This was fixed in master via 780ecb672b.

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-09-11 15:46:55 -07:00
Rishi Gupta
dca727f178 docs: Make the intro to Production Installation less scary. 2019-09-08 20:29:35 -07:00
Fabian Stanke
77d5a37539 postfix: Inserted compulsory setting for postfix ≥ 2.10.
One of smtpd_relay_restrictions or smtpd_recipient_restrictions is
required by postfix ≥ 2.10 (see
http://www.postfix.org/SMTPD_ACCESS_README.html).

This is important for using the email mirror on Ubuntu Bionic.
2019-09-08 15:44:36 -07:00
Tim Abbott
2c16b9905d auth: Fix missing AzureAD section on /register. 2019-07-09 13:27:40 -07:00
Tim Abbott
3c5e69aa0d management: Fix obsolete check for double-adding a permission.
The .has_perm logic in this management command dates from use of
django-guardian that ended years ago.
2019-07-08 13:45:22 -07:00
Tim Abbott
32af9a95d5 management: Clean up a variable name in knight. 2019-07-08 13:45:17 -07:00
Vishnu Ks
3eeaafed73 install: Include no-dist-upgrade in args list.
This was missed out in 2e51ac8c49
2019-06-14 14:24:38 -07:00
Vishnu Ks
e9e25fd319 import: Handle hidden_by_limit case for files in slack import.
Fixes #12011
2019-06-06 21:54:52 -07:00
Tim Abbott
a1f62a66ae Release Zulip Server 2.0.4. 2019-06-06 20:03:14 -07:00
Tim Abbott
d52a5a1d2d settings: Fix getting API key when using social auth.
Long-term, we want this flow to do a full re-authentication, but this
makes the frontend consistent with the backend and fixes a confusing
bug where submitting the form ended up adding a weird `?password=`
thing to the URL, in addition to not working.

Fixes #12200.
2019-06-06 20:02:44 -07:00
Tim Abbott
f2022834bd settings: Improve example for RABBITMQ_HOST.
We prefer 127.0.0.1 over localhost for RabbitMQ because of weird IPv6
issues, so we should avoid mentioning localhost as an example.
2019-06-06 16:42:23 -07:00
Tim Abbott
54f981bfeb restore-backup: Run configure-rabbitmq to update RABBITMQ_PASSWORD.
Previously, if you restored onto a different production system from
the one where you took the backup, backup restoration would fail
because the generated rabbitmq passwords for the two systems would be
different, and we didn't update the restored system to use the
password from the original system.

Fixes #12114.
2019-06-06 16:42:21 -07:00
Tim Abbott
d6daf11e03 restore-backup: Run zulip-puppet-apply before pg_restore.
This should ensure that we apply any special configuration for the
database system (e.g. installing `pgroonga`) before we try to restore
the database contents from the archive.

For pgroonga in particular, this is important so that we can preserve
the configuration of the extension in the `pg_restore` process.

Fixes #12345.
2019-06-06 16:42:17 -07:00
Vishnu Ks
4e5bb844b4 install: Add option to skip dist-upgrade. 2019-06-06 15:09:31 -07:00
Tim Abbott
9230d3304f restore-backup: Fix error on systems using S3 upload backend.
With the S3 file upload backend, we don't store uploads locally, so
the `uploads` directory in the backup will be empty, and more
importantly, LOCAL_UPLOADS_DIR will be None, which the previous code
crashed on.
2019-06-06 15:08:59 -07:00
vinitS101
cd07bcdd29 docs: Fixed a small typo in the LDAP documentation. 2019-06-04 18:35:13 -07:00
Tim Abbott
89cbe7f53b docs: Update contributor count to over 500. 2019-06-04 18:34:55 -07:00
Yashashvi Dave
a41cbad45c org settings: Fix missing <th> element in deactivated-user setting. 2019-06-04 18:34:44 -07:00
Tim Abbott
633c91facf docs: Clarify section on local configuration changes.
We still should add a section documenting all the options.
2019-06-04 18:33:29 -07:00
Tim Abbott
e8acffcb8a pgroonga: Fix do_batch_update logic for all postgres versions.
Apparently, the fix in 430ed061c1
requires a sufficiently modern postgres version not available in
Xenial.

Fixes #12382.

Patch by Sutou Kouhei.
2019-05-29 15:00:11 -07:00
Hemanth V. Alluri
342c7d946a org_settings: Fix error with undefined profile_field in bot settings.
This is a small patch to fix the error message an admin would receive if
they tried to change bot info and owner from the "bots" setting of the
organization settings panel.
2019-04-30 14:51:21 -07:00
Tim Abbott
f95c807100 Release Zulip Server 2.0.3. 2019-04-23 15:00:32 -07:00
Tim Abbott
d11f32909c api docs: Fix typo in typing notifications docs.
notification_to should be just to here.

This resulted from the person doing the port into these docs not
understanding the full REQ API.
2019-04-23 14:48:22 -07:00
Tim Abbott
d232ce0078 settings: Fix comment explaining NOREPLY_EMAIL_ADDRESS.
This documentation comment incorrectly claimed that we don't use
NOREPLY_EMAIL_ADDRESS when ADD_TOKENS_TO_NOREPLY_ADDRESS=True.

Fixes #12169.
2019-04-23 14:48:22 -07:00
Vishwesh Jainkuniya
4f7c463257 notifications: Add user_id in the GCM & APNS payload.
This makes it easy to uniquely identify the user account associated
with a notification by, for example, the (realm_uri, user_id) pair.

This helps improve notifications in the mobile apps.
See https://github.com/zulip/zulip-mobile/pull/3407#discussion_r266196616

Fixes #11961.
2019-04-22 15:59:20 -07:00
Tim Abbott
2eb713552f docs: Make sure that postgresql is running in OS upgrade instructions.
At least in the Trusty->Xenial upgrade flow, it can end up not running.
2019-04-22 15:59:20 -07:00
Tim Abbott
2da9d25a9a docs: Add OS upgrade step to remove upstart.
It's not required on Ubuntu Xenial (having been replaced by systemd)
and causes problems when installing/upgrading other packages; this
change matches a similar block of code in our installer.
2019-04-22 15:59:19 -07:00
Tim Abbott
388565c7bd script: Add static asset pipeline option to support OS upgrades.
The comment explains this in more detail, but basically one previously
needed the `--from-git` option to `upgrade-zulip-stage-2` if one had
last installed/upgraded from Git, and not that option otherwise, which
would have forced us to make the OS upgrade documentation much more
complicated than it needed to be.
2019-04-22 15:59:19 -07:00
Tim Abbott
a88643313f docs: Clarify some key parts of OS upgrade documentation.
Thanks to Vishnu Ks for testing to figure these out.
2019-04-22 15:59:19 -07:00
Anders Kaseorg
6d7a3cf4d7 restore-backup: Open backup tarball as root.
Fixes permission errors when running restore-backup on a tarball
inaccessible to the zulip user.

Fixes #12125.

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-04-17 12:27:32 -07:00
Anders Kaseorg
8f1ac265e4 restore-backup: Reset cwd when switching to postgres user.
Fixes permission errors when running restore-backup from a cwd
inaccessible to the postgres user.

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-04-17 12:27:32 -07:00
Shubham Padia
38af195ab4 backup: Make --output an optional argument instead of a positional one.
Fixes #12150.
Previously the `output` argument was positional, while the docs described
the arguments as optional in the form of `--output=...`.
2019-04-17 12:27:32 -07:00
Shubham Padia
e63245eee3 backup: Add option --skip-uploads to skip uploads backup. 2019-04-17 12:27:32 -07:00
Shubham Padia
cb86bb7d84 backup: Add option --skip-db to skip database backup.
This may be relevant for organizations that use a corporate remote
postgres server and just want to backup their configuration.
2019-04-17 12:27:32 -07:00
Sameer Choubey
b1d5bb4ae4 api_docs: Add explicit '-X GET' to curl examples.
When passing arguments with the `-d` syntax, which is convenient for 
command-line examples, one needs to specify `-X GET` for curl to work
properly.

Fixes #12116
2019-04-17 12:20:05 -07:00
Tim Abbott
1c0653136c docs: Document upgrading the version of Ubuntu.
One longstanding gap in our production documentation is how to
properly do an upgrade to the operating system on which Zulip is
installed.

This adds that documentation.

Ideally, we'd get a few folks to test this procedure over the next few
days to make sure it's bulletproof.

Fixes #1705.
Fixes #10796.
2019-04-17 12:19:31 -07:00
Wyatt Hoodes
3db5a03f5c compose.scss: Fix alignment of "markdown preview" icons.
Removed the preview tag from the css rule, reduced the undo preview tag
to a font-size of 15px.

The preview tag being attached to the rule proved unnecessary. The icon
for reverting back to an editing state also dipped below the horizontal
level of the icon row.
2019-04-17 12:19:25 -07:00
Puneeth Chaganti
967ff6f770 bugdown: Make the youtube URL regex slightly easier to read. 2019-04-17 12:19:02 -07:00
Puneeth Chaganti
67cb813740 bugdown: Show preview for urls copied from the Youtube share widget. 2019-04-17 12:18:59 -07:00
Tim Abbott
5f2c3cd835 compose: Fix buggy escaping of LaTeX in quote-and-reply.
Apparently, our use of JavaScript string `.replace()` here was buggy,
because replace() has several special escape sequences starting with
`$` if they appear in the replacement content string.  We can work
around this through something of a hack, which is to pass a function
as the second argument to replace, which seems cleaner than replacing
all $s with $$s.

Thanks to Shreya for the report.
2019-04-17 12:18:05 -07:00
Anders Kaseorg
7b897cac77 postgres_master.pp: Fix wacky su command line.
The construction `su postgres -c -- bash -c 'psql …'` didn’t behave the
way it reads, and only worked by accident:

1. `-c --` sets the command to `--`.
2. `bash` sets the first argument to `bash`.
3. `-c 'psql …'` replaces the command with `psql …`.

Thus, `su` ended up executing `<shell> -c 'psql …' bash`, where
`<shell>` is the `postgres` user’s login shell, usually also `bash`,
which then executed 'psql …' and ignored the extra `bash`.

Unconfuse this construction.

Note from tabbott: The old code didn't even work by accident, it was
just broken.  The right fix is to move the quoting around properly.

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-04-17 12:17:59 -07:00
Anders Kaseorg
94395c6dd8 terminate-psql-sessions: Allow running as postgres user.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-04-17 12:17:51 -07:00
Anders Kaseorg
38cd21b1b4 scripts: Rename DEFAULT_USER to POSTGRES_USER.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-04-17 12:17:44 -07:00
Anders Kaseorg
e074165c1b backup: Use tar --transform to arrange the tarball instead of symlinks.
This allows tar to print the real paths in error messages if something
goes wrong.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-04-17 12:17:34 -07:00
Tim Abbott
abe645f1d3 settings: Set a default for SSO_APPEND_DOMAIN.
This means that if a user comments out the field in
/etc/zulip/settings.py, they won't get an error.
2019-04-17 12:17:17 -07:00
Mohit Maroliya
064f5ccf8f docs: Fix a few typos in documentation. 2019-04-17 12:16:45 -07:00
Rohitt Vashishtha
19fbf9c3cf terminate-psql-sessions: Allow running without sudo. 2019-04-17 12:15:37 -07:00
Tim Abbott
eb7e44f7ed configure-rabbitmq: Allow running as root.
This makes it possible to run this in production without access to
sudo.
2019-04-17 12:15:19 -07:00
Harshit Bansal
b08824d92f commands: Fix handling of keyword arguments in query_ldap command.
This bug seems to be introduced by me while doing the refactoring
in `94649f58f2fe0ed78d84e597ad6676522cfef9be`.

Fixes: #12006.
2019-04-17 12:14:49 -07:00
Anders Kaseorg
d9a1617d00 scripts: Fix exec invocation for in-process virtualenv activation.
activate_this.py has always documented that it should be exec()ed with
locals = globals, and in virtualenv 16.0.0 it raises a NameError
otherwise.

As a simplified demonstration of the weird things that can go wrong
when locals ≠ globals:

    >>> exec('a = 1; print([a])', {}, {})
    [1]
    >>> exec('a = 1; print([a for b in [1]])', {}, {})
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<string>", line 1, in <module>
      File "<string>", line 1, in <listcomp>
    NameError: name 'a' is not defined
    >>> exec('a = 1; print([a for b in [1]])', {})
    [1]

Top-level assignments go into locals, but from inside a new scope like
a list comprehension, they’re read out of globals, which doesn’t work.

Fixes #12030.

Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-04-17 12:14:27 -07:00
Anders Kaseorg
6f2903dd29 restore-backup: Set the recreated database owner to zulip.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-04-16 17:57:31 -07:00
sameerchoubey
afd06bdb46 api_docs/send-message: Specify request command in curl example.
This commit is related to #11927.
2019-04-16 17:56:17 -07:00
Tim Abbott
57cdef11c4 settings: Move production noreply templates.
These previously lived in Optional settings, which generally caused
users to not read it.

(Also do a bit of reorganization of the "optional settings" area).
2019-04-16 17:55:47 -07:00
Zach Wener-Fligner
8020247b79 docs: Modify dev SSL/certbot setup docs to match script.
The docs specify passing hostname with the --hostname flag, which
doesn't match the actual usage in scripts/setup/setup-certbot. This
change fixes the docs to match the actual usage.
2019-04-16 17:53:28 -07:00
Tim Abbott
01adbc3a2e puppet: Make uwsgi buffer size configurable. 2019-04-16 17:53:06 -07:00
Tim Abbott
8b739e4d0b settings: Fix webapp password change UI.
Apparently, this has been broken since
dee4e3fb89, due to the beforeSend code
here overriding the default beforeSend function that sets the CSRF
token.  The correct fix was actually to just run the relevant code
directly before the channel.patch call.

Fixes #11938.
2019-04-16 17:52:46 -07:00
vipul chhabra
1fb079d63b message view: Fix The unexpected behavior of Youtube Thumbnail.
It is observed in Mozilla margin was considered from other side of thumbnail
due to some special padding issues observed in mozilla.

To fix this top and left value are assigned to 0 so that it automatically
takes its correct position in all browsers

Fixes #11867.
2019-04-16 17:52:40 -07:00
Hemanth V. Alluri
95482235ad context_processors: Do not render inline previews for realm description.
We never intended to render them for this use case as the result would
not look good, and now we have a convenient bugdown option for
controlling this behavior.

Since we're not storing the markdown rendering anywhere, there's
conveniently no data migration required.

Fixes #11889.
2019-04-16 17:52:01 -07:00
Tim Abbott
f8d74fab08 Release Zulip Server 2.0.2. 2019-03-15 11:39:10 -07:00
vsvipul
049b83f0bb image-action: Fix open and download hover highlight in night mode.
When we try to hover over Open or Download they were not highlighted
in night mode, because of incorrect specificity. This commit adds
highlighting in night mode (possibly fixing a regression when we made
night mode less aggressive about hover).

Fixes #11887.
2019-03-15 11:39:10 -07:00
Tim Abbott
bffa709ec8 auth: Use HTTP status 404 for invalid realms.
Apparently, our invalid realm error page had HTTP status 200, which
could be confusing and in particular broken our mobile app's error
handling for this case.
2019-03-15 11:32:28 -07:00
Tim Abbott
ddae999601 send_test_email: Clean up output and provide advice.
Previously, while we sent emails using both noreply addresses, we
didn't make clear what was going on, leading to some potential
confusion.
2019-03-15 11:32:12 -07:00
vsvipul
57cd185366 portico: Fix broken electron check condition for password reset.
This logic for passing through whether the user was logged in never
worked, because we were trying to read the client.

Fix this, and add tests to ensure it never breaks again.

Restructured by tabbott to have completely different code with the
same intent.

Fixes #11802.
2019-03-15 11:32:03 -07:00
Tim Abbott
d39a7ea429 slack import: Fix handling of tombstone files.
Apparently, the mode attribute is not always present.
2019-03-15 11:31:21 -07:00
Tim Abbott
088f8745d1 slack import: Skip processing tombstone files.
The tombstone files undocumented feature of Slack's export format
appears sometimes and has no real data, so we just need to skip these.

Fixes #11619.
2019-03-13 12:55:51 -07:00
Harshit Bansal
f32f02da8b ldap: Ensure email is valid for realm before registering.
Previously, the LDAP authentication model ignored the realm-level
settings for who can join a realm.  This was sort of reasonable at the
time, because the original LDAP auth was an SSO solution that didn't
allow multiple realms, and so one could fully configure authentication
settings on the LDAP side.  But now that we allow multiple realms with
the LDAP backend, one could easily imagine wanting different
restrictions on them, and so it makes sense to add this enforcement.
2019-03-13 12:55:42 -07:00
Anders Kaseorg
76d6d69568 css: Replace generated U+202A LEFT-TO-RIGHT EMBEDDING with CSS properties.
These generated characters (added in #9889) were causing poor wrapping
behavior, at least in Firefox.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-03-13 12:55:21 -07:00
Tim Abbott
4a1e98f574 stream: Fix validator for stream colors.
Apparently, our new validator for stream color having a valid format
incorrectly handled colors that had duplicate characters in them.

(This is caused in part by the spectrum.js logic automatically
converting #ffff00 to #ff0, which our validator rejected).  Given that
we had old stream colors in the #ff0 format in our database anyway for
legacy, there's no benefit to banning these colors.

In the future, we could imagine standardizing the format, but doing so
will require also changing the frontend to submit colors only in the
6-character format.

Fixes an issue reported in
https://github.com/zulip/zulip/issues/11845#issuecomment-471417073
2019-03-13 12:55:00 -07:00
Eeshan Garg
487632b454 webhooks/zapier: Support authentication for the Zapier Zulip app.
If the user sets up a Zap using an incoming webhook bot's API
key, the authentication goes through our webhook.
2019-03-13 12:54:51 -07:00
Eeshan Garg
848276ee3b webhooks/github: Ignore organization and milestone events.
These events are not super useful and were cluttering up our
webhook logs.
2019-03-13 12:54:48 -07:00
Eeshan Garg
d740b1ae19 webhooks/github: Restrict membership event scope to teams.
According to GitHub's webhook docs, the scope of a membership
event can only be limited to 'teams', which holds true when a
new member is added to a team. However, we just found a payload
in our logs that indicates that when a user is removed from a
team, the scope of the membership is erroneously set to
'organization', not 'team'. This is most likely a bug on
GitHub's end because such behaviour is a direct violation of
their webhook API event specifications. We account for this
by restricting membership events to teams explicitly, at least
till GitHub's docs suggest otherwise.
2019-03-13 12:54:45 -07:00
Tim Abbott
48d8b90863 docs: Recommend using an SSD for the Zulip database.
This is sorta common knowledge for folks who have managed databases,
but not everyone has.
2019-03-13 12:54:31 -07:00
Pragati Agrawal
eeeb947187 node_tests: Refactor test_change_save_button_state in settings_org.
This refactors `test_change_save_button_state` function using ES6 syntax,
to make it more clean and readable.
2019-03-13 12:54:24 -07:00
Pragati Agrawal
507cf1d322 settings_org: Fix visibility time of Saved state.
This fixes the bug where the `Saved` state button faded out almost
instantly (that is actually 300 ms) and `Discard` button fades out
along with `Saved` state button; the key problem here was that the
setTimeout intended to fade was actually delaying the transition from
"saving" to "saved".

Now, first of all, we use `setTimeOut` function to fadeout elements giving
fadeout_delay time as `800 ms` and we hide discard button during `saving`
state. Also, when `Discard` button is selected, `Save changes` and `Dicard`
fade out simultaneously.

Fixes: #11737.
2019-03-13 12:54:21 -07:00
Pragati Agrawal
f3f90bb527 settings_org: Refactor change_save_button_state function.
This makes the `change_save_button_state` funtion more clear and readable
by removing too many occurences of `.find()` and `.attr()` function.
2019-03-13 12:54:17 -07:00
Harshit Bansal
46d6541958 tests: Refactor query_ldap() and add complete test coverage. 2019-03-13 12:54:06 -07:00
Harshit Bansal
13eaa49a42 management: Move query_ldap function to zproject/backends.py.
This will make it simpler to organize and unit-test all of our
authentication backend code.
2019-03-13 12:54:02 -07:00
Tim Abbott
1157aef8b3 night mode: Fix initial state of night mode. 2019-03-13 12:53:33 -07:00
Boris Yankov
65eb125d61 cleanup: Remove unnecessary 'magic' style for night mode.
This was introduced in e0236646

For 1.5 years we did not find a case that needed it (besides the
`a` tag hover state, that is not obvious if it was needed or it was
used as an example)

It is not obvious if this solution was a good idea. The concern was
that `body.night-mode` is more specific than `body` and some styles
might override others less specific in cases we might not want that.

Of course, we want that in the majority of cases, and css-specificity
rules are not simple to comprehend.

Good further reading:
http://cssspecificity.com/
https://specificity.keegan.st/

The added complexity of the resulting styles and the added code that
might not serve any practical purpose seem to not be worth it.
2019-03-13 12:53:30 -07:00
Ben Muschol
713d6739ec linkifiers: Add no-select to trash icon.
This fixes some annoying copy-paste issues we've seen with users
accidentally getting a weird invisible unicode character in their URL
format string when trying to copy-paste an existing linkifier to
use for a new linkifier.

Fixes #10828.
2019-03-13 12:53:06 -07:00
Tim Abbott
70c0c7a83f node: Fix a node test broken by recent narrowing fix.
The changes in 3baf1f3dbd required some
additions to our test setup code.
2019-03-13 12:52:46 -07:00
Tim Abbott
c1ee7692d6 narrow: Remove "subscribe" button for guests for emptry streams.
This button didn't work, because the backend blocks subscribing, so it
was just confusing.

Fixes an issue reported in #11743.
2019-03-13 12:52:37 -07:00
Abhinav Singh
ad336800d0 sidebar: Allow users to use sidebar search in mobile browser.
It was impossible to search people in mobile browsers because virtual
keyboard used to fire resize event and the function call that we used
to handle this event caused the input field to loose focus and this
made it impossible to type in the people search bar.

The code in this commit fixes this by simply ignoring the resize
events when the user wants to search.

Fixes #11795.
2019-03-13 12:52:29 -07:00
Anders Kaseorg
e9e3eafdde drafts: Fix CSS transition when opening drafts.
The code was all there, but we weren't triggering a style calculation.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-03-13 12:52:14 -07:00
Rohitt Vashishtha
df68a3e963 Revert "bugdown: Process word boundaries properly in realm_filters."
This reverts commit ff90c0101c but keeps
the test cases added for reference.

This was reverted because it was both not a clean solution and created
other realm filters bugs involving dashes (etc.).
2019-03-13 12:51:32 -07:00
Tim Abbott
faaf84bb01 puppet: Fix nginx configuration logic for S3 backend.
Apparently, our testing environment for this configuration was broken
and didn't test the code we thought it did; as a result, a variable
redefinition bug slipped through.

Fixes #11786.
2019-03-13 12:51:11 -07:00
Harshit Bansal
c082547021 ldap: Continue syncing other fields even if a field is missing.
Earlier the behavior was to raise an exception thereby stopping the
whole sync. Now we log an error message and skip the field. Also
fixes the `query_ldap` command to report missing fields without
error.

Fixes: #11780.
2019-03-13 12:50:56 -07:00
Tim Abbott
d6c7199ce1 i18n: Update translation data from Transifex. 2019-03-13 12:49:03 -07:00
Tim Abbott
29b3dd0852 Release Zulip Server 2.0.1. 2019-03-04 17:39:57 -08:00
Tim Abbott
0ffc42083e i18n: Update translations from Transifex. 2019-03-04 17:28:30 -08:00
Tim Abbott
019e5a17f0 docs: Explain options for preventing changes during export.
This makes it a bit clearer that one doesn't need to deactivate a
realm just to export data.
2019-03-04 16:22:18 -08:00
Harshit Bansal
177673c84e portico: Refresh deactivated realm notice page every 60 seconds.
This helps avoid users being confused if a realm was temporarily
deactivated as part of getting a clean backup.

Fixes: #11757.
2019-03-04 16:22:10 -08:00
Harshit Bansal
f6c1a31988 auth: Remove invalid_subdomain restriction from LDAP backend.
Fixes: #11692.
2019-03-04 16:22:04 -08:00
Tim Abbott
870cd00f5f su_to_zulip: Fix detection of zulip user ID.
Apparently, while upgrade-zulip-from-git always ensures that zulip
deployment directories are owned by the Zulip user, unpack-zulip (aka
the tarball code path) has them owned by root.

The user ID detection logic in su_to_zulip's helper get_zulip_uid was
intended to support both development environments (where the user ID
might vary) and production environments.  For development
environments, the existing code is fine, but given this unpack-zulip
permissions issue, we need to have code to fallback to 'zulip' if the
detection logic detects the "zulip" user has having UID 0.
2019-03-04 16:21:53 -08:00
Aaron Raimist
7db599deaa docs: Fix Learn more about mentions link.
It seems like 1871d00bb2 renamed `/help/at-mention-a-user` to `/help/mention-a-user-or-group` but missed this link that shows up on the "You haven't been mentioned yet!" screen. Right now it leads to a "no such article page".
2019-03-04 11:12:56 -08:00
Tim Abbott
84d2be5e0c docs: Fix export/import manage.py instructions typos.
Fixes #11755.
2019-03-04 11:12:48 -08:00
Tim Abbott
d360833d7f nginx: Restructure how we manage uploaded file routes.
The overall goal of this change is to fix an issue where on Ubuntu
Trusty, we were accidentally overriding the configuration to serve
uploads from disk with the regular expressions for adding access
control headers.

However, while investigating this, it became clear that we could
considerably simplify the mental energy required to understand this
system by making the uploads-route file be unconditionally available
and included from `zulip-include/app` (which means the zulip_ops code
can share behavior here).

We also move the Access-Control-Allow-* headers to a separate include
file, to avoid duplicating it in 5 places.  Fixing this duplication
discovered a potential bug in the settings used for Tornado, where
DELETE was not allowed on a route that definitely expects DELETE.

Fixes #11758.
2019-03-04 11:12:44 -08:00
Tim Abbott
bc3db1701b realm_logo: Fix synchronization of realm night logo.
The night logo synchronization on the settings page was perfect, but
the actual display logic had a few problems:

* We were including the realm_logo in context_processors, even though
  it is only used in home.py.
* We used different variable names for the templating in navbar.html
  than anywhere else the codebase.

* The behavior that the night logo would default to the day logo if
  only one was uploaded was not correctly implemented for the navbar
  position, either in the synchronization for updates code or the
  logic in the navbar.html templates.
2019-03-04 11:12:36 -08:00
Rishi Gupta
e8aca7b723 help: Reorganize stream-permissions table. 2019-03-04 11:12:32 -08:00
Tim Abbott
7a72390710 copy: Fix extra space before > in copy-paste styling. 2019-03-04 11:12:11 -08:00
Boris Yankov
3ffe4ca3e5 user status: Make "unavailable" status circle grey.
After discussion, we decided that the red color is too distinct
and does not convey the idea of "almost offline".

This changes the new "unavailable" status circle's color from dark
red to grey, the same color used by the "offline" status circle.
2019-03-04 11:11:52 -08:00
Tim Abbott
ac24fdd4eb Release Zulip Server 2.0.0. 2019-03-01 10:32:10 -08:00
Steve Howell
3fc2a43573 node tests: Fix recent build break.
This is a one-line fix for the new CSS class
we're using for "away".
2019-03-01 10:07:38 -08:00
Boris Yankov
31536a48ef user status: Add icon for "unavailable".
Fixes #11589.

Adds SCSS style for the "unavailable" user status and enables its
usage in `buddy_data.js`.

The style is a red circle with a horizontal line. The values might
look a bit 'magic' but they were considered carefully ` height` of
1px was too thin, 2px was too thick, thus 1.5px was chosen.
2019-03-01 09:56:09 -08:00
Tim Abbott
beec029324 docs: Fix a typo in last update. 2019-03-01 09:33:12 -08:00
Tim Abbott
f450a5ceaa i18n: Update translation data from Transifex. 2019-03-01 09:28:08 -08:00
Tim Abbott
9693d8a651 docs: Extend testing discussion in events system doc.
Importantly, this also makes that section linkable.
2019-03-01 09:23:56 -08:00
Rishi Gupta
2c0b291902 portico: Add ninth logo to /for/open-source testimonial section. 2019-03-01 09:12:50 -08:00
Rishi Gupta
f8c8b41ad8 portico: Fix media parameters for hiding last testimonial logo.
Tested both /hello and /for/open-source.
2019-03-01 09:12:50 -08:00
Eeshan Garg
9252c43225 api/streams: Support including bot owner's subscriptions.
This is important for situations such as with our Zapier app,
where the requesting user may be a bot that would like to access
its owner's subscriptions.

Tweaked by tabbott to eliminate the 2^N growth of cases in
do_get_streams.
2019-02-28 22:32:05 -08:00
Eeshan Garg
85f453998e webhooks/zapier: Remove code related to our official Zapier app.
Our official Zapier app now uses our JS bindings (zulip-js) to
call the API directly and doesn't need to go through the webhook
anymore for anything.
2019-02-28 22:09:35 -08:00
Raymond Akornor
4603cdba7e tests: Optimize a slow test in tests_bots.py.
tests now ran in 7.649s from 9.297s.  And this test works just as well
with 3 bots, since only 3 database queries with 3 bots confirms we're
not doing linear queries in the number of bots in the organization.
2019-02-28 22:01:55 -08:00
Rishi Gupta
48eb0c2358 help: Update start-a-call to include Hangouts and Zoom. 2019-02-28 17:11:27 -08:00
Rishi Gupta
9357e17b93 help: Add private-messages. 2019-02-28 17:11:27 -08:00
Rishi Gupta
812f62c8b3 help: Add user-groups. 2019-02-28 17:11:27 -08:00
Rishi Gupta
1871d00bb2 help: Update at-mention-a-user to include user groups.
Also changes the terminology for this feature from at-mention to
mention.
2019-02-28 17:11:27 -08:00
Tim Abbott
de65a04ae0 streams: Disable inline URL preview when rendering stream descriptions.
We want to use the baseline features of bugdown, but not fancy things
like inline URL previews, since the whole structure of stream
descriptions is to have a single-line thing supporting some
formatting.

The migration part of this change fixes a bug encountered by some
organizations upgrading from older versions of Zulip.
2019-02-28 17:00:40 -08:00
Tim Abbott
d6c09eac51 bugdown: Add support for no_previews argument.
This allows us to have some features using bugdown rendering where
inline image previews will not be rendered (which would be problematic
for e.g. stream descriptions).
2019-02-28 16:54:04 -08:00
Tim Abbott
62dc6dda49 guests: Block guest user access to default streams.
Guest users will just get an empty list of default streams; we also
hide the "Default streams" organization view from the guest users UI.

This is for consistency with not providing guest users the full list
of streams in an organization.
2019-02-28 16:36:30 -08:00
Tim Abbott
1ce0e8256b zoom: Avoid sending Zoom API secret to other admin clients.
Fixing this involves fixing the backend to handle unchanged field
submissions of the Zoom credentials without trying to re-validate the
credentials (for performance) as well as to fetch the already-sent
secret.
2019-02-28 15:43:42 -08:00
Tim Abbott
0a0ac24d62 settings: Disable autocomplete on various text fields.
This prevents browser autocomplete from annoying trying to insert
values into these settings fields.
2019-02-28 15:39:34 -08:00
Tim Abbott
7fb0122ab3 settings: Fix weird live update when saving zoom form.
Previously, we would reset the state of the form to what it was before
the current change just after saving.
2019-02-28 15:39:34 -08:00
Rishi Gupta
d833c70dc7 org settings: Explain Zoom support is experimental, and fix a few strings.
Visually, #zoom_help_text acts like
.organization-settings-parent div:first-of-type when the Zoom option
is selected, but isn't treated as such.

No visual change with the #google_hangouts_domain change; just there to make
the code more readable/defensible.
2019-02-28 15:09:35 -08:00
Anders Kaseorg
88e90d34b9 try_git_describe: Set cwd, not --git-dir.
git describe --dirty requires a working tree, not just a repository.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-28 14:59:33 -08:00
Rishi Gupta
9962377018 analytics: Fix midnight-related bug in test.
Previously, this would flake if the day changed between
user2 = do_create_user('email2', 'password', ...) and
do_deactivate_user(user2).
2019-02-28 14:48:30 -08:00
Rishi Gupta
5692acdf04 help: Update delete-a-topic. 2019-02-28 14:48:07 -08:00
Rishi Gupta
dbb4817128 help: Rename make-a-user-an-administrator to include guests. 2019-02-28 14:48:07 -08:00
Rishi Gupta
1730a9b355 help: Make it clearer that guests can see other members. 2019-02-28 14:48:07 -08:00
Rishi Gupta
ddad11c43a help: Add silent mentions to format-your-messages-using-markdown. 2019-02-28 14:48:07 -08:00
Rishi Gupta
e1f091f724 help: Add missing link to moderating-open-organizations. 2019-02-28 14:48:07 -08:00
Rishi Gupta
35af34049b help: Add announcement-only-streams.md. 2019-02-28 14:48:07 -08:00
Rishi Gupta
59f7e7d346 help: Add Room to about-streams-and-topics table. 2019-02-28 14:48:07 -08:00
Rishi Gupta
8e503c9ac7 help: Add a few topic-related tips for administrators. 2019-02-28 14:48:07 -08:00
Rishi Gupta
58829b7646 help: Add start-a-new-topic. 2019-02-28 14:48:07 -08:00
varunvaruns9
6725d921ac popovers: Fix toggling of user popover.
Fix the logic for closing user popover on clicking
the chevron again in the buddy list.

Fixes: #11690.
2019-02-28 14:45:16 -08:00
Anders Kaseorg
c6e60ebf0e backup: Set cwd while running pg_dump.
This avoids a spurious permission error inside the Postgres
`resolve_symlinks` function if we don’t have access to the current
working directory (e.g. we’re running with cwd /root inside `su
zulip`).

While we’re here, add a defensive `--` argument.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-28 14:40:28 -08:00
Tim Abbott
bc3b864754 export: Add a bunch of comments to our export tool. 2019-02-28 12:20:08 -08:00
Tim Abbott
de6f724bc5 middleware: Avoid doing work for statsd when not enabled.
This saves about 8% of the runtime of our total response middleware,
or equivalently close to 2% of the total Tornado response time.  Which
is pretty significant given that we're not sure anyone is using statsd
in production.

It's also useful outside Tornado, but the effect is particularly
significant because of how important Tornado performance is.
2019-02-27 17:53:15 -08:00
Tim Abbott
c955b20131 middleware: Don't repreatedly regenerate open graph functions.
This avoids parsing these functions on every request, which was
adding roughly 350us to our per-request response times.

The overall impact was more than 10% of basic Tornado response
runtime.
2019-02-27 17:53:13 -08:00
Tim Abbott
42a5dc2649 requirements: Add line_profiler.
This library is super useful for doing line-by-line profiling of code
paths that we want to be really fast.
2019-02-27 17:48:49 -08:00
Tim Abbott
f289801d23 requirements: Update Django to latest security release. 2019-02-27 17:02:02 -08:00
Tim Abbott
ab95704d2d settings: Fix mismatch of templates with JavaScript.
The alignment between the "Organization settings" code/labels and the
actual logic was broken in 65f6bea7d7
and the related commits.
2019-02-27 16:18:36 -08:00
Tim Abbott
7717337b1e message_edit: Fix rendering bug when topic-editing single messages.
If you topic-edited a single message within a narrow, we would update
all our unreads/sidebar/etc. data structures, and would rerender the
message if appropriate.  However, for the corner case of being inside
a topic narrow when you did this, we didn't have logic to remove the
message from the narrow (which is the appropriate situation when you
just topic-edited a message in a narrow).

When topic-editing multiple messages including the currently selected
message (the more common case), we would end up changing the narrow,
resulting in this issue being masked.

Fixes #11601.
2019-02-27 13:57:45 -08:00
Tim Abbott
da043f163d Revert "docs: Add Zulip logo to ReadTheDocs heading."
This reverts commit 579e2e8b2b.
2019-02-27 13:31:44 -08:00
Tim Abbott
60f33a374d streams: Fix announcement-only option being hidden.
Fixes an unpleasant regression in
746870df65.
2019-02-27 13:29:45 -08:00
Tim Abbott
f40cbdbd19 compose: Fix extra space being added by quote-and-reply.
The correct behavior here is that we want to ensure there is
whitespace in between the syntax being added and the content on either
side.  Our smart_insert logic handled this for the cases that were
common with inserting emoji (etc.), but didn't handle the more complex
cases with "quote and reply".

Fixes #11702.
2019-02-27 13:22:25 -08:00
Samuel Searles-Bryant
579e2e8b2b docs: Add Zulip logo to ReadTheDocs heading.
Add the Zulip logo to the docs that will appear on readthedocs.
Also remove the house logo and "Zulip" text that appear above the logo.

Fixes: #11700.
2019-02-27 12:54:40 -08:00
Steve Howell
7cbee8af5b left-sidebar: Fix title tag for "Private messages".
The title tag should be over the text, not the
entire list item.  This prevents strange hovers
for sublist items like the new green/orange
circles.
2019-02-27 12:20:05 -08:00
Steve Howell
b57c9a85d5 left-sidebar: Remove unused hover-underline class.
The CSS for this was removed in
953ee778f3.
2019-02-27 12:19:31 -08:00
Paurakh Sharma Humagain
e9131b031b docs: Make the vagrant guide clone steps pasteable.
After the user clones Zulip they should first get inside the directory
before adding the remote upstream.

Tweaked by tabbott to make a bit simpler.
2019-02-27 12:09:09 -08:00
Tim Abbott
cefebd87a4 docs: Mention bug in ALWAYS_SEND_ALL_HOTSPOTS feature.
This should avoid some wasted time.
2019-02-27 10:21:30 -08:00
Mohit Gupta
70d54b5a5a compose: Add shortcut hint to New topic and New stream message button.
Fixes: #11678.
2019-02-27 10:05:50 -08:00
Rishi Gupta
6d51b25fc6 help: Rework docs for joining and inviting. 2019-02-27 09:33:37 -08:00
Rishi Gupta
b67709a1c8 help: Update explanation of closed compose box in open-the-compose-box. 2019-02-27 09:29:37 -08:00
Rishi Gupta
ac6f628c44 help: Rework Navigation and unread counts content. 2019-02-26 22:48:04 -08:00
Tim Abbott
216d2ec1bf production: Add optional support for submitting usage statistics.
See documentation for details.
2019-02-26 17:35:10 -08:00
Greg Price
de2f1ee0c4 push notif: Make O(1) database queries in handle_remove_... 2019-02-26 16:41:55 -08:00
Greg Price
b0a84cd7ab message: Add an O(1)-query variant of bulk_access_messages.
We'll use this in the push-notifications code, in a context where
there should definitely already be UserMessage rows if everything's
gone normally... but explicitly checking at the top seems like the
right pattern from a secure-coding perspective.
2019-02-26 16:41:54 -08:00
Greg Price
9869153ae8 push notif: Send a batch of message IDs in one remove payload.
When a bunch of messages with active notifications are all read at
once -- e.g. by the user choosing to mark all messages, or all in a
stream, as read, or just scrolling quickly through a PM conversation
-- there can be a large batch of this information to convey.  Doing it
in a single GCM/FCM message is better for server congestion, and for
the device's battery.

The corresponding client-side logic is in zulip/zulip-mobile#3343 .

Existing clients today only understand one message ID at a time; so
accommodate them by sending individual GCM/FCM messages up to an
arbitrary threshold, with the rest only as a batch.

Also add an explicit test for this logic.  The existing tests
that happen to cause this function to run don't exercise the
last condition, so without a new test `--coverage` complains.
2019-02-26 16:41:54 -08:00
Greg Price
28ff9670de push notif: Push gcm_options logic inside "payload" helpers.
These are logically closely related.
2019-02-26 16:41:54 -08:00
Greg Price
8f26e12c85 push notif: Clarify get_*_payload, and factor another out.
This is a pure refactor; adding docstrings, making some names more
explicit, and pulling out one small helper.
2019-02-26 16:41:54 -08:00
Greg Price
69ded8b1b4 push notif: Drop irrelevant fields in remove payloads.
These fields don't make much sense in this case; and the client
doesn't look at them and never has.  Stop including them.
2019-02-26 16:41:54 -08:00
Tim Abbott
9fec2a1e2a i18n: Update translation data from Transifex. 2019-02-26 16:35:27 -08:00
Wyatt Hoodes
5231b27dea popovers: Add a clear status option in user popover.
Accomplished by adding a function to clear the status message with
an empty string. The html is then updated to reflect changes without a
refresh.

Currently, it's a small hassle to clear a status message.  This option
makes things a bit easier.

Fixes #11630.
2019-02-26 14:40:17 -08:00
Steve Howell
3697add70c settings: Reset scroll when switching sections. 2019-02-26 14:26:15 -08:00
Anders Kaseorg
c6da0d13cd docs: Update links to skip help.github.com redirects.
help.github.com seems to have a bug where HEAD on a redirected page
returns 404.  This causes tools/test-documentation to fail.  Fix it by
skipping the redirects.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-26 11:03:08 -08:00
Tim Abbott
f096472b1d Revert "condense/collapse: Fix MLV to update for new messages."
This reverts commit a6793a14f1.

This was causing weird 0-height display issues.
2019-02-26 10:40:31 -08:00
Steve Howell
bca38200a8 message_store: Add an each helper.
This new helper allows us to do the same operation
on every message in our message_store.  We will
use this in a future commit to clear the `is_tall`
flags on all messages, after a resize.

We should be somewhat cautious about using this,
but simple operations should be really fast, even
if you have lots of messages in the store.
2019-02-25 21:12:07 +00:00
Steve Howell
a6793a14f1 condense/collapse: Fix MLV to update for new messages. 2019-02-25 21:12:07 +00:00
Tim Abbott
cd0db08b14 lint: Fix a too-long line. 2019-02-25 10:06:37 -08:00
Tim Abbott
cc8021a742 message_list: Fix focus issues when editing last message.
Previously, if you were in the process of editing the last message in
a narrow and a new message came in, we'd rerender that second-to-last
message, causing your editing widget to lose focus (and thus the next
few keys you typed to be interpreted as keyboard shortcuts, which
had a good chance of resulting in your navigating somewhere random).

This rerendering was essentially unnecessary; the only change to state
going into the rendering process was the next_is_same_sender CSS class
being toggled on the messagebox in the message.  So, at most, we
should have been just toggling that CSS class (and this commit makes
us do precisely that).

It seems like we could further improve this code by just removing the
next_is_same_sender CSS class entirely and removing this block, but
I'm leaving that for follow-up work.

Fixes #11656.
2019-02-25 10:03:49 -08:00
overide
93f9082071 left sidebar: Fix closing stream search.
This fixes an issue where closing stream search was not working if
user had not entered a search term and tried to close the search box
by clicking on the close icon; the problem was that we'd end up
re-opening the widget immediately after through event propagation.

Fixes: #11636.
2019-02-25 09:47:44 -08:00
Tim Abbott
7312189be0 message_edit: Fix compose icons appearing for topic-editable messages.
The is_editable field includes topic edits, so we need a separate
field for whether to display these icons which are all for content
editing.

Fixes #11666.
2019-02-24 11:29:37 -08:00
Tim Abbott
094dcac2dc message_edit: Fix content editing icons appearing in "view source".
These icons was misplaced during a recent refactoring, resulting in
the compose icons appearing even for non-editable messages.

Fixes part of #11666.
2019-02-24 11:29:07 -08:00
synicalsyntax
db37192857 integrations: Rename Google logo to bypass Adblock Plus.
Adblock Plus's "Block social media icons tracking" setting blocks
images with for social media platforms in their names from loading, so
we rename the Google logo to bypass this.
2019-02-24 11:09:02 -08:00
synicalsyntax
33bd52388a integrations: Rename social media logos to bypass Adblock Plus.
Adblock Plus's "Block social media icons tracking" setting blocked
integration logos for social media platforms from loading, so the logos
are renamed to bypass this.

Fixes #11590.
2019-02-23 10:56:43 -08:00
synicalsyntax
d6483a99d0 integrations: Update xkcd logo. 2019-02-22 18:16:29 -08:00
synicalsyntax
ec866844ac integrations: Update Matrix logo. 2019-02-22 18:16:29 -08:00
synicalsyntax
26d92b422f integrations: Improve resolution of IRC logo. 2019-02-22 18:16:29 -08:00
Anders Kaseorg
9faa009f66 lint: Prohibit unused imports.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-22 16:54:50 -08:00
Anders Kaseorg
f1ec67c614 python: Mark intentionally unused imports with noop statements.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-22 16:54:47 -08:00
Anders Kaseorg
649235cfec python: Remove unused imports.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-22 16:54:36 -08:00
Eeshan Garg
8821b5a903 webhooks/pagerduty: Account for missing trigger summary data.
Some incoming payloads do not include details such as the trigger's
summary and description.
2019-02-22 15:59:28 -08:00
Eeshan Garg
912931e1bc webhooks/trello: Support updateCheckItemStateOnCard events. 2019-02-22 15:59:28 -08:00
Eeshan Garg
788dd48c93 webhooks/trello: Ignore createCheckItem events.
Notifications for every check item that is added to a card's
check list would be too noisy.
2019-02-22 15:59:28 -08:00
Eeshan Garg
9af2aa5566 webhooks/trello: Recommend wrapping webhook URL in quotes.
The ampersand in the query string of a URL can confuse bash,
leading to situations where anything in the URL beyond the
ampersand isn't parsed.
2019-02-22 15:59:28 -08:00
Anders Kaseorg
1e2bd553fb setup-certbot: Remove --force-renewal. (#11652)
There’s no reason to do this unless you’re, like, trying to trip the
Let’s Encrypt rate limits (or perhaps trying to manually test this code).

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-22 15:50:38 -08:00
Rishi Gupta
2d5a33225a help: Fix typo in getting-your-org-started-with-zulip. 2019-02-22 15:21:46 -08:00
Rishi Gupta
e61202387e help: Fix duplicated link in getting-your-org-started-with-zulip.
Fixes: #11635
2019-02-22 15:19:42 -08:00
Challa Venkata Raghava Reddy
e7fb19c8b0 invitations: Fix email validation errors for deactivated accounts.
This provides a much clearer error message when trying to invite a
user who has a deactivated account.

Fixes part of #8144.
2019-02-22 14:27:22 -08:00
Rohitt Vashishtha
62007d3e38 compose: Do not show compose-invite-users row for silent mentions. 2019-02-22 13:17:47 -08:00
Rohitt Vashishtha
c504fa98aa typeahead: Show only users in silent mentions typeahead. 2019-02-22 13:17:47 -08:00
Vaibhav
69c16ab90d messagebox: Change alert message background to dark in night mode.
When copying a message by clicking on "copy and close" button in
message edit box an alert appears that says "Copied!"; Background
of the message is set corresponding with the day mode but not the
night mode. This changes the background of the alert message to
the dark color in night mode.
2019-02-22 13:12:00 -08:00
Puneeth Chaganti
b8e25677ef digest: Remove unnecessary scroll bar for private messages. 2019-02-22 13:09:26 -08:00
Priyanshu Singh
e328671f20 docs: Fix a typo in the-git-difference.md.
Fix a small typing error, correcting 'has' to 'hash'.
2019-02-22 13:01:45 -08:00
Anders Kaseorg
ce2474c0ad css: Fix unread marker gap in night mode.
Instead of drawing a white border between unread markers, leave a real
space.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-22 13:01:03 -08:00
Rishi Gupta
51a8748d23 features: Advertise integrations with IRC, Matrix, and Slack. 2019-02-21 16:36:45 -08:00
Rishi Gupta
be9d1b5411 features: Rename Presence and Branding. 2019-02-21 16:36:23 -08:00
Rohitt Vashishtha
185da99ccb typeahead: Fix accidental overwrite of message content on select.
Also adds tests to ensure that we do not accidentally overwrite
the 'beginning' variable that contains the message content upto
that point. These should prevent similar errors in the future.

The bug was added in 8119258c4d.
2019-02-21 11:34:51 -08:00
Tim Abbott
5e96f53948 realm_logo: Display with target background, not current background.
This makes it a lot more clear what this feature will look like.
2019-02-20 18:04:04 -08:00
Tim Abbott
4df8a2ac0f settings: Fix handling of day logo without night logo.
In this case, we should just use the day logo for both themes.
2019-02-20 17:55:48 -08:00
Tim Abbott
12756b48a0 populate_db: Fix help text for --test-suite. 2019-02-20 17:42:30 -08:00
Tim Abbott
7910b9e739 docs: Recommend yarn install over yarn upgrade.
For most updates to our dependencies, we want the more conservative
yarn install.
2019-02-20 16:37:11 -08:00
Eeshan Garg
cfe0f6b56d webhooks/clubhouse: Account for bug in GitHub branch payloads.
This change was prompted by a possible bug on Clubhouse's end. In
general, if a branch is added, it also prompts a workflow state
transition in its primary story.

However, our webhook error logs show an erroneous payload where
the same branch is added to another story, but there is no
workflow state transition. Also, both the stories are grouped in
the same payload, which confused/broke our code. Ideally, this
shouldn't happen and is most likely a bug on Clubhouse's end.
In most cases, changes included in Clubhouse payloads never
pertain to more than one parent entity (stories) simultaneously,
and we usually operate under the assumption that the changes
included therein are related to each other in terms of their
parent object (story or epic) and not a child object (the GitHub
branch).
2019-02-20 16:32:42 -08:00
Eeshan Garg
76b1a8379b webhooks/clubhouse: Support epic_archive events. 2019-02-20 16:32:42 -08:00
Eeshan Garg
51a1b76a1f webhooks/clubhouse: Ignore story comment updates.
Comment updates in general aren't very informative.
Plus, errors for this event type were cluttering up our
webhook logs.
2019-02-20 16:32:42 -08:00
Eeshan Garg
76e58d05cb webhooks/jira: Ignore a few noisy events.
UnexpectedWebhookEventType errors for these events were cluttering
up our webhook error logs.
2019-02-20 16:32:42 -08:00
Eeshan Garg
fa29006311 webhooks/github: Ignore check_suite events.
A check suite is a collection of check runs. We care a lot more
about the outcomes of check runs in this case because check_run
payloads are a lot more informative than check_suite payloads.

(And in any case, the check_suite events are primarily for notifying
tools like CI to run checks).
2019-02-20 16:32:42 -08:00
Eeshan Garg
a0717e4424 webhook/github: Support check_run events.
We only support notifications for events where a check run has
completed. Notifications for when a check run has been queued or
is in progress are not very informative and may be too noisy.
2019-02-20 16:32:39 -08:00
Tim Abbott
4da430e276 message_list: Fix buggy rerendering of dates with local echo.
The bug here was that when we rerendered messages following local echo
through the echo.process_from_server code path, the eventual call to
_rerender_header() made the implicit assumption that all messages in a
message group had the same date.  As a result, it created a totally
new/fake message group and called the rendering logic on that group
without calling the functions for setting up recipient row dates,
which would always result in no recipient bar date being added.  This
bug was latent/invisible before, because when introduced, the locally
echoed messages were always being added to a recipient group from
today, where the recipient bar's date area was by default empty anyway.

This latent bug was revealed when we modified the structure of the app
to do date dividers between individual messages within a message
group, rather than strictly between message groups.
2019-02-20 16:24:28 -08:00
Tim Abbott
f4aa71fc75 server_events: Fix unnecessary call to insert_new_messages.
When we're handling a single message that was locally echoed, there
will very likely be 0 messages not removed by
`echo.process_from_server`, and we can skip the unnecessary call to
`message_events.insert_new_messages`.  This is a small performance
optimization and logical simplification when sending messages.
2019-02-20 16:24:28 -08:00
Wyatt Hoodes
2580965284 test-backend: Rename '--process' option to '--parallel'.
This change is being made to simply match up our naming conventions
with django's test framework.
2019-02-20 13:25:49 -08:00
Tim Abbott
cbc62b8e07 streams: Prevent creation of multi-line stream descriptions.
We do not anticipate our UI for showing stream descriptions looking
reasonable for multi-line descriptions, so we should just ban creating
them.

Given the frontend changes, multi-line descriptions are only likely to
show up from importing content from other tools, in which case
replacing newlines with spaces is cleaner than the alternative.
2019-02-20 12:28:00 -08:00
Hemanth V. Alluri
3134453220 streams_edit: Prevent newline characters in the description.
This commit achieves two things:
  1. Changes the UI of the "Create stream" form to make the
     textarea previously used to get the stream description
     a simple input field of type text (to suggest a single
     line description).

  2. Adds an extra check on the frontend side to make sure that
     when users create a new stream via. the "Create stream"
     option in the settings panel, they can't enter any newline
     characters (i.e. we disallow the enter key from being
     registered when typing out the stream description).
     We must also make sure that they cannot copy-and-paste over
     descriptions containing newline characters.

  resolves #11617
2019-02-20 12:27:54 -08:00
Rohitt Vashishtha
95d04386e2 docs: Add docs for silent mentions syntax. 2019-02-20 10:41:42 -08:00
Rohitt Vashishtha
8119258c4d typeahead: Migrate from _@ to @_ for silent mentions.
We also clean up the code a little to make it easier to
read and combine the matching code for both mentions and
silent_mentions.
2019-02-20 10:41:42 -08:00
Rohitt Vashishtha
5c2e64d6a2 tests: Fix accidental uses of assert() -> assert.equal(). 2019-02-20 10:41:42 -08:00
Rohitt Vashishtha
92658d2ac9 markdown: Move code related to @mentions to markdown.js.
For consistency, we should keep all the code that works with
@mentions in markdown.js. In this case, message_list_view was
rewriting the contents of the mentions in cases where users'
names had been changed since we rendered their mention.
2019-02-20 10:41:42 -08:00
Rohitt Vashishtha
44ec83ef28 markdown: Render silent mentions as **name**.
This change should help people discover to distinguish
silent mentions in text as a part of Zulip syntax while
differentiating them from regular mentions.
2019-02-20 10:41:42 -08:00
Rohitt Vashishtha
57b9991396 markdown: Change syntax of silent mentions ( _@person -> @_person). 2019-02-20 10:41:42 -08:00
Steve Howell
cdce66813e drafts: Fix date-sensitive test.
To test formatting we want a hard coded date, so we
can verify the date arithmetic with stable dates.

To make the test less brittle, we disable the
feature to remove old drafts.

This was an emergency fix.  We should probably just
remove the last N drafts instead of having the 30-day
limit.  Or we should have a better way to stub the cutoff
date.
2019-02-20 06:49:19 -08:00
Rishi Gupta
fd77c78a97 integrations: Fix broken link to jira.png.
Fixes regression from 1595162.
2019-02-19 16:39:44 -08:00
Rishi Gupta
8cc387c67f integrations: Run svgo to optimize svg files.
Fixes broken build.
2019-02-19 16:10:17 -08:00
Rishi Gupta
e40731574a integrations: Fix missing logo for trello.
Fixes regression from 6f8481c.
2019-02-19 15:41:18 -08:00
synicalsyntax
f08e8c8ffc integrations: Update Freshdesk logo.
Eliminated legacy logo.
2019-02-19 15:08:45 -08:00
synicalsyntax
498cf1b905 integrations: Improve resolution of Greenhouse logo. 2019-02-19 15:07:25 -08:00
synicalsyntax
03d4f248fd integrations: Improve resolution of Gosquared logo. 2019-02-19 15:07:24 -08:00
synicalsyntax
bf4c7d409a integrations: Update Statuspage logo.
Converts logo from PNG to SVG format.
2019-02-19 15:07:24 -08:00
synicalsyntax
ccd06100d5 integrations: Update Raygun logo.
Updates legacy logo and converts logo from PNG to SVG format.
2019-02-19 15:07:24 -08:00
synicalsyntax
f0f3f88dd3 integrations: Update Flock logo.
Updates legacy logo and converts logo from PNG to SVG format.
2019-02-19 15:07:24 -08:00
synicalsyntax
6e18040da0 integrations: Update Dialogflow logo.
Converts logo from PNG to SVG format.
2019-02-19 15:07:24 -08:00
synicalsyntax
2a5fe09d16 integrations: Update Opsgenie logo.
Converts logo from PNG to SVG format.
2019-02-19 15:07:24 -08:00
synicalsyntax
6ddb03fad9 integrations: Update GoCD logo.
Converts logo from PNG to SVG format.
2019-02-19 15:07:24 -08:00
synicalsyntax
756e95867c integrations: Update Discourse logo.
Converts logo from PNG to SVG format.
2019-02-19 15:07:24 -08:00
synicalsyntax
1595162496 integrations: Update Jira logo.
Converts logo from PNG to SVG format.
2019-02-19 15:07:24 -08:00
synicalsyntax
fc7cf5462f integrations: Update Instagram logo.
Converts logo from PNG to SVG format.
2019-02-19 15:07:24 -08:00
synicalsyntax
b65d9e9e10 integrations: Update Clubhouse logo.
Updates legacy logo and converts logo from PNG to SVG format.
2019-02-19 15:07:24 -08:00
synicalsyntax
5bf89b946d integrations: Update Bitbucket logo.
Converts logo from PNG to SVG format.
2019-02-19 15:07:24 -08:00
synicalsyntax
6f8481cd33 integrations: Update Trello logo.
Converts logo from PNG to SVG format.
2019-02-19 15:07:24 -08:00
synicalsyntax
f1a2fe74a6 integrations: Update Beeminder logo.
Converts logo from PNG to SVG format.
2019-02-19 15:07:24 -08:00
synicalsyntax
2b78b643d8 integrations: Update Groove logo.
Eliminated legacy logo and changes logo to SVG format.
2019-02-19 14:56:55 -08:00
synicalsyntax
43cf75c075 integrations: Improve resolution of Zendesk logo. 2019-02-19 14:56:55 -08:00
Raymond Akornor
4dc7f5354d tests: Optimize test-backend performance.
This optimizes test-backend by skipping webhook
tests when run in default mode.

Tweaked by tabbott to extend the documentation and update the CI
commands.
2019-02-19 14:50:41 -08:00
Eeshan Garg
c78c3f423c webhooks/github: Ignore project_card events.
The payloads for this event are missing some important details
about the Project's changes, such as the name of the project,
the card's column name, etc. Without such details, the resultant
notifications would not be useful at all!
2019-02-19 14:25:38 -08:00
Eeshan Garg
ec81410b03 webhooks/github: Ignore repository_vulnerability_alert event.
This event isn't incredibly common/useful and errors for this
event were cluttering up our webhook logs.
2019-02-19 18:01:05 -03:30
alex
254da4ad81 send_button: Remove unnecessary self-cancelling margin. 2019-02-19 12:14:17 -08:00
synicalsyntax
4cc49a693b night mode: Improve coloring of emoji picker. 2019-02-18 19:49:24 -08:00
synicalsyntax
c808dcea18 subs: Reorder stream row selectors for SASS nested selector feature. 2019-02-18 16:08:09 -08:00
synicalsyntax
0d32225bdd night mode: Improve coloring of message reactions. 2019-02-18 15:57:51 -08:00
Tim Abbott
fe4a0d0fcd capitalization: Fix night logo lint errors. 2019-02-18 15:53:55 -08:00
synicalsyntax
0581fd3d51 integrations: Increase min-height of page content.
This allows the footer to not fall under the gradient area.

Fixes #11591.
2019-02-18 15:41:41 -08:00
synicalsyntax
e22c637adf landing page: Adjust white fade gradient color.
The background color of the portico pages aren't true white,
so this commit adjusts it to match the actual portico page
background color to eliminate differences.
2019-02-18 15:41:41 -08:00
sahil839
7157edf4af settings: Add support for uploading logo for night mode.
This adds a new field named realm_night_logo which is used for
displaying the organization logo when the user is in night mode.

Fixes #11176.
2019-02-18 15:15:57 -08:00
Steve Howell
e67cf30dfd private messages: Add user circles to top left.
This is mostly adding markup, calling some convenient
functions in buddy_data.js, and adjusting CSS.

To make the circles update dynamically, I mostly
orchestrate this though activity.js for now.  It's
possible we'll want to adjust that eventually to
happen through something like a `presence_events`
dispatcher, but that's essentially what
a good part of `activity.js` does now.
2019-02-18 14:22:37 -08:00
Steve Howell
a6fdac128f refactor: Move huddle_fraction_present() to buddy_data.
This is a pure data function, so there's no sense having
future callers go through activity.js.
2019-02-18 14:22:37 -08:00
Steve Howell
4c27353154 css: Position/size popover user circles in correct file.
We're soon gonna have user circles in four different places,
and the fourth place, Private Messages, will have different
size/position CSS.

Now each component does positioning and sizing in its
main CSS file:

    user info, group info -- popovers.scss
    buddy list, group PMs -- right-sidebar.scss

(We also use the more explicit syntax for padding each
side.)
2019-02-18 14:22:37 -08:00
Steve Howell
1adcaad04a refactor: Simplify logic for circles.
We now have a function get_user_circle_class
that returns one of these values:

    "user_circle_green"
    "user_circle_orange"
    "user_circle_empty"

And we put that in the templates.

And then CSS renders the circle of the appropriate
color.

The unit tests now explicitly capture whether
we are rendering the correct kind of circle.
2019-02-18 14:22:37 -08:00
Steve Howell
ba91f628c7 css: Use user_circle_fraction for group PM circles.
We rename this CSS class to something super concrete,
since all the associated CSS is very specifically
about drawing circles.
2019-02-18 14:22:37 -08:00
Steve Howell
ea05afdf04 css: Avoid unused background for group PMs.
The background color for group PMs is driven
by specific styles in the HTML, so the CSS
definition here was inaccurate.
2019-02-18 14:22:37 -08:00
Steve Howell
3c8c2abd99 css: Split out user_circles.scss.
This is a pure code move.

We want to use user circles in the left sidebar,
so this code will no longer belong in
right-sidebar.scss.

This code is just related to drawing the circles.
We can still position in size in other CSS files
(with more context-specific selectors).
2019-02-18 14:22:37 -08:00
Challa Venkata Raghava Reddy
815d009006 left_sidebar: Add scrollbar for private messages region.
This fixes a longstanding UI issue when you have way too many recent
private message conversations, as you can now scroll down the list to
find what you're looking for.

Fixes #5384.
2019-02-18 14:20:55 -08:00
Vaibhav
af3b18d1f5 messagebox: Remove on-message-row-hover controls visible rules.
Date separator exists inside the message_row, which causes the
message controls to be visible even when hovering on date
separator. These two rules are redundant and cause this buggy
action. Other rules handle the behaviour of message controls
being visible on message box hover. Hence these can be removed.
2019-02-18 14:15:16 -08:00
Tim Abbott
327e31ae03 docs: Document push-to-pull-request tooling. 2019-02-18 10:40:16 -08:00
Eeshan Garg
0500639d01 api_tests: Test zulip.Client.add_reaction. 2019-02-18 10:24:13 -08:00
Steve Howell
57aabc2a24 away: Use correct user circle in user group popup.
When you click on a user group mention, you see
the list of people with green/orange/empty circles
next to them.  We now correctly reflect away status.
2019-02-17 06:43:36 -08:00
Eeshan Garg
8de84eea4c pypi_packages: Upgrade to release 0.5.9. 2019-02-17 02:57:03 -03:30
Rishi Gupta
2df08618e9 help: Ensure bottom link in sidebar is above browser URL preview.
Previously, if you scrolled down all the way in the left sidebar, and kept
your mouse hovered over a link, you had a feeling that there was still "more
stuff", since you could see the top of "Back to Zulip" peeking out over the
top of the URL Chrome (and maybe some other browsers) add in the bottom left
corner.

This just adds a bit of margin so that "Back to Zulip" is above that when
scrolled all the way down.
2019-02-16 18:19:13 -08:00
Steve Howell
03484e274a refactor: Remove dead code in PM list.
The function that was called here has no side
effects.  If you don't use its value, it's just
wasted computation.  The real action happens
in the subsequent calls to `rebuild_recent`.
2019-02-16 12:03:03 -08:00
Rishi Gupta
ea8a087fd7 user popover: Rename user profile to full profile. 2019-02-16 11:39:10 -08:00
Tim Abbott
57e1307a3a provision: Fix virtualenv-clone handling of success-stamp.
Apparently, virtualenv-clone ends up copying the success-stamp file
that we use to track whether a virtualenv was successfully
provisioned, which results in problems if we get a network error in
the pip install stage afterwards.

The comment explains our fix, but basically we just delete
success-stamp after the clone.

Fixes #11301.
2019-02-16 11:24:10 -08:00
Steve Howell
4de04c460a css: Reduce scope of topic-name selector. 2019-02-16 10:07:46 -08:00
rht
888c84c283 IRC integration: Update documentation to recommend the direct bridge.
Edited by Rishi to remove the Matrix section.
2019-02-16 09:36:36 -08:00
Rishi Gupta
b856d9c0f9 user status: Change away to unavailable. 2019-02-16 09:28:58 -08:00
Rishi Gupta
86378bd0d8 user status: Remove bolding on button click. 2019-02-16 09:28:58 -08:00
Rishi Gupta
aa8ce36b94 user status: Change text of modal button to Save.
Having it say "Clear" when you delete an existing status was a nice touch,
but it's confusing when you first open the modal and the text of the button
says "Clear".

I think the right medium-term solution here is for this modal to have "Save"
and "Cancel" buttons, and for there to be a small UI element in the user
popover itself that allows you to clear your current status.
2019-02-16 09:28:58 -08:00
Tim Abbott
4e53110350 message_list: Fix handling of deleted user groups.
You can now render message lists containing them and click on them
without throwing an exception.
2019-02-15 14:54:25 -08:00
Tim Abbott
7a49611a94 settings_invites: Display links for multi-use invitations.
This makes it possible to figure out which is which if you have
several active at the same time.
2019-02-15 14:28:07 -08:00
Vishnu Ks
763eca6ca9 invites: Add UI for revoking multiuse invites. 2019-02-15 14:13:31 -08:00
Tim Abbott
03dcace09d invite: Extract do_revoke_invite click handler as a function. 2019-02-15 14:13:02 -08:00
Vishnu Ks
ef52f541fe invites: Fix the invalid invite time bug during filtering. 2019-02-15 13:58:30 -08:00
Vishnu Ks
410e2574d1 settings: Remove unused setting ACCOUNT_ACTIVATION_DAYS.
ACCOUNT_ACTIVATION_DAYS doesn't seems to be used anywhere.
INVITATION_LINK_VALIDITY_DAYS seems to do it's job currently.

(It was only ever used in very early Zulip commits).
2019-02-15 13:56:10 -08:00
Tim Abbott
0c0aec3cc9 export: Fix finding manage.py to export usermessages.
We were using a hardcoded relative path, which doesn't work if you're
not running this from the root of the Zulip checkout.

As part of fixing this, we need to make `LOCAL_UPLOADS_DIR` an
absolute path.

Fixes #11581.
2019-02-15 11:32:36 -08:00
Steve Howell
febad410f5 fix: Use padding, not margin, for the date separator.
My very recent margin fix was tested on a slightly
stale version of master.

    see c7e03f9a71
2019-02-15 11:30:36 -08:00
Steve Howell
b1f58fb1ff emoji picker: Prevent cropping.
We now use `fix_positions` to avoid cropping the emoji
picker.  You can see cropping pretty easily on a short
screen if you click the smiley icon for reactions on a
message.  It's a bit tricky to repro, since some
of the current top/bottom placements are correct, but
it's definitely reproducible.

I think there are opportunities to both simplify
and optimize `popovers.compute_placement`, so that it
plays nicer with `fix_positions`.  For example, I would
bias it even more strongly toward favoring right/left
placement.  But there are complicating factors--it is
also used by the hotspot code.

And I wanted to especially preserve the current
behavior when you launch the picker from the compose
box.  That's one place where it looks pretty bad if
you select "right" instead of "bottom".
2019-02-15 10:40:53 -08:00
Steve Howell
a537f4a075 refactor: Clean up viewport_center hack. 2019-02-15 10:40:53 -08:00
Steve Howell
c7e03f9a71 message view: Fix margin for date separator.
Without this tweak the date separator overlaps
the left borner.
2019-02-15 09:55:15 -08:00
Tim Abbott
8779e550a4 popovers: Use fix_positions option for streams popover.
The fix_positions argument here fixes the horizontal
position of the stream popover.

It also fixes the vertical position, both in the default case, and
also doing an appropriate adjustment for the case that the color
picker is open.

This contains a few changes by tabbott to, rather than hiding the
arrow unconditionally, only do so when it would no longer point at the
right part of the screen.

Fixes #2374.
Fixes #6059.
Fixes #7290.
2019-02-14 16:58:00 -08:00
Steve Howell
19a434a289 user popover: Fix cropping/positioning.
We use the `fix_positions` options every time
we launch a user popover, whether it is from
the message pane avatar or the buddy list
chevron.

For the message pane case, we can eliminate
some complexity related to trying to put
the menu above or below the avatar.  We now
always suggest "right", and if there are
constraints due to being close to the edge
of the screen, the fix_positions code
will take care of it.
2019-02-14 16:34:29 -08:00
Steve Howell
66c6423001 popovers: Restructure hardcoded "top" for user popover.
The patch to bootstrap will make the position smarter, but we still
want to preserve the 100px default vertical offset we chose for visual
reasons.

Tweaked by tabbott to preserve the visual design.
2019-02-14 16:34:15 -08:00
Steve Howell
21ccf45db9 bootstrap: Patch popover position calculations.
For large popovers (and tooltips) we want to avoid
having the popovers go offscreen.

Fixes #11469.
2019-02-14 16:32:57 -08:00
Steve Howell
5442b38a20 popovers: Rename template to no_arrow_popover.
The `user_info_popover` template is a generic
way to make a popover without the arrow effect,
and we'll want to reuse it for other popovers.
2019-02-14 16:16:04 -08:00
Anders Kaseorg
ce01a4c5a3 backup: Add Zulip, OS, and PostgreSQL version to the tarball.
==> zulip-backup/os-version <==
    Ubuntu trusty

    ==> zulip-backup/postgres-version <==
    90324

    ==> zulip-backup/zulip-version <==
    2.0.0-rc1+git
    2.0.0-rc1-50-gbf169b8-dirty

Documentation added by tabbott.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-14 15:11:57 -08:00
Rishi Gupta
801d14280d search: Update styling and text for no search results.
Changed <h5> to <p>, and removed the special formatting of
.empty_search_text to make this more in line with the formatting we
generally use with empty narrows.
2019-02-14 15:03:14 -08:00
Greg Price
0213aa0b16 push notif: Don't forget to clear "active" flag on sending to bouncer.
Since da8f4bc0e back in August, this control flow has caused
`flags.active_mobile_push_notification` to be cleared if we don't send
these `remove` messages at all, and if we send them directly to GCM...
but not if we send them via the Zulip notification bouncer.

As a result, on a server configured to send `remove` notification-messages
via the bouncer, we accumulate "active" messages and never clear them.

If the user then does `mark_all_as_read`, we end up sending a `remove`
for each of those messages again, and all in one giant burst.  We've
seen puzzling bursts of hundreds of removals pass through the bouncer
since turning on removals on chat.zulip.org; it's likely many of them
are caused by this bug.

This issue was made more acute with f4478aad5, which unconditionally
enabled removals.

Test added by tabbott.
2019-02-14 14:52:53 -08:00
Vishnu Ks
949d098e99 management: Add tooling for transfering local uploads to s3.
This solves a common migration problem for folks who cut corners when
first setting up Zulip.

Fixes #11294.
2019-02-14 14:31:46 -08:00
Vishnu Ks
6d138bd3e5 tests: Fix broken avatar_disk_path for original size input.
string.replace returns the new string and does
not change the original string.
2019-02-14 14:18:03 -08:00
Vaibhav
fb111d017f drafts: Remove left border from draft-box.
This removes the left border extending the stream label from the
recipient bar in from the drafts in drafts modal.  Those borders are
important in the message feed for containing several messages, but
here we're only ever going to show individual drafts, and this change
avoids potential color clashes with the blue box surrounding the
recipient blocks.
2019-02-14 11:33:08 -08:00
Vaibhav
2ca8ec371e drafts: Change foreground for dark background streams in drafts modal.
In drafts modal, dark background streams still had black foreground;
This changes the foreground to white for the same.
2019-02-14 11:32:11 -08:00
Vaibhav
162f06bbbb drafts: Add blue border around the active draft.
This removes the change in background to a darker one for active draft,
also removes the change in recipient_row_date color to blue; adds a blue
border around the draft box.
2019-02-14 11:32:11 -08:00
Harshit Bansal
d386706382 emoji: Fix traceback on opening emoji popover in quick succession.
Since the bootstrap popovers are destroyed asynchronously so opening a
emoji popover in quick succession like by clicking the reaction button
on another message was causing a race condition which was causing some
operations to be applied on a destroyed emoji popover.  This commit
fixes it by making sure to apply any operations only to the currently
active popover.

Fixes: #9851.
2019-02-14 11:29:25 -08:00
Rishi Gupta
403ae625cd help: Make minor edits and style updates to the Sending Messages section. 2019-02-13 18:03:22 -08:00
Rishi Gupta
559071877e help: Update edit-or-delete-a-message. 2019-02-13 18:03:22 -08:00
Rishi Gupta
20d692bbd6 help: Remove compose-and-reply.
This page was too messy and hard to parse. Parent commits already copied
most of the content out into other articles.
2019-02-13 18:03:22 -08:00
Rishi Gupta
a2130ca106 help: Separate quote-and-reply into its own article. 2019-02-13 18:03:22 -08:00
Rishi Gupta
2454eff51d help: Rename and update at-mention-a-team-member. 2019-02-13 18:03:22 -08:00
Rishi Gupta
4e33c3a970 help: Make open-the-compose-box a separate article. 2019-02-13 18:03:22 -08:00
Rishi Gupta
64cdac9294 help: Remove zulip-glossary.
I'm torn about this, since there is good content here. But ultimately I think
* This page is a lot of work to write and maintain.
* In most cases, the right thing is for people to find the page that
  explains the full feature. E.g. if you don't know what an "administrator"
  is, the page I hope you find is "Roles and Permissions". For bots, it's
  "Bots and Integrations". Writing a punchy short summary for a glossary
  that does better than that is possible, but not fast.
* People find things via search, e.g. by Googling "What is X in Zulip",
  rather than looking for a glossary.
* This page was written more than 3 years ago, before we had 100+ help
  articles. So it may have served a purpose in the past that no longer
  exists.
2019-02-13 18:03:22 -08:00
Rishi Gupta
e40af1ca7f help: Update title of change-your-language. 2019-02-13 17:50:39 -08:00
Rishi Gupta
e183c316dd help: Rename help/change-your-avatar to help/set-your-avatar. 2019-02-13 17:50:39 -08:00
Rishi Gupta
f25cc5a580 help: Update starred messages to include starred messages counts.
This is not yet live in production, but clearing out the TODO list while I'm
looking at these docs.
2019-02-13 17:50:39 -08:00
Tim Abbott
d44b8981e2 docs: Update changelog with most changes for 2.0 release. 2019-02-13 16:54:57 -08:00
Vaibhav
5796d9d623 drafts: Change width of the drafts modal to 58%. 2019-02-13 16:16:34 -08:00
Vaibhav
d710be866f drafts: Change spacing of drafts in modal.
Increase spacing (horizontal padding) of drafts.
Also add spacing between pro-tip and hr.
2019-02-13 16:16:34 -08:00
Vaibhav
72bd3d22e8 drafts: Add helper functions to get focused draft rows.
Adds three helper functions - `row_with_focus`, `row_before_focus` and
`row_after_focus` to get the focused, previous and next to focused
draft rows respectively.
2019-02-13 16:16:34 -08:00
Vaibhav
e0134111d5 drafts: Rename delete_id to draft_to_be_focused_id.
`delete_id` in `drafts.js` referred to the next draft row which was
to be focused when deleting using hot keys. The var name was absurd
and is hence renamed.
2019-02-13 16:16:34 -08:00
Vaibhav
69424e4f2f drafts: Refactor code used to remove drafts.
Adds a `remove_draft` function which deletes the draft and updates the ui
by removing it from the list of drafts.
Also adds comments to increase readability.
2019-02-13 16:16:34 -08:00
Steve Howell
8a4aa0e49a drafts: Add reminder of hotkey. 2019-02-13 16:16:34 -08:00
Steve Howell
0f21020783 drafts: Put 30-day notice in header (to prevent scroll). 2019-02-13 16:16:34 -08:00
Steve Howell
c4cd0fe0c1 drafts: Use a reverse-cron sort.
I think it's natural for your eyes get drawn to
the top of the modal, so that's where we should
put the most recent draft.
2019-02-13 16:16:34 -08:00
Abdelhadi Dyouri
4ac2db56f8 export: Correctly treat emoji author field as optional.
While we likely will eventually want to make every custom emoji have
an author, that's not the data model today.

Fixes #11518.
2019-02-13 16:12:06 -08:00
Tim Abbott
4d1fb5270d message view: Fix asymmetric padding on date separators. 2019-02-13 16:03:33 -08:00
Anders Kaseorg
89897bcf70 css: Move inline date separators from messagebox to message_row.
Fixes border-related glitches introduced by commit
51c6c82003 (#10820).  Alternative
to #11534.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-13 16:03:21 -08:00
Anders Kaseorg
dae6aa21d8 css: Remove dead CSS classes message_data, prev_is_same_sender.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-13 16:03:16 -08:00
Mohit Gupta
bf14f4cd7b notification: Show wrong narrow notification for non locally echoed message.
Show "sent to different narrow" notification and other such notification by
notifications.notify_local_mixes for non locally echoed message sent by
current client.

With significant new comments added by tabbott.

Fixes: #11488.
2019-02-13 15:51:41 -08:00
Mohit Gupta
e5f28ca78e refactor: Rename locally_echoed to sent_by_this_client.
This is a bit clearer, since we will soon want to pass this option for
messages that could not be locally echoed due to markdown rendering.
2019-02-13 15:30:57 -08:00
Tim Abbott
944d590298 settings: Offer starred messages count setting publicly.
Previously, this was only available in the Zulip development
environment.

Further work is needed on documenting this and how to use it for
managing work to follow up on.
2019-02-13 15:11:17 -08:00
Pragati Agrawal
48175ce1f7 subs: Update Default streams data while renaming streams.
If a stream is a default stream, this updates its name at `Default Streams`
section of `Organization settings` page.

Fixes: #11466
2019-02-13 15:05:25 -08:00
Tim Abbott
a0add8f651 puppet: Add IPv6 support to standard nginx listen directives.
This should save some setup work for anyone wanting to setup nginx on
their Zulip server.
2019-02-13 15:00:21 -08:00
Tim Abbott
c41bfcb9e0 Revert "activity: Change definition of active site."
This reverts commit 9f9b7cb991.

This commit made the page not perform well enough to load.
2019-02-13 14:52:13 -08:00
Greg Price
630481cb7a push notif: Switch from GCM to FCM endpoint.
This is the only server-side change required for the FCM migration!

Optionally, at some point in the future we might choose to migrate
to the new ("v1") API which FCM also offers.  Nothing revolutionary
but there are some nice things about it:
  https://firebase.google.com/docs/cloud-messaging/migrate-v1
2019-02-13 13:57:57 -08:00
Greg Price
84e0b68b16 push notif: Rename gcm to less confusing gcm_client.
This opens up space in the namespace for, say, the library
module itself.
2019-02-13 13:57:57 -08:00
YashRE42
93b6fa6036 search: Display stop words from query when no results.
This displays to the user clearly which words we ignored in their
search query due to being stop words.

Fixes #10592.
2019-02-13 13:23:48 -08:00
Tim Abbott
7099d01641 email mirror: Fix missing variable for logging. 2019-02-13 13:16:55 -08:00
Greg Price
f4478aad54 push notif: Unconditionally remove notifications on message read.
The client-side fix to make these not a problem was in release
16.2.96, of 2018-08-22.  We've been sending them from the
development community server chat.zulip.org since 2018-11-29.
We started forcing clients to upgrade with commit fb7bfbe9a,
deployed 2018-12-05 to zulipchat.com.

(The mobile app unconditionally makes a request to a route on
zulipchat.com to check for this kind of forced upgrade, so that
applies to mobile users of any Zulip server.)

So at this point it's long past safe for us to unconditionally
send these.  Hardwire the old `SEND_REMOVE_PUSH_NOTIFICATIONS`
setting to True, and simplify it out.
2019-02-13 13:13:45 -08:00
ss62171
a12c2921d7 email-log: Handle checkbox saying "Show text only version".
After clicking on checkbox saying "Show text only version" UI was rendered
correctly but after refreshing page keeping checkbox checked, emails were
shown without "text only version" but checkbox value remained checked.

Now after refreshing page checkbox value changes to its default value.
2019-02-13 11:44:09 -08:00
Tim Abbott
ab18dbfde5 uwsgi: Increase buffer-size to 8192.
For users putting Zulip behind certain proxies (and potentially some
third-party API clients), buffer sizes can exceed the uwsgi default of
4096.  Since we aren't doing such high-throughput APIs that a small
buffer size is valuable, we should just raise this for everyone.
2019-02-13 11:17:55 -08:00
savish
1b334b906a tests: Use subTest in test_admin_user_can_change_profile_data.
Fixes #11070.
2019-02-13 10:50:39 -08:00
savish
aa605468b6 tests: Use subTest in test_update_realm_properties. 2019-02-13 10:49:13 -08:00
savish
9c292fbeab tests: Use subTest in test_bugdown_fixtures. 2019-02-13 10:49:13 -08:00
Puneeth Chaganti
43caf28e36 digest: Use the same font for the salutation as other paragraphs.
The fact that these were different was just a subtle visual bug.
2019-02-13 10:43:26 -08:00
Puneeth Chaganti
29925fd303 digest: Fix width of digest-email-container.
The width of the messages div is set to 600px, while the
digest-email-container can be 500px at the most. Increasing the width
of the digest-email-container makes the /digest slightly more
readable.
2019-02-13 10:43:21 -08:00
Rishi Gupta
0dfb18fb3b help: Document wide organization logo. 2019-02-13 10:41:29 -08:00
Rishi Gupta
750fff16ef help: Remove TODOs from sidebar_index.md. 2019-02-13 10:41:29 -08:00
Rishi Gupta
e3496830f1 help: Add hide-message-content-in-emails. 2019-02-13 10:41:29 -08:00
Rishi Gupta
7e0e380b5a help: Add change-notification-sound. 2019-02-13 10:41:29 -08:00
Rishi Gupta
458f988262 help: Add configure-missed-message-emails. 2019-02-13 10:41:29 -08:00
Rishi Gupta
d20be1dd66 help: Add disable-new-login-emails. 2019-02-13 10:41:29 -08:00
Rishi Gupta
db3690bffe help: Update emoji-and-emoticons to document changing emoji set. 2019-02-13 10:41:29 -08:00
Rishi Gupta
3b9cb9c68c help: Add change-your-timezone. 2019-02-13 10:41:29 -08:00
Rishi Gupta
378d14af7e import: Fix tests related to plan_type.
Broken in 4d08461.
2019-02-12 18:11:31 -08:00
Tim Abbott
12d5e870c5 tests: Fix import test failure.
Broken in 4d08461ab1.
2019-02-12 17:46:55 -08:00
bartek
9f9b7cb991 activity: Change definition of active site.
Signed-off-by: bartek <bartek.jachowicz@gmail.com>

Edits by Rishi Gupta <rishig@zulipchat.com>

Fixes: #10432
2019-02-12 16:36:44 -08:00
Rishi Gupta
68d73f2e12 left sidebar: Remove border from starred messages count.
The padding changes move the number a bit to the right and down, towards
where the bottom right corner of an unread count box would have been. This
makes the number look better aligned with the unread count boxes above it.
2019-02-12 16:05:35 -08:00
Tim Abbott
4d08461ab1 import: Set plan_type to SELF_HOSTED on import.
We've for a while had logic to set plan_type to LIMITED when importing
into Zulip Cloud; we need corresponding logic to set it to SELF_HOSTED
when importing into a self-hosted server.

Fixes #11541.
2019-02-12 16:01:02 -08:00
Thomas Ip
60c9f22129 typescript: Update TS related dependencies. 2019-02-12 15:59:51 -08:00
Rohitt Vashishtha
15e29e209c markdown: Handle SyntaxError in python_to_js_filter.
We swallow the error if our python_to_js_filter code is
unable to parse some python regex properly. This ensures
that the web app stays responsive.

We would fail to show an accurate local echo for these
regexes, however, the backend would act as the final
authority for handling the realm pattern conversion.
2019-02-12 15:58:09 -08:00
Natsu Kagami
d936fcab3b markdown: Handle multiple python regex capture groups properly.
Since on replacing the first 'P<>' group, we remove this text from
the string, we have to make the RegExp start looking from index 0
again to properly convert later 'P<>' groups to JS regex syntax.
2019-02-12 15:54:28 -08:00
Vishnu Ks
868a763cec auth2: Don't use session for passing multiuse invite key.
For Google auth, the multiuse invite key should be stored in the
csrf_state sent to google along with other values like is_signup,
mobile_flow_otp.

For social auth, the multiuse invite key should be passed as params to
the social-auth backend. The passing of the key is handled by
social_auth pipeline and made available to us when the auth is
completed.
2019-02-12 15:51:11 -08:00
Eeshan Garg
179b747769 streams: Refactor multi-option helpers into separate functions.
For internal stream messages, most of the time, we have access to
a Stream object. For the few corner cases where we don't, it is a
much cleaner approach to have a separate function that accepts a
stream name than having one multi-option helper that accepts both
names and objects.
2019-02-12 11:10:26 -08:00
Steve Howell
c7a9faa803 right sidebar: Move invite link below Group PMs.
It looked kinda terrible in between the two
user lists.

There is some discussion here (I have to break the
link into two lines to make gitlint happy):

https://chat.zulip.org/#narrow/stream/
    101-design/topic/user.20sidebar.20in.20left/near/697682
2019-02-12 10:36:45 -08:00
Abhigyan Khaund
1ef34ccb98 docs: Typo fix in changelog for 2.0.0-rc1. 2019-02-12 10:29:13 -08:00
Steve Howell
96cbea3c11 bug fix: Move stream search out of scroll container.
We want the search widget, when visible, to be
outside the scroll container for the stream list.

One obvious use case is if you start scrolling, and
then realize it might be less effort to search.

Also, for user search, it already worked this way.

We have to add a couple resizing hooks here, but
it's not necessary to change the actual resize
calculation, since we move the section inside
of #streams_header, which is already accounted
for.

The only markup change here is to add
a `stream_search_section` class.  I don't
know why we use `notdisplayed` here instead of
jQuery, or what `input-append` is for, but I
considered them outside the scope of this change.

We can also remove some crufty CSS that was
compensating for it being inside the container.
2019-02-12 10:26:13 -08:00
Steve Howell
6fc45fd941 left sidebar: Disable "gray-out" feature for new users.
If a user has 30 subscribed streams or less, don't gray
them out if they haven't had recent activity.
2019-02-12 17:43:48 +00:00
Eeshan Garg
1d718adce4 zerver/views: Rename integrations.py to documentation.py.
The name "integrations" is misleading because we now also use
this module for our REST API docs.
2019-02-11 21:25:14 -08:00
Eeshan Garg
b0c761dfb1 zapier_app: Include bot details in response to auth requests.
The bot's details (such as ID and name) are used to format a
connection label in Zapier's UI. This allows users to distinguish
between different Zapier-to-Zulip connections set up with different
bots.
2019-02-11 21:24:52 -08:00
Tim Abbott
d6140b684f notifications: Don't send error emails on bouncer 500s.
Since the individual server administrator can't do anything about
these, this should not trigger an email notification.
2019-02-11 21:19:28 -08:00
Tim Abbott
23f950c60c version: Bump ZULIP_VERSION after 2.0.0-rc1 release. 2019-02-11 20:25:00 -08:00
Tim Abbott
edb50cbf2c Release Zulip Server 2.0.0-rc1. 2019-02-11 20:07:38 -08:00
Steve Howell
3a12b514f1 css: Remove Group PMs from **left** sidebar.
First, we are not removing Group PMs from the
right sidebar, where most people see it.

There is a setting called:

    [ ] User list in left sidebar in narrow windows

There are probably very few people that turn that on,
and even when they do, the setting only takes effect
when your window is less than a certain width.

This feature bitrots very quickly, because very few
core maintainers use it.

It's already kind of broken.  It gets very crowded,
and we get CSS bugs when we move the right sidebar
into the left sidebar.  (We can fix those bugs, but
they crop up unexpectedly due to the nature of CSS.)

We historically tried to maintain a ratio between
stream list, single-user buddy list, and group-user
buddy list, but the group-user buddy list gets
particularly crowded out, and it's basically useless
now.

We want to revisit the entire feature eventually, but
this commit at least gives the normal buddy list some
breathing room.

Also, if you need to see the info in the group PM
list, you can basically expand "Private Messages" to
see your recent group PM conversations.  And if you
want to see who's actually online, that info is
already implicit from the normal buddy list.
2019-02-11 19:17:52 -08:00
Steve Howell
dc96b96359 minor: Group main-div related code together. 2019-02-11 19:14:46 -08:00
Steve Howell
cd3aa46f34 left sidebar: Restore 15px in "split" mode.
If users have the option to put user lists in
the left sidebar for narrow windows, they will
now get 15px more of real estate in the left
sidebar.

I just removed the `-15` fudge factor.
2019-02-11 19:14:46 -08:00
Steve Howell
d8f1b2e0bd right sidebar: Reclaim 8px of real estate.
We were double-counting the keyboard icon's
margin (8px) when figuring out how much room
we had for the two users lists.

Now we just use the safe outer height of
the anchor tag.
2019-02-11 19:12:51 -08:00
Steve Howell
5d8664d725 refactor: Add an explicit user_search_section.
This, among other things, makes it easier to
troubleshoot the resize code.
2019-02-11 19:12:51 -08:00
Steve Howell
a921e7e894 minor: Remove unused intermediate variable.
Calculating everything relative to `viewport_height`
is easier to audit.
2019-02-11 19:12:51 -08:00
Tim Abbott
e1832d890a css: Move conversation-partners styles to left-sidebar.css. 2019-02-11 19:12:20 -08:00
Steve Howell
b10ef272f1 css: Simplify selector for conversation partners. 2019-02-11 17:47:54 -08:00
Steve Howell
fd76b1b226 css: Limit scope of filter-icon css. 2019-02-11 17:47:54 -08:00
Steve Howell
5db26cb7fe css: Remove sidebar-title cruft.
This CSS seems to go back to when sidebar-titles
were links.  It's scoped at the wrong level, and
it seems to have no effect.
2019-02-11 17:47:54 -08:00
Steve Howell
350ed9fcaf css: Limit li padding/border to narrows_panel. 2019-02-11 17:47:54 -08:00
Steve Howell
bd3b715cf2 css: Set hover only on narrows_panels. 2019-02-11 17:47:53 -08:00
Steve Howell
51925b03b7 css: Set margin for only narrow_panels.
We don't want this margin to affect every
single thing that goes in the left sidebar.
2019-02-11 17:43:54 -08:00
Steve Howell
c4ac7f5b03 left sidebar: Clean up "split" list moves.
This change only impacts users who have the setting
to put the user lists in the left sidebar when they
have a narrow window.

First, we move ".right-sidebar-items" as an entire
group.

Second, we append the items to "#left-sidebar"
instead of ".narrows_panel".
2019-02-11 17:43:54 -08:00
Steve Howell
039daa2bfa refactor: Rename bottom_sidebar to narrows_panel.
The name `bottom_sidebar` was misleading, because it
includes the entire "normal" left sidebar.

It includes the 4 narrow links at the top plus the
stream/topic list.

We now call is narrows_panel.

Note that the left sidebar sometimes also includes
the user list (with a display setting turned on).

And it will eventually include other views.

We also remove an intermediate value in the resize
calculations.
2019-02-11 17:43:54 -08:00
Anders Kaseorg
e0a51948d9 script: Add ready-to-run tooling for doing backups.
Based on an initial version by Tim Abbott (#11204).

Fixes #552.
2019-02-11 17:30:37 -08:00
Anders Kaseorg
ebad0b7cbf zulip_tools: Get the zulip uid from the owner of DEPLOY_ROOT.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-11 17:00:37 -08:00
Tim Abbott
523e651a10 i18n: Update translations data from Transifex. 2019-02-11 16:52:41 -08:00
Tim Abbott
40916803e7 floating_recipient_bar: Fix incorrect use of jQuery .next().
The semantic of jQuery's .next(selector) return nothing if the
selector doesn't match the next child.
2019-02-11 16:46:11 -08:00
Rishi Gupta
5bd2c70c3c invite: Move success message to top of invite modal. 2019-02-11 16:17:13 -08:00
Rishi Gupta
c61bccb671 invite: Remove spurious <hr> from invite modal.
I suspect this made sense in a previous design, but doesn't really make
sense now.
2019-02-11 16:17:13 -08:00
Rishi Gupta
735ba2ce56 invite: Remove unused div in invite modal. 2019-02-11 16:17:13 -08:00
Tim Abbott
cbc2f495ff css: Fix night mode styling for mentions.
This was missed in developing
51c6c82003.
2019-02-11 16:11:47 -08:00
Tim Abbott
e3bc788660 docs: Announce deprecation of Ubuntu Trusty. 2019-02-11 16:10:12 -08:00
Tim Abbott
51c6c82003 message_list: Don't split message groups for a date divider.
This adds date dividers within a single message group when the only
reason we had previously been splitting apart two message groups is a
change of date.  The overall effect is a cleaner message list user
experience.

The downside of this change would be that the recipient bars no longer
will always show a new date for date changes; to fix that, we rewrite
how the floating recipient bars both set the date field on the
floating recipient bar itself, as well as ensure that non-floating
recipient bars don't show duplicate dates.

In a future design update where we modify how message recipient bars
look, we may very well be able to simplify this logic by removing some
of the dynamic nature of the recipient bar calculations.  But this is
a good implementation of what remains.

Tweaked significantly by tabbott from Steve Howell's original, both to
extract these changes from a larger PR as well as to modify the
first_visible_message logic to handle some tricky corner cases.

Fixes #10171.
2019-02-11 15:56:09 -08:00
xiaomingplus
5120d97633 docs: Remove confusing comment from boto example.
The boto config file format should have comments on a separate line.

here is the docs:

http://boto.cloudhackers.com/en/latest/boto_config_tut.html#details
2019-02-11 15:01:18 -08:00
Hemanth V. Alluri
77f24e2b56 click_handlers: Use stream desc. on edit instead of rendered desc.
On clicking the edit button for a stream description, the stream's
unrendered description should be made editable as text instead of
the stream's rendered description (which would be displayed as HTML
instead of text).

This completes the effort to use backend-rendered stream descriptions
here.  Fixes #11272.
2019-02-11 12:27:11 -08:00
Hemanth V. Alluri
683ec852fd stream_data: Use stream rendered_description provided by the backend.
Use the results of commit #73d26c8 to remove the method
`render_stream_description` in static/js/stream_data.js and instead
use the rendered_description attribute now being sent by the backend.

This will be a valuable optimization and a step towards removing the
need for the marked.js markdown parser and speeding up the client end.
2019-02-11 12:24:27 -08:00
Rishi Gupta
028874bab3 open graph: Remove extraneous spaces from descriptions.
Our html collects extra spaces in a couple of places. The most prominent is
paragraphs that look like the following in the .md file:
* some text
  continued

The html will have two spaces before "continued".
2019-02-11 12:05:19 -08:00
Rishi Gupta
0119b383a6 help: Update Accounts basics section to conform to new tabbed style. 2019-02-11 12:05:19 -08:00
Rishi Gupta
d3125f59e1 open graph: Omit .code-section navigation from open graph. 2019-02-11 12:05:19 -08:00
Rishi Gupta
e1f02dc6f2 open graph: Include multiple paragraphs in description tags. 2019-02-11 12:05:19 -08:00
Rishi Gupta
cd0e55cb95 help: Add streams and topics and moderation to Guides. 2019-02-11 12:05:19 -08:00
Rishi Gupta
dda6f1e123 portico: Fix heading tag on /hello. 2019-02-11 12:05:19 -08:00
Rishi Gupta
c26e2ab178 help: Adjust CSS for headings.
This looks like it affects why-page as well, but in practice all those pages
seem to have CSS that overrides these values.
2019-02-11 12:05:19 -08:00
Rishi Gupta
0958345416 help: Remove styling from spurious <p></p> tags. 2019-02-11 12:05:19 -08:00
Rishi Gupta
83236dc283 help: Add tab styling to untabbed instructions as well.
This changes the border-radius to 6px for the tabbed display, which is not
in line with the current Zulip style for border-radius (4px). However 6px
really looks a lot better for this (possibly because it's a bigger box than
most of our other boxes?)
2019-02-11 12:05:19 -08:00
Rishi Gupta
d6c80d1ce7 help: Restyle tabbed navigation boxes. 2019-02-11 12:05:19 -08:00
Rishi Gupta
e046e6e228 help: Add CSS class to distinguish /api/* from /help/*. 2019-02-11 12:05:19 -08:00
Tim Abbott
a46640b325 docs: Document restricting access to an LDAP group. 2019-02-11 11:40:57 -08:00
anhhuynh
bd548eb7f3 emails: Remove newlines from translated strings in email templates.
Fixes #11390.
2019-02-10 12:28:17 -08:00
Amadeo234
7d42d7b4db message_edit: Fix message edit history breakdown on large messages.
The message_edit_history UI was incorrectly inheriting its content
div's structure from message_edit_content, i.e. the form for editing
message content, and not message_content, i.e. the class for rendering
the content of messages in the message feed (which we also use for
drafts).

Fix this by changing the inheritance, while also adding a (currently
unused) class for any future customizations.

Fixes: #5629.
2019-02-08 15:47:17 -08:00
Pragati Agrawal
3a374f5e68 typeahead: Add typeahead for silent mentions.
This adds typeaheads of the form _@ , _@* , _@** for silent mentions.

Fixes: #11426.
2019-02-08 15:40:01 -08:00
Pragati Agrawal
d5a327f122 typeahead: Extract functions in composebox_typeahead.
This extract functions `get_mention_candidates_data` &
`filter_mention_name` to make code reusable and cleaner and further use
the logic in silent mention syntax.
2019-02-08 15:40:01 -08:00
Steve Howell
3649293d71 left sidebar: Add a bit of margin below stream list.
Having a tiny bit of margin below the stream list
makes it possible to see the bottom of the scrollbar.

It also makes it so that the scrollbar activates
for a tiny range of list sizes where before the
last element would have been right up against the
bottom of the page, but we wouldn't scroll.
2019-02-08 15:27:50 -08:00
Greg Price
a6c2c16666 push notif tests: Clean up how we set up device token fixtures.
I was hoping this would make things faster... it does, but sadly only
by about 70ms, 5% of this file's test runtime.

It sure does make this file rather less action-at-a-distance, though,
as well as fixing some duplication.
2019-02-08 15:18:12 -08:00
Greg Price
ccc1f3cd85 push notif tests: Stop importing module as bizarre name apn. 2019-02-08 15:18:12 -08:00
Greg Price
c372ceb7a2 push notif tests: Use mock.patch instead of apn.gcm = .... 2019-02-08 15:18:12 -08:00
Greg Price
e289c5835d push notif tests: Use mock.patch instead of apn.gcm = None.
This is what it's for -- and it cleans up after itself, too.
2019-02-08 15:18:12 -08:00
Greg Price
ff12072f18 push notif: Skip four layers of setup for some pure unit tests.
This saves about 50ms, for just four test cases.
2019-02-08 15:18:12 -08:00
Greg Price
1e11e929ec push notif: Guess a GCM priority on behalf of old servers. 2019-02-08 15:18:12 -08:00
Greg Price
a293aeee23 push notif: Explicitly set GCM priority normal for remove.
If we make a practice on the Zulip server of always explicitly setting
the desired priority, then when an old server doesn't set the priority
we can reasonably have the bouncer make a guess.
2019-02-08 15:18:12 -08:00
Greg Price
ffabebd7f3 push notif: Set GCM priority high for real notifications.
This is the payoff of this branch!  Fixes zulip/zulip-mobile#3185.
2019-02-08 15:18:12 -08:00
Greg Price
699bf262ca push notif: Test GCM options parsing more comprehensively.
The payoff from making these into real unit tests.
2019-02-08 15:18:12 -08:00
Greg Price
02ba302009 push notif: Simplify tests for parsing GCM options.
Huzzah for unit tests!
2019-02-08 15:18:12 -08:00
Greg Price
f1cb9be79c push notif: Consolidate and simplify GCM tests. 2019-02-08 15:18:12 -08:00
Tim Abbott
925bf7b907 message_list: Move update_group_date_divider earlier.
We need to move the update_group_date_divider call to run when a
message group is created.  This achieves a few things:

* Fixes calling this multiple times useless for long message groups.
* It will soon no longer be correct to assume that every message
within a group has the same date, and in that case, we want to process
the date of the first message in the group, not of the last.
2019-02-08 14:54:40 -08:00
Tim Abbott
31e98b8b65 message_list: Remove extra calls to update_timestr.
We only generate message_containers in one place, and that code path
already calls update_timestr.  And update_timestr's effect only
depends on the message.  Thus, this code was useless.
2019-02-08 14:51:03 -08:00
Tim Abbott
7fd582025f message_list: Extract render_group_display_date. 2019-02-08 11:45:21 -08:00
Tim Abbott
0aa438e199 message_list: Rename update_group_time_display.
The name now reflects that this is about date dividers.
2019-02-08 11:30:58 -08:00
Tim Abbott
21a86f3ef7 message_list: Rename show_date_separator to show_group_date_divider. 2019-02-08 11:30:15 -08:00
Tim Abbott
0d66d3fafd message_list: Rename show_date to group_date_divider_html.
This is much more clear about what this actually means.
2019-02-08 11:26:24 -08:00
Tim Abbott
72bb3fb6c2 message_list: Extract clear_date_divider_html.
This also fixes the fact that the logic had swapped which object
should be undefined and which should be false.
2019-02-08 11:20:00 -08:00
Rishi Gupta
fe28d0731e org settings: Move "allow message content in email" to different subsection. 2019-02-08 10:16:09 -08:00
Rishi Gupta
3a26daf911 org settings: Remove unnecessary titles from Organization settings. 2019-02-08 10:16:09 -08:00
Rishi Gupta
65f6bea7d7 org settings: Move video chat provider into other settings. 2019-02-08 10:16:09 -08:00
Rishi Gupta
16042ba15d org settings: Reorder the major sections of Organization settings. 2019-02-08 10:16:09 -08:00
Rishi Gupta
76488bd2fe settings: Remove button styling from role. 2019-02-08 10:16:09 -08:00
Anders Kaseorg
dec8c7dba4 provision: Run generate_secrets earlier.
Commit 7d12e2019d (#10994) broke fresh
provisions by importing zproject.settings before we were done
modifying settings.  Fix it by moving the generate_secrets invocation
to the earliest reasonable place.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-08 10:13:18 -08:00
Tim Abbott
a2373a63cd capitalization: Add GCM to list of proper nouns.
This fixes failures in master from the recent GCM merge.
2019-02-08 10:11:55 -08:00
Greg Price
6da9aeee7d push notif: Expand and clarify docs on GCM options. 2019-02-08 09:44:00 -08:00
Greg Price
674b254b65 push notif: Accept GCM priority option.
That is, this allows a Zulip server to now set the `priority`; but if
it doesn't, we use upstream's default value, which has the same effect
as we've always previously had by not setting it at all.

But when this is deployed to the push notifications bouncer server, it
does allow another server to set priority when pushing notifications
through the bouncer.
2019-02-08 09:42:59 -08:00
Greg Price
575f320009 push notif: Factor out a helper parse_gcm_options.
Looks a bit silly as is, but this will give us a good home for
logic to start parsing more than zero allowed options.
2019-02-08 09:41:07 -08:00
Greg Price
9ebad5d505 push notif: Reorg send_android_... slightly for clarity.
In particular, get the `remote`/`DeviceTokenClass` bit out from
in between `json_request` and the various bits of code preparing
for it.
2019-02-08 09:40:45 -08:00
Greg Price
49fd2e65de push notif: Add GCM options to bouncer API; empty for now.
The first use case for this will be setting `priority`,
coming up shortly.
2019-02-08 09:40:43 -08:00
Eeshan Garg
3470e541c8 internal_send_stream_message: Support accepting a Stream object.
If the caller has access to a Stream object, it is wasteful to
query a database for a stream by ID or name. In addition, not
having to go through stream names eliminates various classes of
possible bugs involved with re-fetching the Stream object by name.
2019-02-08 08:59:03 -08:00
Eeshan Garg
c240008edb internal_prep_stream_message: Support accepting a Stream object.
If the caller has access to a Stream object, it is wasteful to
query a database for a stream by ID or name. In addition, not
having to go through stream names eliminates various classes of
possible bugs involved with getting a Stream object back.
2019-02-08 08:53:16 -08:00
Abhinav Singh
849c296f90 popovers: Fix 'w' hotkey in narrow windows.
In small screen sizes, when the user presses shortcut `w` to search
for another user, the hide_all function calls in the search code path
would hide the right sidebar, immediately after opening it, making the
hotkey basically unusable.

We fix this by extracting a separate hide method that hides all true
popovers, but not the user list sidebar.

Fixes #11463.
2019-02-08 08:42:34 -08:00
Puneeth Chaganti
b6cf14608d upload: Ensure correct textarea is focused when an upload finishes.
The `uploadFinished` code switches on the composing mode, if we aren't
in the composing mode already. This causes the focus to be incorrect
when this code path runs due to an upload from the message edit
box. This commit fixes that logic to turn on the composing mode or
switches focus to the message edit box, depending on where the upload
was triggered.
2019-02-08 07:45:41 -08:00
Steve Howell
d7f9a21519 api docs: Move json-api-example css to portico.scss.
We didn't need to patch the third-party bootstrap code for this.
2019-02-08 07:42:32 -08:00
Anders Kaseorg
e4832cc9da setup_path_on_import: Don’t re-add BASE_DIR to sys.path.
BASE_DIR must already be in sys.path if we got as far as importing
this.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-07 17:17:31 -08:00
Anders Kaseorg
8fdb62a6bc tools: Create DEPLOY_ROOT/zulip-py3-venv symlink in development too.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-07 17:12:33 -08:00
Anders Kaseorg
70bfcd3402 zulip_tools: Extract get_deploy_root function.
Modified by tabbott from the original to preserve the implementation;
see https://github.com/zulip/zulip/pull/11295#discussion_r254925032
for why this is correct.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-07 17:09:29 -08:00
Tim Abbott
4826393ec4 hipchat: Fix help documentation for slim_mode. 2019-02-07 16:17:01 -08:00
Vishnu Ks
0ed6dab806 invites: Show multiuse invite button only to admins. 2019-02-07 15:41:00 -08:00
Vishnu Ks
6ed6bcef05 invites: Move multiuse invite status to footer. 2019-02-07 15:41:00 -08:00
Vishnu Ks
b62bd83083 invites: Add generate multiuse invite button. 2019-02-07 15:41:00 -08:00
Vishnu Ks
28769e040f invites: Add backend for multiuse admin invites. 2019-02-07 15:41:00 -08:00
Steve Howell
0e65e74566 refactor: Make build_topic_popover() not rely on HTML.
Now all the markup-specific finding of elements just
happens in the click handler.
2019-02-07 15:19:55 -08:00
Steve Howell
b5347c78b2 scrolling: Fix sidebar size calculation.
So the top navbar is above the left sidebar
on the z-axis, not the y-axis.

So it doesn't make sense to use the top
navbar in calculating the size of the left
sidebar.

It kind of coincidentally works, since these
two numbers are closely related:

    left sidebar top margin = 50
    navbar height = 40

Calculating `bottom_sidebar_height` correctly
decreases its value by 10.

And then the only value that depends on it
is `stream_filters_max_height`.  We were
subtracting out 10 there to make it work,
since `bottom_sidebar_height` was inaccurate
by +10.  Now that's fixed.

The comment there was inaccurate--the
`stream_filter` div actually has a bottom
margin of 22px.  The bottom margin does
have some consequences for scrolling,
but the main goal here is to make the
calculation return the same value but
be more accurate about what happens
toward the top of the screen.
2019-02-07 15:19:55 -08:00
Steve Howell
e7ead7383d css: Add explicit padding below the navbar.
We have always intended to have 10px of whitespace
below the navbar, and this enforces it directly
and explicitly in the CSS.

Note that the three major panels still should
have a margin of 50px, which is equal to
the safe outer height of the header (40px + 10px).
2019-02-07 22:36:08 +00:00
Eeshan Garg
4da28970fa addressee: Rename for_stream to for_stream_name.
The name for_stream_name is more appropriate here.  The name
for_stream is more suitable for a function that takes in a Stream
object, which we're about to add.
2019-02-07 13:41:24 -08:00
Tim Abbott
970c7d1ddf notifications: Fix hash-named duplicate sound files in options.
Our hash-naming of production assets interacted badly with the "look
at files in a directory" algorithm used to determine what sound
options exist for the "notification sound" feature.  For lack of a
better solution, we fix this by excluding files with an extra `.` in
their name.
2019-02-07 13:36:41 -08:00
Rishi Gupta
0f3125582b org settings: Reposition instructions for user groups, and hide from guests. 2019-02-07 11:46:09 -08:00
Rishi Gupta
9f2995a6f6 org settings: Reorder options under org permissions -> other permissions. 2019-02-07 11:46:09 -08:00
Rishi Gupta
9572c5ddb0 org settings: Update explanation for Default user settings. 2019-02-07 11:46:09 -08:00
Rishi Gupta
abe67a3000 org settings: Reorder options in org settings -> message edit. 2019-02-07 11:46:09 -08:00
butchyyyy
c1a47012fd jenkins: Update integration for new plugin release.
Fixes #11425.
2019-02-07 11:35:26 -08:00
Rishi Gupta
2d015d85d6 user docs: Note that quoted mentions do not act as mentions. 2019-02-06 22:16:24 -08:00
Rishi Gupta
e8251bb758 user docs: Add delete-a-topic. 2019-02-06 22:16:24 -08:00
Rishi Gupta
2d4c0ef292 user docs: Add rename-a-topic. 2019-02-06 22:16:24 -08:00
Rishi Gupta
aae9773f09 delete topic: Update wording in confirmation modal. 2019-02-06 22:16:24 -08:00
Tim Abbott
ab41f13575 docs: Fix mistakes in PGroonga documentation.
Eventually, we'll just make this the default, but for now, we should
fix the typos and use our standing approach for documenting running
management commands.
2019-02-06 12:17:45 -08:00
Rishi Gupta
7adc7ed490 docs: Update mobile-push-notifications to discourage legacy signup. 2019-02-06 11:53:39 -08:00
Thomas Ip
744cadc33c docs: Add missing link to npm. 2019-02-06 14:05:05 +08:00
Steve Howell
3ef9d18baf top left: Add border to starred messages count.
The border makes the alignment look nicer.  Without
a border your eyes plays tricks on you and makes it
seem like numbers are not in the same column.

The border color is the same subtle color as the
backgrounds in others.

Because CSS is annoying, you have to tweak the padding
to make room for the border.

(It should look ok in night mode, too.)
2019-02-05 16:56:16 -08:00
Steve Howell
4825479600 top left: Move "Starred messages" down.
Since it has different unread counts, we want
it grouped away from the other three.
2019-02-05 16:56:16 -08:00
Tim Abbott
32757b489b message_list: Move scroll-after-reply logic into rendering path.
Since the main autoscroll feature was implemeneted, the
maybe_advance_to_recently_sent_message logic had an unfortunate
structure, where the code for this potentially large scroll was
running AFTER the autoscroll decision was made, but before an actual
scroll could have occurred.

This resulted in code that was very difficult to reason about, as
there were 2 potential sources of scrolling when you send a new
message, with little connection between their implementations either
in location or implementation.

Moving this into the main autoscrolling code path clarifies the code,
with the added benefit of fixing a bug where we would report to the
user that they needed to scroll down when in fact we were just about
to scroll the bottom of the feed into view (via
maybe_advance_to_recently_sent_message).

With this change, we never display the "you need to scroll manually"
message in the cast that we just scrolled you there via selecting a
message.
2019-02-05 16:48:20 -08:00
Eeshan Garg
361d2d0688 webhooks/stripe: Add fixture and test for invoiceitem.created. 2019-02-05 18:40:38 -03:30
Tim Abbott
11ea8ae9fe tests: Fix test broken by recent url preview change. 2019-02-05 13:45:00 -08:00
Vaibhav
a494244427 message edit: Rearrange order of control icons.
This arranges the control icons in similar order as that in compose
box.
2019-02-05 13:42:58 -08:00
Rishi Gupta
a7a5188030 user status: Style status message in user popover. 2019-02-05 13:42:32 -08:00
Tim Abbott
a4b294da98 url preview: Remove useless logging.error in open graph code path.
As detailed in the comment, someone pasting a broken URL isn't a
situation that a server administrator needs to be notified about.
2019-02-05 13:25:47 -08:00
Tim Abbott
309aef4c27 compose: Fix "You need to scroll" notifications for large messages.
When you just sent a large message, our logic for "you need to scroll"
notifications did not correctly take into account the height of the
compose box.  This was easily reproduced when sending very long
messages.  The correct solution requires a bit of math to compute what
the visible area will look like after the compose box is closed.

This should be the final fix to #11138.
2019-02-05 13:17:10 -08:00
Eeshan Garg
20769f0fe9 zapier_app: Add support for private/huddle messages. 2019-02-05 17:25:58 -03:30
Rishi Gupta
36472413e4 hotspots: Add hotspot for gear menu. 2019-02-05 12:19:21 -08:00
Harshit Bansal
ae3881b472 tests: Extract SocialAuthBase class.
Extracts out common tests so that future social-auth backends can
be tested without duplicating tests. I have been careful to not
change any testing logic.
2019-02-05 11:39:31 -08:00
Vaibhav
61ebee6993 message edit: Add "preview" option to edit UI.
This add the "Preview" option to message edit controls similar to that in
compose UI.

Fixes #11438.
2019-02-05 11:35:30 -08:00
Vaibhav
24445309e2 compose: Extract render_and_show_preview function.
This adds a function that controls the whole process of applying
markdown and displaying the markdown rendering preview on request;
This is required to avoid code duplication when adding preview feature
to message-edit UI.
2019-02-05 11:31:56 -08:00
Vaibhav
5e4bd9f57d compose: Change preview_message_area and preview_content to classes.
Preview box is to be reused in message edit. ID does not remain the
same in message-edit section so the styles are changed to classes.
2019-02-05 11:28:13 -08:00
Tim Abbott
e91f22c416 docs: Reorganize and simplifiy LDAP data synchronization docs. 2019-02-05 10:37:04 -08:00
Harshit Bansal
2abe325147 docs: Add documentation for the new custom profile data sync feature.
Fixes: #10976.
2019-02-05 10:25:50 -08:00
Harshit Bansal
1a5e07e0f9 ldap: Add ability to automatically sync custom profile fields. 2019-02-05 10:25:50 -08:00
YashRE42
22e3955262 search: Add stop words to page_params.
Add all the stop words to page_params, reading from the
`zulip_english.stop` database, with caching to avoid loading the file
on every page load.

Part of #10592.
2019-02-05 10:23:28 -08:00
Vishnu Ks
4b1229c072 billing: Add node tests for upgrade.js. 2019-02-04 22:37:05 -08:00
Vishnu Ks
5f0492b3b1 billing: Use this.value instead of .val().
This change is mostly for making testing easier.
2019-02-04 22:37:05 -08:00
Vishnu Ks
ab97a84f3a billing: Use is_valid_input helper for checkValidity.
Mainly for making the node tests easier to write.
2019-02-04 22:37:05 -08:00
Vishnu Ks
7b22fec532 billing: User on(change) instead of change() in upgrade.js. 2019-02-04 22:37:05 -08:00
Tim Abbott
47c85fa02e email: Set email based on realm email_address_visibility.
This causes changing the email_address_visibility field to actually
modify what user_profile.email values are generated for users, both on
user creation and afterwards as email addresses are edited.

The overall feature isn't yet complete, but this brings us pretty close.
2019-02-04 18:45:10 -08:00
overide
fd3be00fbd media: Fix sender name clipping in mobile.
In mobile devices, letters like g, y, p etc. in sender name were clipped from bottom.
Fixed by adding line height to sender name.

Fixes: #11445
2019-02-04 14:31:30 -08:00
Rishi Gupta
71958fc1d8 Revert "webhooks/stripe: Add support for remaining payout events."
These ended up more noisy than helpful.

This reverts commit d4cd789213.
2019-02-04 12:34:32 -08:00
Rishi Gupta
942e419b85 Revert "webhooks/stripe: Handle invoice events explicitly."
The original commit made a number of well-meaning but suboptimal product
changes to the invoice events, such as threading them under the invoice id
rather than the customer id. It also seems to be causing 500s for
invoiceitem events, though I'm not sure why.

This reverts commit 65489b0391.
2019-02-04 12:18:47 -08:00
Rohitt Vashishtha
19672241e6 markdown: Disable definition/reference links in marked.
We had disabled reference style links in bugdown, however,
we hadn't disabled them in marked. This commit rectifies
that and adds test cases for the same.

Fixes #11350.
2019-02-04 11:16:37 -08:00
Wyatt Hoodes
9c68a97472 import/export: Use separate analytics.json for analytics data.
This helps keep the realm.json small and easy to process; previously,
almost the entire size of that file was the analytics data.

We implement this by refactoring the analytics Config objects into a
separate subroutine that writes to a separate file, plus the
corresponding import code.

Manual testing was performed by exporting the 'analytics' realm, and
importing back to a newly created 'test' realm.  The 'test' realm was
then exported and the json files were inspected.  The data appeared
consistent with no abnormalities.

Fixes: #11220.
2019-02-04 10:59:24 -08:00
Wyatt Hoodes
bb6a75c3dc populate_analytics_db.py: Subscribe user for exporting.
AssertionErrors were raised when attempting to run manual comparison
tests to ensure correctness when exporting the analytics realm using
export_from_config.  This was caused by this populate_analytics_db
stream being created without any subscribers, which violates an
invariant.

We fix this by simply subscribing the 'shylock' user to that stream.
2019-02-04 10:59:24 -08:00
vinitS101
0c37b9f116 Fix typo in new-feature-tutorial.md 2019-02-03 17:02:35 -08:00
Tim Abbott
001ec76e1f export: Document /etc/zulip when discussing server migrations. 2019-02-02 23:22:22 -08:00
Shubham Dhama
afe2197210 invite: Add UI to generate multiuse invitation link.
Adds a very basic UI to generate the multiuse invitation link.
2019-02-02 23:05:47 -08:00
Shubham Dhama
dee4e3fb89 ajax: Fix wrong ajax setting name from beforeSubmit to beforeSend.
The beforeSubmit function was a feature of the jquery-form plugin that
we removed months ago; the appropriate similar feature of jQuery's
built-in AJAX library is beforeSend.
2019-02-02 23:05:10 -08:00
Tim Abbott
f34a5d6828 signals: Document the weird unused import for signal registration. 2019-02-02 23:04:02 -08:00
Anders Kaseorg
c2cb804ebe analytics/views.py: Remove unused imports.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:43:58 -08:00
Anders Kaseorg
3127fb4dbd zerver/tests: Remove unused imports.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:43:03 -08:00
Anders Kaseorg
f0ecb93515 zerver core: Remove unused imports.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:41:24 -08:00
Anders Kaseorg
3968fe9fdf tornado: Remove unused imports.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:33:13 -08:00
Anders Kaseorg
9add47ba0f docs/conf.py: Remove unused imports.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:31:45 -08:00
Anders Kaseorg
f5197518a9 analytics/zilencer/zproject: Remove unused imports.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:31:45 -08:00
Anders Kaseorg
4e0a79d146 test_messages: Don’t mock an unused import.
Since 8a1794caa3, we don't do any
caching in that system.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:29:53 -08:00
Anders Kaseorg
023f8a0def test_outgoing_webhook_interfaces: Don’t mock an unused import.
We eliminated use of this function in outgoing_webhook.py in
bdc95b5d72.

Tweaked by tabbott to also eliminate code only used for that mock.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:28:11 -08:00
Anders Kaseorg
56a675d5ec export: Remove unused imports.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:25:27 -08:00
Anders Kaseorg
e12c433745 bugdown: Remove unused imports.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:25:22 -08:00
Anders Kaseorg
4e21cc0152 views: Remove unused imports.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:23:43 -08:00
Tim Abbott
13b9e90a40 analytics: Fix importing zilencer.
In ebdd55814c, we added zilencer imports
without using the proper mocking procedure for when zilencer is not enabled.

This whole setup is a mess and probably we should enable zilencer
unconditionally in a future version.
2019-02-02 17:18:57 -08:00
Anders Kaseorg
2a2e744b27 management: Remove unused imports in management commands.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:12:36 -08:00
Anders Kaseorg
ee8ff4df66 tools: Remove unused imports.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:10:31 -08:00
Anders Kaseorg
a0041afaf9 python: Stop importing Length from the wrong file.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:09:10 -08:00
Anders Kaseorg
b80a095196 python: Stop importing PushNotificationBouncerException from wrong file.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:09:01 -08:00
Anders Kaseorg
1a3c195f7e python: Stop importing TestCase from the wrong file.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:08:59 -08:00
Anders Kaseorg
e8b32a4b67 python: Stop importing get_display_recipient from the wrong file.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:08:57 -08:00
Anders Kaseorg
39ac378220 webhooks: Remove unused imports.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:05:20 -08:00
Anders Kaseorg
e984107966 scripts: Remove unused imports.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:02:58 -08:00
Anders Kaseorg
c109690cf8 puppet: Remove unused Python imports.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:02:12 -08:00
Anders Kaseorg
4bd28f7ae6 migrations: Remove unused imports.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 17:01:04 -08:00
Tim Abbott
96f096f38e analytics: Add section for remote Zulip servers. 2019-02-02 16:55:12 -08:00
Tim Abbott
ebdd55814c analytics: Add support for graphing remote analytics data.
Combined with recent work on submitting data, one can now view the
high-level usage numbers for chat.zulip.org on zulipchat.com's
dashboards.
2019-02-02 16:55:12 -08:00
Tim Abbott
a6d3bbfc63 zilencer: Add client-size rate limiting of analytics upload.
This should help both by avoiding high memory usage causing OOM kills
on the client, as well as timeouts causing an exception email to be
sent.
2019-02-02 11:51:22 -08:00
Tim Abbott
55ead5b77f zilencer: Fix buggy validation of installation_counts upload.
This was a simple copy-paste error.  It's probably worth a bit more
work on code duplication in this code path.
2019-02-02 11:51:22 -08:00
Anders Kaseorg
4fef10f4e6 install: Improve error handling.
On usage errors (except --help), write usage message to stderr and
exit with nonzero status.

Forbid setting the hostname and email to the example values.  Those
are specifically checked for and would fail later.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-02-02 11:18:42 -08:00
Mohit Gupta
01d34a8575 compose: Use lightbox when clicking images in compose preview.
Fixes #11424.
2019-02-02 11:11:24 -08:00
Mohit Gupta
9ce6cc5097 lightbox: Extract arguments to payload as variables.
This extracts sender_full_name (and the existing $parent), which will
make life easier for using the lightbox for images outside the message
feed.
2019-02-02 11:09:22 -08:00
Abhinav Singh
e7c8077abc edit: Add support for using video call link in message edit.
This code will correctly add video call link to the message
textarea based on whether 'Add video call' was selected from
message composition form or message edit form.

The implementation was semi-rewritten by tabbott to remove an
unnecessary global variable, with fixes for the unit tests from
showell.

Fixes #11188.
2019-02-02 11:03:31 -08:00
Eeshan Garg
954a98b49f webhooks/jira: Ignore issuelink_created events.
Notifications for this event aren't very useful to begin with,
plus exceptions from this event are cluttering up our webhook
error logs.
2019-02-02 14:53:15 -03:30
Steve Howell
6116ede5f7 compose tests: Avoid global event var.
It's better to be explicit here and avoid leaking
between tests.
2019-02-02 07:05:16 -08:00
Steve Howell
8e88ca3a46 compose tests: Encapsulate helper.
We don't need to have global vars shared across all
functions using `setup_parents_and_mock_remove`.
2019-02-02 07:05:16 -08:00
Rishi Gupta
d7043eec49 portico: Add branding to /features. 2019-02-01 23:34:47 -08:00
Rishi Gupta
d5a0769fc0 portico: Update notifications section title on /features. 2019-02-01 23:34:47 -08:00
Rishi Gupta
3e5e4ce561 portico: Add information on billing guests. 2019-02-01 23:34:47 -08:00
Tim Abbott
1d788980be docs: Update changelog with most changes for next major release. 2019-02-01 23:17:37 -08:00
Hemanth V. Alluri
73d26c8b28 streams: Render and store the stream description from the backend.
This commit does the following three things:
    1. Update stream model to accomodate rendered description.
    2. Render and save the stream rendered description on update.
    3. Render and save stream descriptions on creation.

Further, the stream's rendered description is also sent whenever the
stream's description is being sent.

This is preparatory work for eliminating the use of the
non-authoritative marked.js markdown parser for stream descriptions.
2019-02-01 22:24:18 -08:00
Tim Abbott
022c8beaf5 analytics: Add APIs for submitting analytics to another server.
This adds a new API for sending basic analytics data (number of users,
number of messages sent) from a Zulip server to the Zulip Cloud
central analytics database, which will make it possible for servers to
elect to have their usage numbers counted in published stats on the
size of the Zulip ecosystem.
2019-02-01 22:03:52 -08:00
Rishi Gupta
8df0d95559 billing: Remove deprecated RealmAuditLog.requires_billing_update. 2019-02-01 18:49:43 -08:00
Rishi Gupta
85f7ac8172 analytics: Remove Anomaly model. 2019-02-01 18:48:18 -08:00
Tim Abbott
1f4de8328d actions: Add a comment explaining historical messages in detail. 2019-02-01 18:41:03 -08:00
kunal-mohta
ac55a5222c messages: Add support for quickly deleting all messages in a topic.
This is primarily a feature for onboarding, where an organization
administrator might send a bunch of random test messages as part of
joining, but then want a pristine organization when their users later
join.

But it can theoretically be used for other use cases (e.g. for
moderation or removing threads that are problematic in some way).

Tweaked by tabbott to handle corner cases with
is_history_public_to_subscribers.

Fixes #10912.
2019-02-01 17:09:44 -08:00
sameerchoubey
65489b0391 webhooks/stripe: Handle invoice events explicitly.
Closes #10909
2019-02-01 21:38:20 -03:30
Eeshan Garg
bffc473ec8 webhooks/zapier: Support stream messages for the Zapier Zulip app. 2019-02-01 21:19:26 -03:30
Eeshan Garg
b1ce237624 webhooks/zapier: Support authentication for the Zapier Zulip app. 2019-02-01 21:19:26 -03:30
Eeshan Garg
f9ee393e4f webhooks/common: Allow suppressing exceptions for missing headers.
This is useful in cases where an event type HTTP header isn't
crucial for inferring the payload's type.
2019-02-01 21:19:26 -03:30
Shubham Dhama
5779320874 invites: Use stream_id instead of stream names in invitation.
This replaces the current usage of stream names with stream ids.

This commit also removes the `traditional` attribute from the invite
form as now we are sending stream_ids as an argument; this was the
only place in the codebase we used traditional=true, and it's great to
have it removed.
2019-02-01 15:47:20 -08:00
Shubham Dhama
8f680c3dac invite: Extract get_common_invitation_data.
This is a minor refactor to make this code reusable.
2019-02-01 15:39:58 -08:00
Shubham Dhama
b4e2313cbc invite: Add stream_id stream data returned by get_invite_streams().
This is done by using `stream_data.get_invite_stream_data()` in place of
`stream_data.invite_streams()`.
2019-02-01 15:35:42 -08:00
Shubham Dhama
fbd73ba637 stream_data: Add get_invite_stream_data helper function.
This function unlike `invite_streams()` returns an array of objects having
various info (name, stream_id, invite_only, default_stream) related to
streams rather than an array of names of streams.
2019-02-01 15:35:42 -08:00
Tim Abbott
a7fb7d1f5c user status: Add a maxlength to the input field.
This avoids an annoying bug where trying to save a too-long status
makes the save button appear to do nothing.
2019-02-01 15:23:35 -08:00
Steve Howell
9ce5d51bdc user status: Fix tiny green dot in user popover.
We now compute the class that drives the tiny
green/orange/empty dot in the user popover using
the same logic as the buddy list.

This was broken in the early implementation of
set/clear-away, but it was never released.

Fixes #11413
2019-02-01 15:23:35 -08:00
Steve Howell
6375d72862 user status: Change icon for set/clear away. 2019-02-01 15:23:35 -08:00
Steve Howell
7f23b7fb98 user status: Fix wording in set-status modal. 2019-02-01 15:23:35 -08:00
Steve Howell
3e615fd8b0 user status: Fix wording in user popover. 2019-02-01 15:23:35 -08:00
Steve Howell
ab8b50453b user status: Show status in user info popovers. 2019-02-01 15:23:35 -08:00
Vishnu Ks
150d9c9d3e stats: Fix the bug in showing all time actives by default.
Followup commit of 0b1e36db27
2019-02-01 11:14:03 -08:00
Shoumorup
e8ba08367b requirements: Upgrade pyflakes.
Pyflakes has been upgraded from 2.0.0 to 2.1.0 and
a few new linter errors have been fixed.

Fixes #11397.
2019-02-01 07:26:13 -08:00
Anders Kaseorg
893e1475bb setup_virtualenv: Do not activate the virtualenv on creation.
Instead, manually activate it in the one place where this
functionality was used (tools/lib/provision.py).  This way we avoid
trying to activate the Python 2 thumbor virtualenv from Python 3.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-31 17:55:04 -08:00
Tim Abbott
1bcd7dfbad remote_server: Return the result dictionary on success. 2019-01-31 17:39:41 -08:00
Greg Price
6613f4c22c test-install/install: Print usage when run without arguments.
The `-z "$INSTALLER"` was intended to do this -- but we don't get that
far, because the `shift` fails.
2019-01-31 16:15:51 -08:00
Tim Abbott
2d11e163dd push_notifications: Move "push" part of URLs to callers.
This will make it possible for us to use this library for endpoints
not directly related to push notifications.
2019-01-31 15:22:00 -08:00
Rishi Gupta
4fab08172b billing: Remove deprecated billing fields from Realm. 2019-01-31 15:12:43 -08:00
Rishi Gupta
8f7e38c559 billing: Remove deprecated billing tables and fields from corporate/models. 2019-01-31 15:12:43 -08:00
Rishi Gupta
55179f913c billing: Remove references to Customer.has_billing_relationship. 2019-01-31 15:12:43 -08:00
Tim Abbott
88fae0b6a9 remote_server: Extract remote_server.py library.
This moves the network request code for connecting to the push
notification bouncer service into its own module.
2019-01-31 15:08:46 -08:00
ss62171
5649b954ef stream_stats: Add a column representing type of stream.
This adds a column which represents whether a stream is public or
private.

Fixes #11374.
2019-01-31 15:04:45 -08:00
ss62171
5fd9748e13 stream_stats: List number of private and public streams for each realm.
Previously, we only displayed public streams and didn't list the
number of them.  Now, we just list all streams.
2019-01-31 15:04:09 -08:00
synicalsyntax
76bc253a8a docs: Fix mistake in optimize-svg test suite description. 2019-01-31 13:31:07 -08:00
synicalsyntax
2162d06e7c docs: Document custom icon webfont subsystem in Frontend build processes. 2019-01-31 13:31:07 -08:00
Eeshan Garg
f4221f2655 internal_prep_message: Don't call ensure_stream for stream IDs.
Ever since we implemented support for stream IDs in Addressee,
Addressee.stream_name() can now return None. This commit ensures
that _internal_prep_message only calls ensure_stream when
Addressee.stream_name() is not None.
2019-01-31 12:55:10 -08:00
Eeshan Garg
0420ecadeb addressee: Use stream ID for sender's default sending stream. 2019-01-31 12:43:38 -08:00
Eeshan Garg
998437c123 check_message: Support sending stream messages by ID.
This commit also contains the following auxiliary changes:
* Adds a custom exception, StreamWithIDDoesNotExist for when
  a stream with a given ID does not exist because the error
  message returned by StreamDoesNotExist only makes with stream
  names, not IDs.
* Adds a new helper, get_stream_by_id_in_realm, which is similar
  to get_user_profile_by_id_in_realm (introduced in #10391).
* Adds a helper, validate_stream_id_with_pm_notification, which
  returns the Stream object associated with a given ID and also
  handles PM notifications to the bot owner if the message was
  sent by a bot and if the stream does not exist or has no
  subscribers.
* Modifies the message sent by send_pm_if_empty_stream to
  accommodate stream IDs.

Note that all of the above changes are required before check_message
can be modified to support stream IDs.
2019-01-31 12:43:38 -08:00
Eeshan Garg
b8221555d2 addressee: Add support for stream IDs to Addressee.legacy_build(). 2019-01-31 12:43:38 -08:00
Tim Abbott
9b25f8789f hipchat: Fix handling of user IDs in Stride import.
We've had this code oscillated a few times; the original comparison
was added as part of Stride import but broke HipChat import.
c34a8f2e69 fixed HipChat import but
regressed Stride.

This change fixes this for both HipChat + Stride.
2019-01-31 12:40:05 -08:00
Vishnu Ks
18ffec626f billing: Use -- instead of : in fixture files.
It's not safe to use ":" in filenames.

Fixes #11320
2019-01-31 12:26:00 -08:00
Pragati Agrawal
e1772b3b8f tools: Upgrade Pycodestyle and fix new linter errors.
Here, we are upgrading pycodestyle version from 2.4.0 to 2.5.0.

Fixes: #11396.
2019-01-31 12:21:41 -08:00
Abhinav Singh
07bac66db7 right sidebar: Hide user detail popover correctly.
This code will hide the user detail popover correctly
when the user wants to search other users.

Fixes #11362.
2019-01-31 11:58:24 -08:00
Steve Howell
4a56980bff starred messages: Change styling of count.
The count for "starred messages" is not a
true "unread" count.

We break out the CSS so that it's styled
differently from other elements.
2019-01-31 19:01:27 +00:00
ss62171
b7a0a45f01 people: Improve mentioning users with diacritics in their name.
This makes it possible to mention a user with a name like Gaël that
contains diacritics by typing e.g. "Gael", significantly reducing the
need to use a special keyboard to mention other users.

Fixes #11183.
2019-01-31 10:07:44 -08:00
Tim Abbott
805ec5fbdb manage.py: Revert sabotaging pika.adapters.twisted_connection import.
This reverts commit ec9f6702d8.

Now that pika 0.13.0 has merged our PR to not import twisted unless it
is needed, we don't need to use this performance hack in order to
avoid wasting time importing twisted and all its dependencies.
2019-01-31 10:04:28 -08:00
Vishnu Ks
0d0007742f requirements: Upgrade pika from 0.12.0 to 0.13.0.
The important changes to pika for us are based on this PR of ours:
https://github.com/pika/pika/pull/1129

Fixes #11394.
2019-01-31 10:04:07 -08:00
Steve Howell
a1a7047819 top left: Remove home-link markup in the main app.
The `home-link` markup wasn't used in the app,
and it was confusing, since we do use that
markup for the portico system.
2019-01-30 13:53:20 -08:00
Steve Howell
090227e809 tab bar: Remove unused markup.
The only time we set the `home` flag to true
is when it's the last (and only) item in the
list, in which case we flip `hash` to false
at the end of `make_tab_data()`.

So the section of code where both `home` and
`flag` were true is dead code.

Also, we can use `else` instead of `unless`.
2019-01-30 13:53:20 -08:00
Steve Howell
9986e41999 top left: Simplify markup for main links.
The following elements in the top left corner
are major components of our app:

    All messages
    Private messages
    Starred messages
    Mentions

We can now find them directly:

    $('.top_left_all_messages')
    $('.top_left_private_messages')
    $('.top_left_starred_messages')
    $('.top_left_mentions')

Before this, we had to build up complicated selectors
like below:

    exports.get_global_filter_li = function (filter_name) {
        var selector = "#global_filters li[data-name='"
            + filter_name + "']";
        return $(selector);
    };

I don't think any newbie would know to grep for "global_filter",
and I've seen a PR where somebody added specific markup here
to "Private messages" because they couldn't grok the old scheme.

Another thing to note is that we still have a "home-link"
class for "All messages", which overlapped with portico
code that had the same name.  (There were some inaccurate
comments in the code relating to the tab bar, but we don't
actually have a way to click to the home view in the tab
bar any more.)  I'll eliminate that cruft in another commit.

For this commit the four elements still have the
"global-filter" class, since there's some benefit to being
able to style them all as a group, although we should give
it a nicer name in a subsequent commit.

Most of this PR is basic search/replace, but I did add a
two-line helper: `top_left_corner.update_starred_count`
2019-01-30 13:53:20 -08:00
Rishi Gupta
a37558b021 billing: Update get_seat_count to incorporate guests. 2019-01-30 10:35:01 -08:00
Rishi Gupta
db6e6472b1 billing: Set idempotency key to None when running test suite. 2019-01-30 10:35:01 -08:00
Rishi Gupta
60f2213451 billing: Change seat count to 6 in tests.
We were about to make it 7 anyway by changing the definition of
get_seat_count. Hopefully 6 will be a bit more future proof.
2019-01-30 10:35:01 -08:00
Rishi Gupta
fa2b5df107 settings: Update tip strings for adding custom emoji. 2019-01-30 10:34:16 -08:00
Rishi Gupta
3f385cae38 invite: Rename guest users to guests. 2019-01-30 10:34:16 -08:00
Vishnu Ks
cf5b21d422 version: Bump provision version for mass dependency upgrade. 2019-01-30 09:50:43 -08:00
Vishnu Ks
5bf437b964 thumbor requirements: Upgrade virtualenv-clone from 0.4.0 to 0.5.1. 2019-01-30 09:50:43 -08:00
Vishnu Ks
8ac5ebbf39 requirements: Upgrade setuptools from 40.6.3 to 40.7.1. 2019-01-30 09:50:43 -08:00
Vishnu Ks
ec3ca2b30e requirements: Upgrade pip from 18.1 to 19.0.1. 2019-01-30 09:50:43 -08:00
Vishnu Ks
8fc3a1f6b7 requirements: Upgrade virtualenv-clone from 0.4.0 to 0.5.1. 2019-01-30 09:50:43 -08:00
Vishnu Ks
6e0764f32d requirements: Upgrade twilio from 6.22.1 to 6.23.1. 2019-01-30 09:50:43 -08:00
Vishnu Ks
50a53a4fc6 requirements: Upgrade stripe from 2.17.0 to 2.20.0. 2019-01-30 09:50:43 -08:00
Vishnu Ks
1159480ef8 requirements: Upgrade SQLAlchemy from 1.2.15 to 1.2.17. 2019-01-30 09:50:43 -08:00
Vishnu Ks
89467538c7 requirements: Upgrade Scrapy from 1.5.1 to 1.5.2. 2019-01-30 09:50:43 -08:00
Vishnu Ks
9231e5453c requirements: Upgrade pyasn1-modules from 0.2.3 to 0.2.4. 2019-01-30 09:50:43 -08:00
Vishnu Ks
84dd501775 requirements: Upgrade psycopg2 from 2.7.6.1 to 2.7.7. 2019-01-30 09:50:43 -08:00
Vishnu Ks
757e0e39b8 requirements: Upgrade oauthlib from 2.1.0 to 3.0.1. 2019-01-30 09:50:43 -08:00
Vishnu Ks
f29aff0de6 requirements: Upgrade disposable-email-domains from 0.0.39 to 0.0.43. 2019-01-30 09:50:42 -08:00
Vishnu Ks
5c0dc326eb requirements: Upgrade cryptography from 2.4.2 to 2.5. 2019-01-30 09:50:42 -08:00
Vishnu Ks
2ecd02aa5d requirements: Upgrade backports.ssl-match-hostname from 3.5.0.1 to 3.7.0.1. 2019-01-30 09:50:42 -08:00
Vishnu Ks
2f9a38971d requirements: Upgrade argon2-cffi from 18.3.0 to 19.1.0.
This also upgrades various recursive dependencies of Zulip.
2019-01-30 09:50:33 -08:00
Vishnu Ks
a3996098cb requirements: Fix JSON syntax in unupgradables.json. 2019-01-30 07:30:31 +00:00
Tim Abbott
dc663057ce docs: Add changelog from 1.9.2 release. 2019-01-29 16:54:45 -08:00
Steve Howell
c665f809f2 run-dev: Make address-in-use errors more obvious.
This seems to be a common enough pitfall to justify
a bit of extra handling.  Example output:

    $ ./tools/run-dev.py
    Clearing memcached ...
    Flushing memcached...
    OK
    Starting Zulip services on ports: web proxy: ...
    Note: only port 9991 is exposed to the host in a Vagrant environment.

    ERROR: You probably have another server running!!!

    Traceback (most recent call last):
      File "./tools/run-dev.py", line 421, in <module>
        app.listen(proxy_port, address=options.interface)
      File "/srv/zulip-py3-venv/lib/python3.5/...
        server.listen(port, address)
      File "/srv/zulip-py3-venv/lib/python3.5/...
        sockets = bind_sockets(port, address=address)
      File "/srv/zulip-py3-venv/lib/python3.5/...
        sock.bind(sockaddr)
    OSError: [Errno 98] Address already in use
    Terminated
2019-01-29 16:03:47 -08:00
Harshit Bansal
837483b026 tests: Don't fail silently on 500 on logins. 2019-01-29 16:01:30 -08:00
Harshit Bansal
6777b94d41 lib: Extract validate_user_custom_profile_field(). 2019-01-29 16:01:30 -08:00
Harshit Bansal
9bac192241 dev_ldap: Add custom profile data. 2019-01-29 16:01:30 -08:00
Harshit Bansal
88c1d868d2 dev_ldap: Fix password in mode 'c' to be equal to username. 2019-01-29 16:01:30 -08:00
Harshit Bansal
dccfadc1a5 minor: Fix some typing errors. 2019-01-29 16:01:30 -08:00
Rishi Gupta
78d98168a4 portico: Add stride import to /features and /help. 2019-01-29 13:48:39 -08:00
Steve Howell
c2fcfc087a bugdown: Include message id in exceptions. 2019-01-29 12:49:56 -08:00
Steve Howell
643d4cacd3 bugdown tests: Pass message stub to bugdown_convert().
This makes the calling sequence slightly more
realistic (without any additional overhead).
2019-01-29 12:49:56 -08:00
Tim Abbott
8d404dbcc6 confirmation: Fix "continue to registration" full name handling.
Apparently, the "continue to registration" flow used a subtly invalid
way of encoding the full name.  We put in the query part of the action
URL of the HTML form, but apparently HTML forms with a `GET` type will
ignore the query part (replacing it with any input values), which
makes sense but doesn't do what we want here.  There are a few sane
ways to fix it, but given that the encoding logic we had before for
including the name in the URL was ugly, I'm pretty happy with just
adding a hidden input to the form for the name.
2019-01-29 12:39:40 -08:00
Tim Abbott
9dc4b04e52 auth: Migrate Google authentication off deprecated name API.
As part of Google+ being removed, they've eliminated support for the
/plus/v1/people/me endpoint.  Replace it with the very similar
/oauth2/v3/userinfo endpoint.
2019-01-29 12:39:40 -08:00
Rishi Gupta
42deef8c57 portico: Add inspire-hep to /for/open-source. 2019-01-29 11:46:19 -08:00
Rishi Gupta
52a513b0a8 portico: Add infinispan to /for/open-source. 2019-01-29 11:46:19 -08:00
Rishi Gupta
75145fdb58 portico: Update logos on /hello. 2019-01-29 11:46:18 -08:00
Rishi Gupta
03e12e1921 portico: Add mariadb to for/open-source. 2019-01-29 11:45:44 -08:00
Tim Abbott
aea93f9826 api: Document support for setting stream description on creation.
This makes clear how to set the stream description when making a new
stream.

Fixes #11372.
2019-01-29 11:28:55 -08:00
Daniel Bradburn
1e65cdd072 emoji: Only resize custom emoji that need it.
This additional logic to prevent resizing is certain circumstances
(file size, dimensions) is necessary because the pillow gif handling
code seems to be rather flaky with regards to handling gif color
palletes, causing broken gifs after resizing.  The workaround is to
only resize when absolutely necessary (e.g. because the file is larger
than 128x128 or 128KB).

Fixes #10351.
2019-01-29 10:33:50 -08:00
Steve Howell
a964977960 user status: Add ability to edit status text. 2019-01-29 10:27:49 -08:00
Rohitt Vashishtha
a2751d90c2 widgets: Remove ALLOW_SUB_MESSAGES flag and enable widgets by default. 2019-01-29 09:34:14 -08:00
Rohitt Vashishtha
a197959959 poll-widget: Downgrade key error to warning.
It is an error, but it is obnoxious in dev to get these.
2019-01-29 09:34:14 -08:00
Rohitt Vashishtha
c176891c2e poll-widget: Refactor comment to option.
We had initially designed the poll widget like a blog
post with comments beneath it but it makes more sense
to think of it as just a simple poll with options.
2019-01-29 09:34:14 -08:00
Rohitt Vashishtha
5641afc6e2 poll-widget: Add syntax for adding options when creating poll.
We add a new syntax which converts the messages like the following:

```
/poll Who do you support?

Nadal
- Djokovic
```

to a poll with the two names as options. The list syntax is optional
since anyone making a poll is likely to want to create a list anyway.
2019-01-29 09:34:14 -08:00
Rishi Gupta
1b0b72c827 billing: Change upgrade errors from info to warning. 2019-01-29 07:46:52 -08:00
Rishi Gupta
81745ba171 billing: Show licenses_used and better renewal information on /billing. 2019-01-29 07:38:24 -08:00
Rishi Gupta
4ccbeeb4a9 billing: Add an event_time argument to renewal_amount. 2019-01-29 07:37:21 -08:00
Rishi Gupta
a5324b6ea7 billing: Add a test for a race condition in process_initial_upgrade. 2019-01-29 07:01:31 -08:00
Rishi Gupta
6a1017ea94 billing: Update text on /upgrade. 2019-01-29 06:30:19 -08:00
Rishi Gupta
9018ef5175 billing: Do not require a Stripe account to store Customer discounts. 2019-01-29 06:09:11 -08:00
Rishi Gupta
21b51ba8d1 billing: Remove mix option from backend. 2019-01-29 06:09:11 -08:00
xiaomingplus
7331cdc0f5 provision: Fix Docker development environment unicode issues.
Apparently, we need these environment settings in bashrc as well.  

Fixes #11323.
2019-01-28 22:08:19 -08:00
Tim Abbott
0181086d0f streams: Improve validation for arguments to stream creation.
This doesn't have any security impact, since we overwrote any other
fields in any case, and also this step happens before the security
part of input validation for stream creation.  But this does improve
error messages if one tries to specify other arguments, and also makes
more clear that the `description` argument is supported here.
2019-01-28 22:02:16 -08:00
Akshay Gupta
88ed75d06d travis_webhooks: Update the list of bad statuses.
Fixes #11259.
2019-01-28 21:37:18 -08:00
Adarsh Patel
9b740df277 api_docs: Specify max width for long code examples.
Fixes #10673.
2019-01-28 22:39:54 -03:30
Rishi Gupta
4aa2ac1b52 billing: Add functions for automatic invoicing of plans. 2019-01-28 16:04:11 -08:00
Rishi Gupta
421cda0e34 billing: Adding invoicing fields to CustomerPlan. 2019-01-28 16:04:11 -08:00
Rishi Gupta
fe280fc38c billing: Create StripeTestCase. 2019-01-28 16:04:11 -08:00
Rishi Gupta
83a7595feb billing: Update next_renewal_date to take an event_time.
Also changes a < into a <= in add_plan_renewal_to_license_ledger_if_needed.
2019-01-28 16:04:11 -08:00
Rishi Gupta
7c11fe819a billing: Update license ledger when users are added and removed. 2019-01-28 16:04:11 -08:00
Rishi Gupta
03c71dad17 billing: Fix misuses of CustomerPlan.discount. 2019-01-28 16:04:11 -08:00
Wyatt Hoodes
8eac361fb5 docs: Refactor BS work with use of cache_with_key.
Refactor the potentially expensive work done by Beautiful Soup into a
function that is called by the alter_content function, so that we can
cache the result.  Saves a significant portion of the runtime of
loading of all of our /help/ and /api/ documentation pages (e.g. 12ms
for /api).

Fixes #11088.

Tweaked by tabbott to use the URL path as the cache key, clean up
argument structure, and use a clearer name for the function.
2019-01-28 15:21:52 -08:00
Matthew Wegner
370cf1a2cb import: Normalize Slackbot String Comparison.
In very old Slack workspaces, slackbot can appear as "Slackbot", and
the import script only checks for "slackbot" (case sensitive).  This
breaks the import--it throws the assert that immediately follows the
test.  I don't know how common this is, but it definitely affected our
import.

The simple fix is to compare against a lowercased-version of the
user's full name.
2019-01-28 14:59:41 -08:00
Steve Howell
f2b26b9bcc integration tests: Add check for new messages.
This commit should make it a bit easier to debug
integrations that silently don't send any messages.
2019-01-28 14:56:42 -08:00
Tim Abbott
6994fad237 portico: Specifically mention open source projects in /for/open-source. 2019-01-28 14:50:20 -08:00
Rohitt Vashishtha
ff90c0101c bugdown: Process word boundaries properly in realm_filters.
Earlier, our realm filters didn't render for languages that do not
use spaces (eg: Japanese) since we used to check for the presence
of an actual space character. This commit replaces that logic with
a complex scheme to detect word boundaries.

Also, we convert the RealmFilterPattern to subclass InlineProcessor
and make use of the new no-op feature in py-markdown 3.0.1 where we
can tell py-markdown that our pattern didn't find a match despite
the initial regex getting matched.

Fixes #9883.
2019-01-28 14:48:15 -08:00
Steve Howell
ad071ced47 bugdown: Avoid recomputing the stream-link regex. 2019-01-28 13:12:37 -08:00
Rohitt Vashishtha
2dc447d707 bugdown: List py-markdown 3.0.1 features that we do not use.
Tweaked by tabbott to extend the documentation.
2019-01-28 13:12:37 -08:00
Rohitt Vashishtha
434094e599 bugdown: Restructure Bugdown to extend Markdown from being an extension.
Since we are building our parser from scratch now:

1. We have control over which proccessor goes at what priority number.
   Thus, we have also shifted the deprecated `.add()` calls to use the
   new `.register()` calls with explicit priorities, but maintaining
   the original order that the old method generated.

2. We do not have to remove the processors added by py-markdown that
   we do not use in Zulip; we explicitly add only the processors we
   do require.

3. We can cluster the building of each type of parser in one place,
   and in the order they need to be so that when we register them,
   there is no need to sort the list. This also makes for a huge
   improvement in the readability of the code, as all the components
   of each type are registered in the same function.

These are significant performance improvements, because we save on
calls to `str.startswith` in `.add()`, all the resources taken to
generate the default to-be-removed processors and the time taken to
sort the list of processors.

Following are the profiling results for the changes made. Here, we
build 10 engines one after the other and note the time taken to build
each of them. 1st pass represents the state after this commit and 2nd
pass represent the state after some regex modifications in the commits
that follow by Steve Howell. All times are in microseconds.

| nth Engine | Old Time | 1st Pass | 2nd Pass |
| ---------- | -------- | -------- | -------- |
|          1 |  92117.0 |  81775.0 |  76710.0 |
|          2 |   1254.0 |    558.0 |    341.0 |
|          3 |   1170.0 |    472.0 |    305.0 |
|          4 |   1155.0 |    519.0 |    301.0 |
|          5 |   1170.0 |    546.0 |    326.0 |
|          6 |   1271.0 |    609.0 |    416.0 |
|          7 |   1125.0 |    459.0 |    299.0 |
|          8 |   1146.0 |    476.0 |    390.0 |
|          9 |   1274.0 |    446.0 |    301.0 |
|         10 |   1135.0 |    451.0 |    297.0 |
2019-01-28 13:12:37 -08:00
Rohitt Vashishtha
9f2c52c86e bugdown: Rename variables regex to REGEX for importing regex module. 2019-01-28 12:00:58 -08:00
Steve Howell
3b7d899532 bugdown: Use CompiledPattern in AtomicLinkPattern.
We avoid re-computing the regex string here, and we
also avoid re-compiling the regex itself.

I decided to put the "one_time" decorator in the
bugdown file itself, just to reduce friction in
folks reading the "buyer beware" comments.

Unfortunately, we can't use this for the
get_web_link_regex() function due to testing concerns,
so that continues to do an inelegant cache-with-global-var
scheme.
2019-01-28 11:58:47 -08:00
Steve Howell
eea711a805 bugdown: Flatten get_web_link_regex().
We use early-exit to flatten the code.

I also tweaked the comments a bit based on some recent
profile findings.  (e.g. reading the file isn't actually
a big bottleneck, it's more the regex itself)
2019-01-28 11:58:46 -08:00
Steve Howell
852756aeb3 bugdown: Eliminate LinkPattern class.
The only code that used LinkPattern was AtomicLinkPattern.

We just move the helper method into AtomicLinkPattern.
2019-01-28 11:58:05 -08:00
Steve Howell
77446a710c bugdown: Optimize CompiledPattern.
We don't need the hacky step of passing in a blank
regex to the superclass's __init__ function.

All we need to do is assign `md` to `self.md`.
2019-01-28 11:57:28 -08:00
Steve Howell
025df33d7a bugdown: Rename VerbosePattern to CompiledPattern.
This class only requires a compiled regex--it's up
to the callers how they compile it (verbose or
otherwise).
2019-01-28 11:56:01 -08:00
Eeshan Garg
681f07f98f check_message: Refactor stream validation into separate function. 2019-01-28 11:48:17 -08:00
Eeshan Garg
4cb9a472e6 addressee: Add helper to check for missing or empty topic. 2019-01-28 11:42:26 -08:00
Steve Howell
17a9f20f76 node tests: Use zjquery in narrow.js.
Instead of custom stubs, we now use zjquery.  We also
limit a couple checks to the first call to
`show_empty_narrow_messages`, since it's the same
logic every time.
2019-01-28 07:08:20 -08:00
ss62171
63702d50e6 poll widget: Fix duplicate options bug in poll.
This is a frontend-only change to make it difficult to accidentally
create duplicate options in the poll widget menu.
2019-01-26 15:48:28 -08:00
Tim Abbott
df436a55b4 scripts: Recommend apt update after enabling universe.
One needs to manually do an apt update after add-apt-repository, or it
won't actually work.
2019-01-26 12:29:05 -08:00
Vishnu Ks
5fec84221e stats: Make all time active users graph default.
We now bill by total users, whereas we used to
bill by 15 day actives.
2019-01-26 12:19:59 -08:00
Steve Howell
1228e541d7 dispatch test: Restore 100% line coverage (user_status).
We now have 100% coverage on server_events_dispatch.js.

The last piece were was covering "status_text" updates
in the "user_status" event.
2019-01-26 10:48:57 -08:00
Steve Howell
1279249a09 dispatch tests: Add tests for removing starred flags. 2019-01-26 10:48:57 -08:00
Steve Howell
f7cf759740 dispatch tests: Stop stubbing message_store.
I am trying to use somewhat more realistic data
for data classes in the dispatch tests.  (We still
want to mostly stub UI stuff.)
2019-01-26 10:48:57 -08:00
Steve Howell
4480846aa5 node tests: Do some zrequires higher in dispatch tests. 2019-01-25 16:53:51 -08:00
Steve Howell
17c906d6bb user status: Surface status in the buddy list.
When you hover over a user that has set a user
status, we now show something like "out to lunch."

You can test this in the console by doing:

    user_status.server_update({status_text: 'out to lunch'})

And then hover over your name in the buddy list.
2019-01-25 16:53:51 -08:00
Steve Howell
6de77d30eb node tests: Test starred message updates. 2019-01-25 16:53:51 -08:00
Steve Howell
afe575f02e node tests: Test logo updates. 2019-01-25 16:53:51 -08:00
Steve Howell
dfd52ebe1f node tests: Use actual people in dispatch tests.
The stubs here were kind of unnecessary, as the
real people module is lightweight and data setup
is pretty easy.

In passing I also removed the unnecessary `sed`
abbreviation.
2019-01-25 16:53:51 -08:00
Steve Howell
49b16b5b01 activity: Rename function to redraw_user().
The name `insert_user_into_list` is sort of misleading,
since we are often just redrawing the user's existing
item in the buddy list.

I chose `redraw_user` over `update_user` to emphasize
that we're just going to redraw it with whatever data
has been updated by the callers.
2019-01-25 16:53:51 -08:00
kunal-mohta
b89769420a stream_color: Extend subscribe API to support color attribute.
This fixes an annoying bug where clicking to subscribe to a stream
would change the color shown in the "manage streams" UI immediately
after you click.

Fixes #11072.
2019-01-25 16:44:59 -08:00
Vishnu Ks
ce1db751d0 billing: Make tabs work with back forward buttons. 2019-01-25 16:40:46 -08:00
Vishnu Ks
537b7612cb billing: Remove hash when reloading upgrade page. 2019-01-25 16:40:46 -08:00
Pragati Agrawal
1e811b42ec org settings: Add realm level setting for missed message content in email.
This adds a setting under "Notification" section of
"Organization settings" tab, which enables Organization administrator to
control whether the missed message emails include the message content or
not.

Fixes: #11123.
2019-01-25 14:34:10 -08:00
Vishnu Ks
bec875a9af import realm: Use processes for resizing avatar images.
This should significantly improve the data import performance when
importing large open source realms from Slack.

Fixes #11009.
2019-01-25 12:37:12 -08:00
Puneeth Chaganti
33a322baa2 paste: Hook up the paste handler to the message edit form.
This ensures that any nice pasting features we have in the compose box
also apply to message editing.
2019-01-25 11:40:33 -08:00
Puneeth Chaganti
9c377a05f3 paste: More robust check to verify if clipboard data is an image.
The commit f863a9b567 had modified
jquery.filedrop's paste method to exit early if any of the items in the
clipboardData is of the string kind. The early exit was added to prevent pasting
an image thumbnail for text copied from software like MS Word, instead of
pasting the actual copied text content. When copying an image in a (modern?)
Browser, though, the clipboard seems to contain a html `img` tag item, along
with the actual image file. This resulted in pastes being broken.

This commit modifies the condition checked for the early exit. We now actually
look at the html content in the clipboard to see if it is an `img` tag, in which
case we upload the image, instead of exiting early.

Closes #7130.
2019-01-25 11:40:33 -08:00
Priyanshu Singh
8cf5810fc0 docs: Fix a typo in gsoc-ideas.md. 2019-01-25 11:19:18 -08:00
TharunThomas8
2ebd3f244d left sidebar: Fix scrollbar sticking up few pixels above container.
This is likely not the "right" fix in that it involved a negative
margin, but this does eliminate an annoying visual glitch where the
scrollbar overflows above its container in the left sidebar, without
creating other apparent problems.

Fixes #8731.
2019-01-25 11:17:06 -08:00
Mohit Gupta
42d886a6d5 messages: Add loading spinner for deleting messages.
User was able to click delete button multiple time which could cause
multiple delete requests. This commit disables and hides the delete
message button after the first click and shows a spinner until http
the delete request responds.

Also adds a casperjs test to ensure that spinner becomes visible and
delete button becomes invisible after clicking on delete button for
first time and hides spinner and show delete buttton when message is
deleted.

Fixes: #11219.
2019-01-25 11:07:02 -08:00
Mohit Gupta
c89356fabf messages: Fix 500 error with duplicate delete message requests.
Multiple delete message requests for the same message sometimes caused
a 500 error.  This happened via the normal IntegrityError being thrown
by delete message/archiving code.

This was manually reproduced by adding latency in function
move_messages_to_archive() in retention.py and
delete_message_backend() in views.py.  This addresses the problem by
adding code to handle the exception and throw JsonableError to convert
500 to 400 errors, with an automated test.
2019-01-25 11:07:02 -08:00
Steve Howell
c172001f22 minor: Finish last fix.
See the prior commit.  I missed another info -> status_text
thing.
2019-01-25 07:55:37 -08:00
Steve Howell
45d07e8472 user status: Fix stray "info" reference.
This fixes a section of code that hasn't really
been turned on yet.  We decided to rename
"info" to "status_text", and I apparently missed
this.  We don't have any UI to set these yet,
so it was a harmless bug.

I'll try to get some better test coverage on this
when I tweak the buddy list to show user status.
2019-01-25 07:45:00 -08:00
Tim Abbott
a64c434b9e topics: Fix messages_for_topic to use iexact matching.
This fixes the archive codebase to use our covention of using
case-insensitive matching for message topics.
2019-01-24 17:55:15 -08:00
Eeshan Garg
5057406f16 webhooks/clubhouse: Extract story labels from actions.
Apparently, Clubhouse has two different payloads for story label
changes, one where the label name lives inside the "references"
object, and the other where it lives inside the "actions" object.
Their webhook API is still in beta, so this could just be a bug.
Anyhow, we should support both.
2019-01-24 20:08:59 -03:30
Vaibhav
746870df65 stream settings: Hide creating admin-only streams in members UI.
This commit takes away the ability for non-admin members to create
streams where only admins can post messages by hiding the option from
them.

Fixes #11290.
2019-01-24 10:51:49 -08:00
Vaibhav
268c25e95f streams: Prevent members from creating admin-only streams.
This a check on server side to verify whether the user sending request
to create stream where only admins can post is an admin or not; Raises
a JsonableError when the user is not the realm admin.
2019-01-24 10:51:45 -08:00
Eeshan Garg
2b81d66537 webhooks/clubhouse: Add support for GitHub handler events.
These events are triggered when one has Clubhouse's GitHub
integration and custom event handlers set up.
2019-01-24 10:01:17 -08:00
Steve Howell
513d666ba1 user status: Add frontend data layer for "status_text".
This sets up the frontend to handle "status_text" data like
"out to lunch" or "in a meeting".
2019-01-24 09:46:35 -08:00
Steve Howell
0ef5d1f9c8 user status: Add "status_text" support in the backend.
You can now pass in an info field with a value
like "out to lunch" to the /users/me/status,
and the server will include that in its outbound
events.

The semantics here are that both "away" and
"status_text" have to have defined values in order
to cause changes.  You can omit the keys or
pass in None when values don't change.

The way you clear info is to pass the empty
string.

We also change page_params to have a dictionary
called "user_status" instead of a set of user
ids.  This requires a few small changes on the
frontend.  (We will add "status_text" support in
subsequent commits; the changes here just keep
the "away" feature working correctly.)
2019-01-24 09:46:35 -08:00
Steve Howell
ac861f2b7d user status: Restructure code.
We now have single function that handle both away
and not-away.

This refactoring sets us up to piggyback "info" more
easily onto status updates.

The only thing that changes here is that we don't
delete database rows any more when users revoke
their away status.  Instead we just set the status
to NORMAL.
2019-01-24 09:46:35 -08:00
Steve Howell
7e904c3a1a user status: Add status_text field to the database.
The status_text field will be something like "out to lunch."
2019-01-24 09:46:35 -08:00
Tim Abbott
8b1591f263 settings: Migrate test settings to modern postgres backend name.
This should have no effect; it's just
the missing remainder of 555d5b4dc6.
2019-01-23 17:08:24 -08:00
sameerchoubey
d4cd789213 webhooks/stripe: Add support for remaining payout events.
This adds support for payout events to the Stripe
intergration.
2019-01-23 21:29:40 -03:30
kunal-mohta
c07f85250d messages: Extend do_delete_message to do_delete_messages.
do_delete_message has been renamed to do_delete_messages and all
occurrences of the function replaced with the appropriate new version.
2019-01-23 16:49:12 -08:00
kunal-mohta
67f2533ba3 messages: Rename do_delete_messages to do_delete_messages_by_sender. 2019-01-23 16:49:12 -08:00
Puneeth Chaganti
382d3085c4 api_docs: Document is_guest field in the get_members API. 2019-01-23 16:04:16 -08:00
Hemanth V. Alluri
10211e7565 refactoring: Remove unnecessary _allow_only_listed_keys in test_events.
When I was initially writing the tests to solve issue #10131 in PR
2 schema checkers as I modified the code to send the rendered_value
only when required.

When I was using just 1 schema checker shared between two code paths,
we needed _allow_only_listed_keys. But after shifting to 2 schema
checkers for the two different cases, we no longer needed that flag,
and it's better to remove it for a stronger check.
2019-01-23 13:12:50 -08:00
Tim Abbott
19a4c6de6a docker: Fix Docker development environment unicode handling.
Fixes #11323.

Thanks to xiamingplus for the report and debugging.
2019-01-23 11:05:58 -08:00
Tim Abbott
68552c31cb Revert "puppet: Increase process listening count for uwsgi."
This reverts commit ccce83d0f0.

This needs sysctl changes as well.
2019-01-23 11:02:14 -08:00
Steve Howell
01d9a3b02c quote/reply: Leave message intact for IE/Chrome.
We had a bug where if you started typing a message
and then used quote/reply (after the fact), we
would overwrite the user's original message.

The bug was kind of subtle--the internal call
to "respond" to the message would select the message
text, and then `smart_insert` would replace the
selection, unless it was Firefox.

Note that we now also allow you to cross-post
replies, which is a plausible scenario, although
possibly unintentional at times, too.  I'm erring
on the side of giving the user control here, but
I'll add a warning in the next commit.  Our compose
fade feature should also prevent unintentional
mixes here, too.
2019-01-23 10:57:40 -08:00
Steve Howell
664ee8d017 quote/reply: Dedup some logic with replace_content().
We often need to go to the server to get raw content.
The exceptions are messages for which we've already
fetched the raw content for some other reason (maybe
a previous quote-and-reply) or which are locally echoed.

Whether we can get the raw content locally or from
the server, the replace_content() logic is the same.
2019-01-23 10:57:40 -08:00
Tim Abbott
ccce83d0f0 puppet: Increase process listening count for uwsgi.
The default limit is too low for situations right around a server
restart when there might be a large burst of connections.
2019-01-23 10:34:01 -08:00
Eeshan Garg
9cdcfad920 pypi: Upgrade to release 0.5.8. 2019-01-22 22:49:51 -03:30
Vishnu Ks
8f3a0927c3 lint: Ban color names in CSS.
We already lint using HSL rather than RGB consistently.
2019-01-22 15:33:18 -08:00
Rohitt Vashishtha
f1ae0e2e94 docs: Do not indicate that Bugdown is an extension.
Also fix minor typos and formatting.
2019-01-22 15:28:08 -08:00
Rohitt Vashishtha
0451c42e5c minor: Add test for mentions using silent syntax inside quotes. 2019-01-22 15:28:08 -08:00
Steve Howell
8aee6a1dd7 poll widget: Add some keyboard support.
We support enter/ESC for our input fields.

You still need to use the mouse to vote.
2019-01-22 10:27:39 -08:00
Steve Howell
bacf896228 poll widget: Clean up code and add edit controls.
NOTE: If you revert this commit, you want to revert
the immediately prior commit as well.  The history
is that Ishan made some improvements to the widget,
but there were some minor bugs.  I decided not
to squash the commits together so that the git
history is clear who did what.  (In particular, I
want questions about the JS code to come to me if
somebody does `git blame`.)

Anyway...

This is a fairly significant rewrite of the polling
widget, where I clean up the overall structure of
the code (including things from before the prior
fix) and try to polish the prior commit a bit as
well.

There are a few new features:

    * We tell "other" users to wait for the poll
      to start (if there's no question yet).
    * We tip the author to say "/poll foo" (as
      needed).
    * We add edit controls for the question.
    * We don't allow new choices until there's
      a question.
2019-01-22 10:27:39 -08:00
ishanrai05
85535ae09c poll-widget: Change "Edit question" UI to edit-pencil button.
This changes the "Edit question" UI to be just an edit-pencil button
rather than a large "Edit question" button for a poll.
Fixes part of #11010.
2019-01-22 10:27:39 -08:00
Hemanth V. Alluri
6c18ca9cac validators: Add optional keys feature to check_dict and check_dict_only.
along with the `required_keys` argument an additional `optional_keys`
argument can be passed to both `check_dict` and `check_dict_only`.
Fixes #10892.
2019-01-22 10:03:21 -08:00
Eeshan Garg
ac86074869 api_docs: Suggest using call_endpoint for undocumented endpoints. 2019-01-22 07:37:56 -08:00
Rishi Gupta
ad7a7b246e billing: Move license management from CustomerPlan into its own table. 2019-01-19 16:00:44 +05:30
Rishi Gupta
7958ac96a8 billing: Use CASCADE instead of models.CASCADE in models.py.
models.CASCADE will make lines too long in models we're about to add.
2019-01-18 11:46:17 +05:30
Rishi Gupta
112eb01728 billing: Remove PLAN_NAMES and other legacy code. 2019-01-18 11:46:17 +05:30
Rishi Gupta
267dd00a05 billing: Set loglevel for stripe package in tests. 2019-01-18 11:46:17 +05:30
Harshit Bansal
2944075f70 lint: Respect --force flag while running mypy. 2019-01-17 10:34:43 -08:00
Shubham Jadon
2900537ffa settings: Improve set of icons for 'organization settings'.
Fixes #11280.
2019-01-17 10:29:49 -08:00
Shubham Dhama
9e3423129b invite: Clean error handling and use ui_report.
This also fixes few unusual UI issues like an invitation got failed when
certain emails can't be invited then the error box is left with "warning"
even when next request got succeed and another case when invitation got
succeed after failing it's still reported with "alert-error" class alert
banner.
2019-01-17 10:28:59 -08:00
Shubham Dhama
93ddf2ca37 ui_report: Remove now redundant type argument from .message().
It's no longer used, as can be seen in
2d52463b61, in past we use `type` for
specifiying whether status is 'subscriptions-status' or else, which isn't
used now, hence `type` is removed here.
2019-01-17 10:28:59 -08:00
Shubham Dhama
09ab874642 Revert "invite: Fix non-admins inviting new users."
This reverts the temporary fix done in commit
46f4e58782 and replaced it with the fix that
non-admins should be able to see a dropdown to select a non-admin type of
invited user i.e. normal member or guest user.
2019-01-17 10:28:59 -08:00
Harshit Bansal
fcf2ffe8db registration: Populate LDAP users using invitation information.
Fixes: #11212.
2019-01-17 10:16:48 -08:00
Harshit Bansal
3e3d8527b0 tests: Use init_fakeldap() in test_signup.py. 2019-01-17 10:16:48 -08:00
Harshit Bansal
47b5f9a4a3 ldap: Don't ask users to create password when invited. 2019-01-17 10:16:48 -08:00
Harshit Bansal
dc1fd61adf registration: Don't remove LDAP populated full name.
This commit fixes a bug that caused:
1: A valid full name on an onboarding form to be cleared after an
invalid submission.
2: Incorrectly cleared name populated from LDAP which was janky from
UX perspective.

Ideally we should disable name change for LDAP as next login
will overwrite any changes but I think that can be done in a
separate PR.

Fixes: #10867.
2019-01-17 10:16:48 -08:00
Harshit Bansal
356c5bfb0e dev_ldap: Make userPassword a multi-value attribute.
`fakeldap` assumes every attribute to be a multi-value attribute
while making comparison in `_comapare_s()` and so while making
comparisons for password it gives a false positive. The result
of this was that it was possible to login in the dev environment
using LDAP using a substring of the password. For example, if the
LDAP password is `ldapuser1` even entering `u` would log you in.
2019-01-17 10:16:48 -08:00
Eeshan Garg
3c4e3ddcdb pypi: Upgrade to release 0.5.7. 2019-01-16 21:27:50 -03:30
Rohitt Vashishtha
96aa1d4b37 markdown: Reduce mentions inside blockquotes to silent-mentions.
On the backend, we extend the BlockQuoteProcessor's clean function that
just removes '>' from the start of each line to convert each mention to
have the silent mention syntax, before UserMentionPattern is invoked.

The frontend, however, has an edge case where if you are mentioned in
some message and you quote it while having mentioned yourself above
the quoted message, you wouldn't see the red highlight till we get the
final rendered message from the backend.

This is such a subtle glitch that it's likely not worth worrying about.

Fixes #8025.
2019-01-16 16:08:37 -08:00
Rohitt Vashishtha
988af1c803 markdown: Use silent mentions in Notification Bot messages.
Messages converted:
- new stream
- rename stream
- new user signup
2019-01-16 16:01:06 -08:00
Rohitt Vashishtha
f993fdd480 markdown: Add _@**Name** syntax for silent mentions.
These mentions look like regular mentions except they do not
trigger any notification for the person mentioned. These are
primarily to be used when you make a bot take an action and
the bot mentions you, or when you quote a message that mentions
you.

Fixes #11221.
2019-01-16 16:01:06 -08:00
Tim Abbott
5fd43fcf56 zoom: Fix coverage of new zoom error handling code path. 2019-01-16 15:58:26 -08:00
Tim Abbott
1660856bf5 zoom: Fix handling of 201 status codes from zoom API.
Apparently, zoom's API will (sometimes?) return a 201 (not 200)
created in response to the API request to create a call.  We fix this
by using the proper requests check for whether or not the request
failed.
2019-01-16 15:37:06 -08:00
Tim Abbott
7824ce32a0 docs: Advertise HipChat/Slack import tools in installer docs.
This should help avoid confusion about when to use the import tools.
2019-01-16 15:15:01 -08:00
Tim Abbott
f9b60b4803 docs: Update some notes about Tornado scalability. 2019-01-16 11:26:57 -08:00
Adarsh Patel
5050b595a0 api docs: Fix showing correct link to install Python bindings.
We just make the Python tab the default first tab, which is clearer anyway.

Fixes #9575.
2019-01-16 10:05:25 -08:00
Harshit Bansal
2dc500b11e tests: Fix tests broken in previous commit and add some new ones.
This commit fixes some tests broken in commit
32aa4e02ca.
It also adds some tests for full name mapping in the registration
flow using LDAP.
2019-01-16 09:45:51 -08:00
Harshit Bansal
5f76a65b1d emoji: Make unicode/span emojis more accessible.
This commit adds `aria-label="<title_text>"` and `role="img"` to
the generated HTML.

Fixes: #5975.
2019-01-16 09:07:19 -08:00
Harshit Bansal
0051ca5db6 markdown: Extract make_emoji_span(). 2019-01-16 09:07:19 -08:00
Harshit Bansal
32aa4e02ca registration: Fix full_name mapping in LDAP registration flow.
We forgot to change this part of codebase when introduced changes
to allow split full name mapping in LDAP.
2019-01-16 08:50:21 -08:00
Harshit Bansal
4ec82b28f7 auth: Convert get_mapped_name() in LDAP backend to a class method. 2019-01-16 08:50:21 -08:00
Anders Kaseorg
5ba84d75ce create-zulip-admin: Fix shell quoting.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-16 08:46:50 -08:00
Anders Kaseorg
981f09d950 terminate-psql-sessions: Fix shell and SQL quoting.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-16 08:46:50 -08:00
Anders Kaseorg
c0792808e2 deliver_email, deliver_scheduled_messages: Remove lock file.
Tim believes it’s useless.

https://github.com/zulip/zulip/pull/11285#discussion_r248110926

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-15 16:56:49 -08:00
Anders Kaseorg
0a8598ce65 feedback: Generate the ticket number from the message ID.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-15 16:56:49 -08:00
Tim Abbott
dfaa2e481d import: Log a warning when avatars can't be thumbnailed.
This fixes a potential crash in the import tool if a single user has a
broken avatar image.
2019-01-15 16:48:04 -08:00
Anders Kaseorg
25d6107a4f docs: Avoid hardcoded /tmp paths in miscellaneous documentation.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-15 16:16:12 -08:00
Anders Kaseorg
b7179f8f79 webhooks/zabbix: Don’t write unused /tmp/payload.txt file.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-15 16:13:30 -08:00
Anders Kaseorg
e5bf0c0a69 event_queue: Avoid hardcoded paths in /var/tmp.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-15 16:12:05 -08:00
Anders Kaseorg
b37ed12df2 export: Let mkdtemp pick its favorite directory.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-15 16:08:48 -08:00
Anders Kaseorg
79d888223f profiling: Use mkstemp for profile.data filename.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-15 16:08:48 -08:00
Anders Kaseorg
601b5eb036 export: Avoid hardcoded paths in /tmp.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-15 16:05:51 -08:00
Anders Kaseorg
f3c9b87c30 test-locked-requirements: Avoid hardcoded paths in /var/tmp.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-15 16:05:51 -08:00
Anders Kaseorg
b4e1403cf9 test-install: Avoid hardcoded paths in /tmp.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-15 16:05:51 -08:00
Anders Kaseorg
c17ddceeae test-emoji-name-scripts: Avoid hardcoded paths in /var/tmp.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-15 16:05:50 -08:00
Anders Kaseorg
df7b63cd5e tools: Remove check-css.
As of commit 0042694e24 (#10017), this
is unused.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-15 16:05:50 -08:00
Anders Kaseorg
f099fd9e28 pretty_print: Replace hardcoded path in /var/tmp with a pipe.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-15 16:00:48 -08:00
Anders Kaseorg
d3dff61016 .travis.yml: Use /nonexistent instead of /tmp/nowhere.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-15 16:00:48 -08:00
Anders Kaseorg
6678a95b20 test-queue-worker-reload: Use a pipe rather than polling a log file.
This avoids unnecessary polling delays, quadratic string operations,
and hardcoded paths in /tmp.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-15 16:00:48 -08:00
Anders Kaseorg
19429c3ad7 test-run-dev: Use a pipe rather than polling a log file.
This avoids unnecessary polling delays, quadratic string operations,
and hardcoded paths in /tmp.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-15 16:00:48 -08:00
Yashashvi Dave
54d92446db user settings: Re-open settings after closing profile preview.
Users can preview their profile from user settings. If user
open preview profile modal from user settings, then closing
preview profile modal should redirect them to settings modal
again (since probably they want to keep editing).

This commit fixes above issue.
2019-01-15 15:42:26 -08:00
Yashashvi Dave
0949419f68 user settings: Change width of "Preview profile" button. 2019-01-15 15:38:25 -08:00
Yashashvi Dave
b53857b168 settings: Add admin UI for editing users' custom profile fields.
This commits add UI which will allow admin to edit every user's
custom profile field data from admin settings.

Fixes #10161
2019-01-15 15:34:35 -08:00
Hemanth V. Alluri
7d07dc66fd custom profile fields: Fix error handling for admin clearing values.
This commit fixes an error in the logic for allowing admins to edit any
user's CPF (custom profile field) values. The logic allowing users to
edit their own CPF values is however sound. What happens is that of all
the CPF types, for "choice fields" as well as "URL" and "date fields",
when the value is reset/deleted/cleared by the admin in the Admin UI
(organization settings), the frontend would send a null (empty string)
value to the backend for that custom profile field (as this is, after
all, the new value in this case). This would then triggers the backend
validators to return an error message.

We fix this by using the method check_remove_custom_profile_field_value,
that both code paths (user editing their own CPFs and admin editing a
user's CPF) can call.
2019-01-15 15:29:02 -08:00
Hemanth V. Alluri
716bcad393 custom profile fields: Extract check_remove_user_custom_profile_value.
This moves the logic for deleting the user's custom profile field
value in the remove_user_custom_profile_data view function to a method
named check_remove_user_custom_profile_value in actions.py, so that we
can reuse it in the next commit.
2019-01-15 15:28:16 -08:00
Jeswin
03d66abd9e settings: Add success messages for deactivation/reactivation.
This adds the same style of "Saving"/"Saved" loading spinners we use
elsewhere in our settings.

Tweaked significantly by tabbott to fix issues with the notifications
being on the wrong screen for reactiving/deactivating users; this was
done by introducing the get_status_field helper function and using it
everywhere.
2019-01-15 15:05:41 -08:00
Jeswin
060f40c356 settings: Use standard error handling in settings/invites.
Changed the error message element from organization-status to
an alert-notification block within this page.
2019-01-15 14:52:31 -08:00
Jeswin
17a5d6c1f7 settings: Improve status messages styling on "users" changes.
The legacy "Updated Successfully" message shown after saving changes,
is removed, and replaced with our standard "Saving" spinner and
animation.

Fixes: #11177.
2019-01-15 14:50:17 -08:00
Tim Abbott
c70face2dc css: Make message editing controls look like compose controls. 2019-01-15 12:05:02 -08:00
Abhinav Singh
e6493ef0c8 emoji: Add support for using emoji picker in message edit.
This code will correctly render emoji to the message textarea based on
whether emoji was selected from message composition form or message
edit form.

Fixes part of #11188.
2019-01-15 12:00:02 -08:00
Tim Abbott
a92a5f19f0 email_mirror: Handle case where email body is empty.
This provides logging that makes clear this situation is a user error.
2019-01-15 11:30:15 -08:00
Tim Abbott
14b2ed649b email_mirror: Don't email errors for emails missing body type.
This lowers the severity on content type errors to not send spammy
error emails, and instead just log a warning.
2019-01-15 11:30:15 -08:00
Tim Abbott
164adcd433 user groups: Fix membership checks for unknown user groups.
AFAIK I should this never fail, hence the blueslip.error line.  But it
is failing in practice when rendering user groups after looking them
up by ID, and the error handling should definitely be softer.
2019-01-14 16:00:06 -08:00
Harshit Bansal
50ef91bb08 scripts: Add argparse option to restart-zerver for --fill-cache.
Nowm unless you specify `--fill-cache`, memcached caches will not be
pre-filled after a server restart. This will be helpful when someone
is in a hurry (e.g. if the server is down right now, or if he/she
testing a configuration change in a newly setup server), it's best to
just restart without pre-filling the cache.

Fixes: #10900.
2019-01-14 15:20:01 -08:00
Tim Abbott
46f4e58782 invite: Fix non-admins inviting new users.
Our recent work on inviting users as guests accidentally set the
invite_as argument in a way that would fail for non-admin users.

Fixes #11283, fixes #11255.
2019-01-14 15:09:20 -08:00
Adarsh Patel
c886b53a3d help: Fix rendering correct OS-specific docs.
This fixes #11279, a bug where the OS-specific docs did not correctly
select the Uuser's OS tab as active when clicked from the left sidebar
of /help/.
2019-01-14 14:34:04 -08:00
Adarsh Patel
f7b18bf68c portico: Deduplicate code for detecting browser OS.
We apparently had two copies of this in different files.
2019-01-14 14:33:22 -08:00
Aditya Bansal
4e4c33fee2 reminders: Make reminders setup work only for Streams.
We make this change because setting up reminders in PM's didn't
play really well with our current infrastructure. Basically the
reminder messages from the bot can't appear in the same narrow as
that of a PM between two people and therefore we disable it.
Though we make an exception here where a person wants to set up
reminder for himself.
2019-01-14 12:23:48 -08:00
Aditya Bansal
bb7c9a544b reminder.js: Refactor to make notify_above_composebox conditional.
We do this because now we send a message to stream if a reminder
is set and won't need the notification above the compose box saying
that we set a reminder. We would still need that notifications for
the send later feature so we make the construct conditional.
2019-01-14 12:11:27 -08:00
Aditya Bansal
b2fa7a2293 popovers: Add a require for confirmDate plugin. 2019-01-14 12:11:27 -08:00
Aditya Bansal
aae90d5d6b deliver_scheduled_messages: Make notification bot deliver reminders.
We do this since we are yet to figure out how the entire realm
internal bots scenerio should work and therefore for the timming
we will use notification bot to deliver the reminders.
2019-01-14 12:11:27 -08:00
Hemanth V. Alluri
58fa142c7d subscriptions: Update the color validator to check_color.
Previously, the subscription color attribute had a validator of
check_string, but this is insufficient. Hence this commit update the
validator used to check_color. Fixes #11268.
2019-01-14 10:16:42 -08:00
Hemanth V. Alluri
1f0d319f9f validators: Add a validator called check_color for hex color codes. 2019-01-14 10:16:42 -08:00
Tim Abbott
0c5f4d43f9 ldap: Avoid spammy log messages from fakeldap as well. 2019-01-14 09:52:25 -08:00
Harshit Bansal
00ca98348a ldap: Shorten the name of logger of sync_ldap_user_data command. 2019-01-14 09:50:30 -08:00
Harshit Bansal
d2b7a24c26 ldap: Adjust django_auth_ldap settings to avoid spammy log messages. 2019-01-14 09:50:30 -08:00
Harshit Bansal
5037b2c5c4 management: Fix a bug in parser of sync_ldap_user_data command.
After recent changes for extending the `sync_ldap_user_data` to
update a single user, it was not running without specifying any
arguments.
2019-01-14 09:50:30 -08:00
Vaibhav
ac4aa16962 markdown preview: Fix code style for preview in night mode.
When in night mode, `code` style was still the same as in the light mode;
The fix is for the same.

Fixes #11269.
2019-01-13 23:14:19 -08:00
Adarsh Patel
aad010fd27 docs: Update screenshot-and-gif-software.
This adds a few more standard screenshot capture tools.
2019-01-13 20:21:58 -08:00
Eeshan Garg
e9e075f6e8 webhooks/pagerduty: Stop sending raw payloads in notifications.
For unsupported or invalid payloads, we should just raise the
UnexpectedWebhookEventType exception and let our logging system
take care of recording the payload that caused the error.
2019-01-13 19:09:11 -08:00
Eeshan Garg
a1994122ca webhooks/pagerduty: Refactor and make minor improvements.
This commit improves a couple of things:

* All of the message templates are now at the top, a convention
  we follow in a lot of our webhooks.
* Messages are not prefixed with any emojis. We don't do this in
  any of our other webhooks. Plus, the emojis were outdated.
* Remove some superfluous code.
* Use ```quote <quote goes here> ``` style formatting for
  quoted text instead of the `>` character.
2019-01-13 19:09:11 -08:00
Eeshan Garg
74f0d32a21 webhooks/pagerduty: Support events from webhook v2.
This commit only adds support for the four events that have sample
payloads provided for them on the Pagerduty developer website.
Support for the remaining events will be added in subsequent
commits, as we get access to more sample payloads.
2019-01-13 19:09:11 -08:00
Harshit Bansal
71761bc2da ldap: Add a setting to automatically deactivate non_matching users.
Fixes: #11151.
2019-01-13 19:04:09 -08:00
Harshit Bansal
6797dea6c3 auth: Add tests for ZulipLDAPUserPopulator.
Fixes: #11041.
2019-01-13 18:51:50 -08:00
Harshit Bansal
05ad6a357b ldap: Add support for two field mapping of full name.
Tests for `sync_full_name_from_ldap()` are pending and will be added
in a separate commit.

Fixes: #11039.
2019-01-13 18:51:50 -08:00
Harshit Bansal
348f370b79 management: Extract sync_user_from_ldap(). 2019-01-13 18:51:50 -08:00
Harshit Bansal
6e20a9a419 ldap: Extract init_fakeldap(). 2019-01-13 18:51:50 -08:00
Harshit Bansal
e09ef69a8d management: Extend sync_ldap_user_data to allow update of a single user. 2019-01-13 18:51:50 -08:00
Harshit Bansal
4d68abd54f settings_account: Show error on failed avatar upload. 2019-01-13 08:17:31 +00:00
Harshit Bansal
d5fc02557c settings_org: Fix an incorrect jquery selector. 2019-01-13 08:17:30 +00:00
Harshit Bansal
45d50715c5 uploads: Return a HTTP 400 error for a decompression bomb attack.
Fixes: #11215.
2019-01-13 08:17:24 +00:00
Harshit Bansal
22b67a5207 uploads: Tag error messages for translation. 2019-01-13 06:24:09 +00:00
Tim Abbott
e29533df0f emails: Fix duplicate <html> blocks in missed-message emails.
Apparently, the missed-message templates have a slightly different
structure from our other email templates, which triggered a latent,
subtle bug in inline-email-css's effort to remove duplicate <html>
blocks from emails that had been generated by premailer.  Fix this
bug, and add appropriate assertions to prevent similar issues in the
future.

Fixes #11249.
2019-01-11 14:23:30 -08:00
Vaibhav
4219cc497d tooling: Move confirmation_key view to development only views.
Previously, zerver.views.registration.confirmation_key was only
available in development; now we make that more structurally clear by
moving it to the special zerver/views/development directory.

Fixes #11256.
2019-01-11 12:45:21 -08:00
Vaibhav
b94892d633 tooling: Move email_log.py to development only views.
Some urls are only available in the development environment
(dev_urls.py); Corresponding views (here email_log.py) is moved to the
new directory zerver/views/development.

Fixes #11256.
2019-01-11 12:45:02 -08:00
Rohitt Vashishtha
b7c5ae7bca dependencies: Upgrade markdown from 2.6.11 -> 3.0.1.
This is a major upgrade, and requires some significant compatibility
work:
* Migrating the pattern-removal logic to use the Registry feature.
* Handling the removal of positional arguments in markdown extensions.
* Handling the removal of safe mode.
2019-01-11 11:40:18 -08:00
Eeshan Garg
73eed42b3c webhooks/clubhouse: Extract story labels from references.
It looks like Clubhouse has moved where they store the label name
from the "actions" list to the "references" list.
2019-01-10 20:00:30 -08:00
Raymond Akornor
254bf4c08f send_email: Add support for passing language into send_future_email.
This adds language paramater to send_future_email. As a result, this
properly internationalizes invitation reminder emails, by passing
correct language into send_future_email.

Fixes #11240.
2019-01-09 17:47:58 -08:00
Anders Kaseorg
b9f7b08af2 setup_path_on_import: Check that the virtualenv is compatible.
The site_packages variable points to (e.g.)
zulip-py3-venv/lib/python3.4/site-packages.  If that doesn’t exist,
we’re probably running the wrong Python version.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-09 17:32:09 -08:00
Anders Kaseorg
7a58f574bf setup_path_on_import: Skip activate_this if already activated.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-09 17:32:07 -08:00
Anders Kaseorg
2ad1a27b28 create-production-venv: Remove Python 2 support.
We still create a Python 2 virtualenv for thumbor but that’s
separate (/srv/zulip-thumbor-venv from
scripts/lib/create-thumbor-venv).

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2019-01-09 17:32:05 -08:00
Tim Abbott
4c603990d2 hipchat: Use HTML2Text for the content.
While the result is by no means perfect, it's significantly cleaner
than what we had before this.
2019-01-09 16:59:45 -08:00
Tim Abbott
53436766c1 hipchat: Improve import of public room subscribers.
Now, if you pass an api_key, we'll initialize the public room
subscribers to be whatever they were at the time the import happened.

Also, document the situation on the caveats section.
2019-01-09 16:50:00 -08:00
Tim Abbott
035138dd98 hipchat: Refactor code for building subscriptions.
This moves the filtering of invite-only into the caller, and also
adjusts the indentation.
2019-01-09 16:50:00 -08:00
Tim Abbott
c34a8f2e69 hipchat: Fix importing of private messages.
Apparently a stupid typing issue meant that we broke this a few weeks
ago.
2019-01-09 16:50:00 -08:00
Vaibhav
34ef37b1fe portico: Fix overlap of server and frontend errors.
Clears the errors received from the server whenever there is a chance of
overlap among them.

Fixes #10831.
2019-01-09 10:56:17 -08:00
Harshit Bansal
fbaa497dbb registration: Make an incorrect exception check more precise.
In this case, we should be checking for the precise subclass for
readability.
2019-01-09 10:53:12 -08:00
Harshit Bansal
a55e101bef ldap: Allow users to login with just LDAP username.
We had an inconsistent behavior when `LDAP_APPEND_DOMAIN` was set
in that we allowed user to enter username instead of his email in
the auth form but later the workflow failed due to a small bug.

Fixes: #10917.
2019-01-09 10:53:12 -08:00
Steve Howell
475108b784 outgoing webhooks: Set a Zulip-specific user-agent.
This now sets the user-agent to something like:

    ZulipOutgoingWebhook/2.0

(It uses the current ZULIP_VERSION.)

Before this change, the user-agent would be
something like `python-requests/2.18.4`.

Fixes #10741
2019-01-09 10:45:46 -08:00
Tim Abbott
a3ac94fa26 management: Support multi-line usage in all management commands. 2019-01-09 10:39:29 -08:00
Mateusz Mandera
3e5f89f2fe email_mirror: Add send_to_email_mirror management command.
Closes #11195. We add a management command to allow us to send emails
to the email mirror directly. The command doesn't require any
configuring of email sending or receiving for the email mirror,
it passes the emails directly using the process_message function.
2019-01-09 10:36:16 -08:00
Mateusz Mandera
726767ece5 dev_settings: Remove port number from EMAIL_GATEWAY_PATTERN.
EMAIL_GATEWAY_PATTERN used to contain a port number in dev setttings
which made it impossible for the email mirror to accept emails sent to
it.
2019-01-09 10:19:24 -08:00
Steve Howell
82e453d9fe ui: Fix scrollbar regressions.
In between releases, the following commit introduced
a bug where we agressively scroll to the top every
place we call `ui.update_scrollbar`:

    092b73d0b7

The main symptoms were that the left and right sidebars
would go to the top for things like selecting a topic,
getting activity updates from the server, and resizing
the window.  It was very jarring.

The recent commit looked innocuous--the root of the problem
was the original API expressed an intent to scroll to the
top, but didn't actually do it, so it was a bug in hiding.

There are **some** occasions where it's actually appropriate
to scroll to the top, mostly around search filtering, and
in those places we now call the new `ui.reset_scrollbar`
function.

This is a bit of an emergency fix, so particularly with
the settings stuff, we may get more reports of glitches here.

The important thing here is that you almost never want to
reset the scrollTop for sidebars.
2019-01-09 09:15:45 -08:00
Tim Abbott
40884dbb1d docs: Document active directory values for AUTH_LDAP_USER_SEARCH.
Fixes #10019.
2019-01-08 16:28:51 -08:00
Eeshan Garg
884b67bea7 bot_lib: Raise exception when PM recipient list is empty.
We need to explicitly check for empty recipient lists in
send_message to ensure that internal_send_huddle_message doesn't
call Addressee.for_private with an empty recipient list.
2019-01-08 16:19:20 -08:00
Eeshan Garg
020f2d0db5 send_message_backend: Add support for recipient user IDs.
Note that create_mirrored_message_users has not been updated to
use user IDs.

Tweaked by tabbott to add a unit test for the huddle case as well.
2019-01-08 16:17:20 -08:00
Eeshan Garg
060de48800 mypy: Accept integer user IDs in handle_deferred_message. 2019-01-08 19:08:49 -03:30
Eeshan Garg
82ace8ccc8 addressee: Add support for user IDs to Addressee.legacy_build().
This commit is a part of our efforts surrounding #9474.
2019-01-08 19:08:49 -03:30
Eeshan Garg
b3e8e36a8d messages: Check for empty recipient lists in Addressee.
The check for empty recipient lists (the "message_to" argument)
does not belong in check_message. As we implement support for
sending messages by user IDs (see #9474), we will be extending
much of the existing code in Addressee.legacy_build that validates
recipient lists. Therefore, Addressee.legacy_build is a much more
apt area to check for empty recipient lists.

Also, Addressee.for_private and Addressee.for_user_ids also need
to do their own validation, since not everything goes through
Addressee.legacy_build. It is okay to simply throw a 500 in these
cases because we expect that callers will be doing their own
validation for calls that don't go through Addressee.legacy_build().

This commit is a part of our efforts surrounding #9474.
2019-01-08 19:08:49 -03:30
Eeshan Garg
2f634f8c06 backend: Support user IDs for sending typing notifications.
This is a part of our efforts surrounding #9474.
2019-01-08 19:08:49 -03:30
Eeshan Garg
8f1dba6aad extract_recipients: Support user IDs.
This is a part of our efforts surrounding #9474.
2019-01-08 19:08:49 -03:30
Tom Daff
fbffbf8ef0 puppet/nginx: Update to recommended SSL ciphers.
Update the list of ciphers that nginx will use to the current
Mozilla recommended ones.

These are Intermediate compatibility ones suitable for clients
running anything newer than Firefox 1, Chrome 1, IE 7, Opera 5
and Safari 1. Modern compatibility is not suitable as it excludes
Andriod 4 which is still seen on ~1% of traffic.

More info: https://wiki.mozilla.org/Security/Server_Side_TLS
2019-01-08 14:19:49 -08:00
Vishnu Ks
c263674507 billing: Add node test for billing.js. 2019-01-08 10:47:35 -08:00
Vishnu Ks
b89a10676a billing: Use underscore built in contains function. 2019-01-08 10:47:35 -08:00
Steve Howell
37c78abe14 frontend: Use topic on message.
This seems like a small change (apart from all the
test changes), but it fundamentally changes how
the app finds "topic" on message objects.  Now
all code that used to set "subject" now sets "topic"
on message-like objects.  We convert incoming messages
to have topic, and we write to "topic" all the way up
to hitting the server (which now accepts "topic" on
incoming endpoints).

We fall back to subject as needed, but the code will
emit a warning that should be heeded--the "subject"
field is prone to becoming stale for things like
topic changes.
2019-01-07 19:20:56 -08:00
Tim Abbott
534bf8f806 docs: Make more clear how installing from Git works.
The previous discussion made it sound like this did a development
environment installation.
2019-01-07 19:16:59 -08:00
sahil839
4dcccf32f8 zerver: Add feature for notification at rename of a stream.
Feature of sending notification to the stream using notification bot
is added. user_profile is also passed to do_rename_stream for using
the name of user who renamed the stream in notification.
Notification is sent to the stream using
internal_send_stream_message in do_rename_stream.

Fixes #11034.
2019-01-07 19:13:01 -08:00
rht
3f0bae8c38 puppet: Disable camo when not on Debian. 2019-01-07 18:52:45 -08:00
rht
bf65f86a0b puppet: Abstract out ssl certs and private keys dirs. 2019-01-07 18:52:45 -08:00
rht
91348a6aee create-thumbor-venv: Generalize to CentOS, Fedora, RHEL. 2019-01-07 18:52:27 -08:00
rht
68c20c610e create-production-venv: Generalize to CentOS, Fedora, RHEL. 2019-01-07 18:52:27 -08:00
rht
15763f8545 provision: Include DISTRIB_FAMILY in parse_lsb_release output. 2019-01-07 18:52:09 -08:00
rht
d9ef3fd505 puppet: Manually create ssl-cert group on CentOS to acess ssl private key. 2019-01-07 18:51:39 -08:00
Steve Howell
b3594c984a message scrolling: Fix "Scroll down to view" warning.
We recently added a feature to warn users that they
may need to scroll down to view messages that they
just sent, but it was broken due to various complexities
in the rendering code path.

Now we compute it a bit more rigorously.

It requires us to pass some info about rendering up
and down the stack, which is why it's kind of a long
commit, but the bulk of the logic is in these JS files:

    * message_list_view.js
    * notifications.js

I choose to pass structs around instead of booleans,
because I anticipate we may eventually add more metadata
about rendering to it, plus bools are just kinda brittle.
(The exceptions are that `_maybe_autoscroll`, which
is at the bottom of the stack, just passes back a simple
boolean, and `notify_local_mixes`, also at the bottom
of the stack, just accepts a simple boolean.)

This errs on the side of warning the user, even if the
new message is partially visible.

Fixes #11138
2019-01-07 17:17:55 -08:00
Steve Howell
6f8da1bb27 Refactor: Split up add_messages api.
We now have two functions:

    add_new_messages
    add_old_messages

This is a lot easier on the eyes, and it will also
prevent us from exceeding line length in future commits.

We also remove an unneeded stub in the narrow_activate
tests.
2019-01-07 17:17:55 -08:00
Steve Howell
9a30b51e6e minor: Simplify maybe_add_narrowed_messages.
We eliminate the messages_are_new parameter, which
was always set to `true`.
2019-01-07 17:17:55 -08:00
Steve Howell
9893256668 message_events: Reorganize code to insert new messages.
This commit makes it a bit more explicit about
why we're updating 2 or 3 message lists every time.

It looks funny now to repeat the home-list updates
in both sides of the conditional, but this will be
more obvious in a subsequent commit, where we want
to capture return values from rendering.
2019-01-07 17:17:50 -08:00
Steve Howell
ed0abb8a53 minor: Move code around for setting link id/text/class.
We don't need to compute these vars if we early exit.
2019-01-07 17:11:17 -08:00
Steve Howell
a8fe6a864d message scrolling: Add started_scrolled_up logic.
Figuring out whether we started scrolled up
**BEFORE** rendering is more accurate than trying
to subtract out heights of new messages after
rendering.
2019-01-07 17:11:17 -08:00
Steve Howell
632262e484 message scrolling: Avoid zero-pixel animations.
In a recent commit we allowed for `scroll_amount`
to be zero (as an indirect consequence of letting
`scroll_limit` be zero without early exiting).

See 0f75be3e8e

We want to short circuit the call to
`system_initiated_animate_scroll`, partly to save
unnecessary computation, but in particular to avoid
invoking the suppress-pointer-update logic.
2019-01-07 17:11:17 -08:00
Steve Howell
f1f7f72119 message scrolling: Add visible_bottom to info.
It's convenient to have visible_bottom as well
as top/height, and the extra computation is
trivial (it's just arithmetic, no extra jQuery
involved).

There's some minor cleanup here too.
2019-01-07 17:11:17 -08:00
rht
6c3bb507b0 puppet: Ensure nginx sites-available & sites-enabled dirs exist on CentOS.
These are automatically created on Debian.
2019-01-07 17:09:42 -08:00
Tim Abbott
848b2f687c export: Add support for public-streams-only exports.
Previously, this wasn't an explicit feature of the export tool.

Note that the current version still includes metadata on private
streams and private message recipients, just not their messages.
2019-01-07 16:52:02 -08:00
Tim Abbott
c6371bb3ef export: Add option to upload exports to S3.
This should make it more convenient to operationalize providing
exports from Zulip Cloud.

Fixes #11178.
2019-01-07 15:28:17 -08:00
Eeshan Garg
539e5e5f41 webhooks/jira: Support comment_created event type.
Fixes: #11200
2019-01-07 14:55:12 -08:00
Tim Abbott
0ffc2ce183 push_notifications: Don't rename import for lxml.html.
This is our standard way of writing code.
2019-01-07 13:15:46 -08:00
Tim Abbott
b1cb38e7a0 push_notifications: Remove an unnecessary else clause.
This makes the code a bit cleaner.
2019-01-07 13:15:21 -08:00
Shoumorup
2afdbb139d digest: Fix the styling of /digest page.
This adds a proper template for the /digest page, making it a
reasonable way to view the digest email content for development and
debugging.

Fixes: #11016.
2019-01-07 13:09:29 -08:00
Vishnu Ks
c6352c4d9d version: Bump provision version to facilitate dependency upgrade. 2019-01-07 10:30:49 -08:00
Vishnu Ks
d9781ec46d requirements: Upgrade Sphinx to 1.8.3. 2019-01-07 10:30:49 -08:00
Vishnu Ks
58cf938aa2 requirements: Upgrade Django to 1.11.18. 2019-01-07 10:30:49 -08:00
Vishnu Ks
aea4e014c3 requirements: Upgrade wheel from 0.32.2 to 0.32.3. 2019-01-07 10:30:48 -08:00
Vishnu Ks
2f11c44c34 requirements: Upgrade setuptools from 40.6.1 to 40.6.3. 2019-01-07 10:30:48 -08:00
Vishnu Ks
259f87fcdc requirements: Upgrade yamole from 2.1.5 to 2.1.6. 2019-01-07 10:30:48 -08:00
Vishnu Ks
728b4069f5 requirements: Upgrade twilio from 6.19.2 to 6.22.1. 2019-01-07 10:30:48 -08:00
Vishnu Ks
7f602f41c9 requirements: Upgrade stripe from 2.16.0 to 2.17.0. 2019-01-07 10:30:48 -08:00
Vishnu Ks
95bbcba089 requirements: Upgrade SQLAlchemy from 1.2.14 to 1.2.15. 2019-01-07 10:30:48 -08:00
Vishnu Ks
aaf20d2768 requirements: Upgrade six from 1.11.0 to 1.12.0. 2019-01-07 10:30:48 -08:00
Vishnu Ks
a028fb710b requirements: Upgrade pytz from 2018.5 to 2018.9. 2019-01-07 10:30:48 -08:00
Vishnu Ks
6cbbbbfd5a requirements: Upgrade python-dateutil from 2.6.1 to 2.7.5. 2019-01-07 10:30:48 -08:00
Vishnu Ks
5b7eec3d02 requirements: Upgrade PyJWT from 1.6.4 to 1.7.1. 2019-01-07 10:30:48 -08:00
Vishnu Ks
c1d18c6976 requirements: Upgrade Pygments from 2.2.0 to 2.3.1. 2019-01-07 10:30:48 -08:00
Vishnu Ks
7773a277d9 requirements: Upgrade pyasn1-modules from 0.2.2 to 0.2.3. 2019-01-07 10:30:48 -08:00
Vishnu Ks
39d455e217 requirements: Upgrade pyasn1 from 0.4.4 to 0.4.5. 2019-01-07 10:30:48 -08:00
Vishnu Ks
fdcb55873a requirements: Upgrade Pillow from 5.3.0 to 5.4.1. 2019-01-07 10:30:48 -08:00
Vishnu Ks
6825b9d3b6 requirements: Upgrade pika from 0.11.0 to 0.12.0.
Based on our analysis, the bug that made us uncomfortable with
upgrading to 0.11.2 was fixed in 0.12.0.

Fixes #8466.
2019-01-07 10:29:41 -08:00
Vishnu Ks
c64ad40a04 requirements: Upgrade moto from 1.3.3 to 1.3.7. 2019-01-07 10:26:31 -08:00
Vishnu Ks
2b86e10eda requirements: Upgrade lxml from 4.2.5 to 4.3.0. 2019-01-07 10:26:31 -08:00
Vishnu Ks
fc903e0b0e requirements: Upgrade httplib2 from 0.11.3 to 0.12.0. 2019-01-07 10:26:31 -08:00
Vishnu Ks
7354678215 requirements: Upgrade disposable-email-domains from 0.0.38 to 0.0.39. 2019-01-07 10:26:31 -08:00
Vishnu Ks
261475c2fd requirements: Upgrade cryptography from 2.4.1 to 2.4.2. 2019-01-07 10:26:31 -08:00
Vishnu Ks
110fb7cd7b requirements: Upgrade certifi from 2018.10.15 to 2018.11.29. 2019-01-07 10:26:31 -08:00
Vishnu Ks
e566a450c4 requirements: Upgrade beautifulsoup4 from 4.6.3 to 4.7.1. 2019-01-07 10:26:31 -08:00
Vishnu Ks
13de959121 tools: Add script to automate python dependency upgrade. 2019-01-07 10:25:35 -08:00
Tim Abbott
828577c3b2 email_mirror: Fix parsing of unicode in subject headers.
Previously, we had some hand-written logic for parsing the subject
line of the email's headers and turning it into a Python string using
each of the valid encodings for an email.  That logic was buggy, and
sometimes resulted in a bytes object being passed into the
`send_zulip`, which would eventually throw an exception.

The fix for this is to use the Python standard library make_header
method for handling internationalized email headers.

https://stackoverflow.com/questions/7331351/python-email-header-decoding-utf-8
2019-01-07 10:21:04 -08:00
Marco Burstein
9ddadd39f4 compose: Add support for using Zoom as the video chat provider.
This adds Zoom call properties to the `Realm` model, creates endpoints
for creating calls, adds a frontend and tests.

Fixes #10979.
2019-01-07 10:00:02 -08:00
Akash Nimare
1aab1594e2 settings: Fix alignment of left-side icons in org setting tab.
This fixes a part of #10954.
2019-01-07 09:36:16 -08:00
Eeshan Garg
9c589ac7d9 api docs: Stop mentioning "dev servers" in JS code examples.
Since the Zulip API runs on both developement and production
servers, it is misleading to mention "dev servers" when discussing
zuliprc files.

Also, note that it is better to manually edit all of our JS
examples than to implement macro-like functionality that we use
for our Python examples. For our current purposes, it would be
too much work to build a full-blown testing framework for our
JS code examples just so that we can fix a minor wording issue.

Fixes #10672.
2019-01-07 09:14:25 -08:00
Rishi Gupta
c9cc3ae451 user docs: Make it clearer that you should run HipChat import on master. 2019-01-06 21:24:01 -08:00
Rishi Gupta
cfc1138abc org settings: Improve labels and styling for realm logo/avatar. 2019-01-05 16:26:56 -08:00
Yashashvi Dave
4bfea4cebe subscriptions: Hide add-subs html element if user is guest user.
Guest users can not add subscribers to subscribed or unsubscribed
streams. Therefore hide add-subs html element if current user
is guest user.

Tweaked by tabbott to use the early-return pattern.
2019-01-05 16:24:39 -08:00
Yashashvi Dave
e8fbd855e6 subscriptions: Add tooltip, only subscribers can add user in private stream.
Add explanation in popover on disabled add-subscriptions input elements,
admin can't add subscribers to non subscribed private streams, only
subscribed users can.

Fixes #10593
2019-01-05 16:21:41 -08:00
Yashashvi Dave
7f3724dc5d subscription: Rename add subscription input placeholder.
In stream membership section, rename add subscription input
placeholder to 'Name or email' from 'Email address'.
2019-01-05 16:14:46 -08:00
Mateusz Mandera
87c95c6f41 email_mirror: Strip RE and FWD from email subject.
Fixes part 1 of #10612. We use a regex to remove RE:, FWD: (and similar
variations) from email subjects. Unit test is included, we add
subjects.json in fixtures containing various subjects to try the
stripping on.
2019-01-05 15:59:19 -08:00
Mateusz Mandera
36714342a3 lint: Allow usage of the word subject in test_email_mirror.py. 2019-01-05 15:59:19 -08:00
rht
f2b6a2c68a puppet: Add CentOS version of the command to start supervisor. 2019-01-05 15:57:53 -08:00
rht
39f28a0d0f puppet: Abstract out supervisor service name. 2019-01-05 15:57:53 -08:00
rht
d2069f7720 puppet: Include yum repository for CentOS voyager. 2019-01-05 15:57:45 -08:00
rht
1da17be52a puppet: Ensure supervisord conf.d directory is created on CentOS. 2019-01-05 15:55:43 -08:00
rht
902bb7a80c puppet: Add CentOS version of supervisor conf.d path. 2019-01-05 15:54:21 -08:00
rht
6b0bf828f7 puppet: Add CentOS version of supervisord.conf path. 2019-01-05 15:49:03 -08:00
rht
9ee2ee046a puppet: Use systemctl instead of pg_ctlcluster on CentOS. 2019-01-05 15:49:03 -08:00
rht
2bcf83d940 puppet: Add CentOS packages to static_asset_compiler.pp. 2019-01-05 15:49:03 -08:00
rht
071e32985c puppet: Generalize redis.conf path to CentOS. 2019-01-05 15:49:03 -08:00
rht
acaf001cdd puppet: Group commonly reused variables into zulip::common. 2019-01-05 15:49:03 -08:00
rht
766ff38586 puppet: Abstract out nagios plugins directory. 2019-01-05 15:49:03 -08:00
rht
b22f6c6a99 puppet: Abstract out postgresql package. 2019-01-05 15:49:03 -08:00
rht
43fdb00fc7 puppet: Abstract out nginx package. 2019-01-05 15:49:03 -08:00
rht
5424fca168 puppet: Add CentOS packages to postgres_appdb_base.pp. 2019-01-05 15:49:03 -08:00
rht
d8a081b94c setup-yum-repo: Add prod flag for doing IUS install on CentOS. 2019-01-05 15:49:02 -08:00
rht
21c71a0c52 puppet: Use generic erlang package variable for all dependencies. 2019-01-05 15:49:02 -08:00
rht
a55f5b59f6 generate-self-signed-cert: Generalize to CentOS, Fedora, RHEL. 2019-01-05 15:49:02 -08:00
Steve Howell
efc1c74792 message scrolling: Move early-exit code higher.
This avoids some unnecessary computation and will
simplify testing.
2019-01-05 15:33:20 -08:00
Steve Howell
0f75be3e8e message scrolling: Extract _scroll_limit().
There's a subtle change here in how we handle the
hypothetical case that the selected message is above
the top of the feed.  Instead of early-exiting
from _maybe_autoscroll(), we just treat the limit
as zero, which will have the same effect.

We also change a var name be just `scroll_limit`
instead of `available_space_for_scroll`.  A longer
name would be valuable if it were somehow more
specific, but it was needlessly verbose.
2019-01-05 15:33:20 -08:00
Steve Howell
a7c92a2590 message scrolling: Extract _new_messages_height(). 2019-01-05 15:33:20 -08:00
Tim Abbott
0c6175f27e lint: Enforce semicolon spacing in eslint.
We only had a few exceptions to this rule; the zjquery one was actually a bug.
2019-01-05 15:31:30 -08:00
Tim Abbott
99721755e8 node: Temporarily remove composebox_typeahead from fully covered. 2019-01-05 15:31:30 -08:00
Harshit Bansal
194dd5fd30 emoji: Remove now unused emoji.emojis data structure. 2019-01-05 15:09:04 -08:00
Harshit Bansal
25229ffeea emoji: Merge datasources for emoji picker and typeahead.
This will help us in avoiding a lot bugs where some emojis were
present in emoji picker and not in typeahead and vice-versa.
2019-01-05 15:09:04 -08:00
Harshit Bansal
f8f971bfd6 typeahead: Rename codepoint to emoji_code. 2019-01-05 15:09:04 -08:00
Harshit Bansal
4251543426 emoji.js: Add display_name field.
The idea is to use this field for storing the best matching alias
to be displayed in search results. In subsequent commits I will
replace the search and rendering logic to use this field instead
of creating new objects on each search.
2019-01-05 15:09:04 -08:00
Tim Abbott
d1b189b2cd settings: Fix casper tests on invitations page.
We don't allow arrow functions in the codebase yet.
2019-01-05 15:08:37 -08:00
Shubham Dhama
e26cba062b settings_invites: Add invited_as column to the table.
This makes it possible to review the roles used in active invitations.
2019-01-05 14:53:09 -08:00
Shubham Dhama
efb9128aaa invite: Add option to invite user as guest.
This completes our basic guest user feature.

Fixes: #10818.
2019-01-05 14:52:51 -08:00
Shubham Dhama
42c262b807 invite: Replace invite_as_admin usage with invite_as.
Since we have already added the `invite_as` field to models, we can now
replace usage of `invite_as_admin` properly with its equivalent `invite_as
== PreregistrationUser.INVITE_AS['REALM_ADMIN']`.

Hence, also removed now redundant `invite_as`.
2019-01-05 14:46:38 -08:00
Shubham Dhama
c9414a3572 invite: Rename NORMAL_USER to MEMBER of Preregistration.INVITE_AS.
Renamed to keep the user-facing and the codebase terminologies coherent.
2019-01-05 14:43:06 -08:00
Tim Abbott
2adb0734d1 decorator: Set an error code for invalid API key errors.
This should make it easily for mobile/terminal apps to handle
situations like the user's API key changing.

Also fix the fact we were incorrectly using a 400, not 401, status
code for this case.
2019-01-05 11:29:34 -08:00
Tim Abbott
047817b6b0 puppet: Disable log2zulip cron job.
It hasn't been working for years, but more importantly, it spams up
root's mail queue so that one can't find important things in there
(e.g. the fact that the long-term-idle cron job was failing).
2019-01-05 10:56:44 -08:00
Vishnu Ks
689d8221e5 emails: Fix the if condition logic in missed_message.html.
Refactoring in 4e1c058 was not correct since recipient_block
and message_content checked for if not condition while
recipient_header checked for if.

The naming of classes in 6077a33 was also not correct
semantically.
2019-01-05 10:22:39 -08:00
Vishnu Ks
21f4aeff4f emails: Fix wrongly converted hex colors.
It looked like I got some hex values wrong during the
hsl to hex conversions. I used the built in vscode color
converter for this so not really sure how this happened.
The colors are now equalent to the original hex colors
before the conversion to hsl was made in
5869cc3b6d
2019-01-05 10:22:39 -08:00
Rishi Gupta
925475e5b1 portico: Add endorsements to /for/open-source. 2019-01-05 10:39:20 +05:30
Tim Abbott
2ba24bdd09 settings: Fix flushing of API key cache.
The logic for flushing the API key has been broken every since we
added the cache, since we were incorrectly flushing the new API key,
not the old API key, from the cache after regeneration.
2019-01-04 17:26:10 -08:00
Tim Abbott
bd5745ab35 test_settings: Extend caching section of API key test. 2019-01-04 17:26:05 -08:00
Tim Abbott
6eda129741 export: Export and import analytics table data.
This should eliminate the need to do manual analytics work when
importing organizations imported/exported using the zulip -> zulip
import/export tools.
2019-01-04 16:22:18 -08:00
Tim Abbott
48ccb3ad18 import: Move realm_tables to the appropriate file.
These had ended up in the wrong place when we split export from
import.
2019-01-04 16:22:18 -08:00
Tim Abbott
b33e0ad539 import: Fix pointer logic to sort by message_id.
Previously, the pointer calculation logic wasn't sorting by message
ID, which caused the database queries to not properly use the indexes
they should.
2019-01-04 16:22:18 -08:00
rht
801b04c057 puppet: Abstract out nagios-plugins package. 2019-01-04 15:27:03 -08:00
rht
04372e3300 puppet: Add CentOS packages to postgres_common.pp. 2019-01-04 15:24:42 -08:00
rht
bdf36bdc3d puppet: Use pip to install python dependencies on CentOS. 2019-01-04 15:23:45 -08:00
rht
d815239aac docs: Update CentOS/RHEL python3 ln command in setup-advanced. 2019-01-04 15:23:45 -08:00
Tim Abbott
453b65bde3 provision: Clean up comments and unused variables.
This has some changes inspired by #8514.
2019-01-04 15:16:19 -08:00
Tim Abbott
e15b279fb3 i18n: Sync translation data from Transifex. 2019-01-04 14:42:46 -08:00
Rishi Gupta
c1d40e22a7 emails: Update text for confirm_new_email. 2019-01-04 14:32:21 -08:00
Aastha
a65cb91cc1 docs: Add nginx reload documentation.
This adds reference for reloading nginx when the certificates are
replaced so that the server works with the new certificates instead of
the old ones.

Fixes: #4849.
2019-01-04 14:30:26 -08:00
Eeshan Garg
ecb506f13c webhooks/clubhouse: Support adding owners to stories. 2019-01-04 14:27:46 -08:00
rht
7e1520b01f provision: Ensure python3 exists in PATH for CentOS. 2019-01-04 14:11:03 -08:00
rht
105732ab1f parse_lsb_release: Fix vendor name matching for CentOS. 2019-01-04 14:09:48 -08:00
Rishi Gupta
f5c1a69737 portico: Add usage number hint in quotes section of /hello. 2019-01-04 12:13:10 -08:00
Rishi Gupta
84494c169a portico: Add link to /atlassian on /hello. 2019-01-04 12:13:10 -08:00
Rishi Gupta
3f4f43ab91 portico: Remove exclamation points from CTA at bottom of /hello. 2019-01-04 12:13:10 -08:00
Amadeo234
e07ad67624 message-edit: Add press to Enter to Save edited message functionality.
This couples the behavior of Enter to Save with Enter to Send.
Extracts and exports functions responsible for checking if enter
does send/edit and handling default behavior otherwise.
Changes made in static/js/message_edit.js and
static/js/composebox_typeahead.js

Fixes #10320.
2019-01-04 11:59:15 -08:00
Amadeo234
e06867fec3 message-edit: Extract functions concerning Enter to Send.
This adds two functions to static/js/composebox_typeahead.js.
should_enter_send(event) checks if enter should actually send.
handle_enter(textarea,event) emulates browser's default behavior
if enter doesn't send.

These two are just straight extractions of portions of the compose box
logic.
2019-01-04 11:58:56 -08:00
Tim Abbott
5a9d0c87bb node: Fix ui_init test failing due to night_mode initialization.
This was a rebase conflict between the new test and the extraction of
an initialization method for night_mode.
2019-01-04 11:44:56 -08:00
Tim Abbott
b7fb919dfa hipchat: Don't enable slim_mode by default.
For small organizations, generally one prefers the non-slim_mode
default behavior.
2019-01-04 11:30:25 -08:00
Tim Abbott
492230f405 hipchat import: Always include deleted users in import.
The slim_mode setting had been incorrectly configured to skip
"deleted" users, resulting in bugs where private messages with deleted
users would not be imported.
2019-01-04 11:23:02 -08:00
Steve Howell
d844a070fd ui: Render feedback widget client side.
We re-render the feedback widget on every call to
show().  This allows us more flexibility to mess
with the markup for particular use cases.
2019-01-04 10:54:10 -08:00
Steve Howell
c3a0a22661 slash commands: Add undo for /day and /night.
This also works for the synonyms /light and /dark.
2019-01-04 10:54:10 -08:00
Steve Howell
995a26f4e5 ui: Explicity initialize night mode. 2019-01-04 10:54:10 -08:00
Steve Howell
bdd7a64d19 ui: Close feedback widget with escape key.
It's a bit dangerous for the user to hit escape
to close the feedback widget, since it can
disappear suddenly, but users will try it, and
we should just close the widget.

(Hitting escape should be a noop if the box
is closed, but now it goes to "All Messages".)
2019-01-04 10:54:09 -08:00
Steve Howell
1cbcb06157 ui: Extract feedback_widget module. 2019-01-04 10:54:07 -08:00
Steve Howell
4468311620 feedback widget: Avoid duplicate handlers.
We only need these once, not during every show()
call.  We actually were only setting up the
click handlers one time, but we had redundant
mouse handlers.

More importantly, we stop a runaway timer
that tries to fade out our feedback widget
every 100ms or ten times per second!
2019-01-04 10:49:19 -08:00
Steve Howell
39cdc926a5 muting: Simplify dismiss() method. 2019-01-04 10:49:17 -08:00
Steve Howell
4baa65f38a muting: Rename container template to feedback_widget.html.
We now load the specific content for unmuting from
a handlebars template.
2019-01-04 10:48:19 -08:00
Steve Howell
0c48dad1da muting: Use more generic markup for undo-mute popup.
This makes everything generic except for the main
message given to the user.
2019-01-04 10:40:05 -08:00
Steve Howell
425df1c905 muting: Extract notify_widget class.
A few things are still hard coded, but the class exposes
show() and dismiss() now.

The show() method is configured with callbacks for
populate() and on_undo().
2019-01-04 10:40:02 -08:00
Steve Howell
51438281c7 minor: Rename $mute to $container.
The name doesn't even make sense for the specific
case, and we want to generalize this widget.
2019-01-04 10:37:31 -08:00
Aditya Bansal
079dfadf1a camo: Add endpoint to handle camo requests.
This endpoint serves requests which might originate from an image
preview link which had an http url and the message holding the image
link was rendered before we introduced thumbnailing. In that case
we would have used a camo proxy to proxy http content over https and
avoid mix content warnings.

In near future, we plan to drop use of camo and just rely on thumbor
to serve such images. This endpoint helps maintain backward
compatibility for links which were already rendered.
2019-01-04 10:27:04 -08:00
Aditya Bansal
3ee69f3da9 thumbnails: Add setting THUMBNAIL_IMAGES.
This setting splits away part of responsibility from THUMBOR_URL.
Now on, this setting will be responsible for controlling whether
we thumbnail images or not by asking bugdown to render image links
to hit our /thumbnail endpoint. This is irrespective of what
THUMBOR_URL is set to though ideally THUMBOR_URL should be set
to point to a running thumbor instance.
2019-01-04 10:27:04 -08:00
Vishnu Ks
9e9bd2456f billing: Add node test for is_in_array. 2019-01-04 23:52:00 +05:30
Vishnu Ks
2547d4ea07 billing: Remove mix option from frontend. 2019-01-04 23:52:00 +05:30
Vishnu Ks
c1551405aa billing: Extract setting initial tab into helpers.js. 2019-01-04 23:52:00 +05:30
Vishnu Ks
d94b0da3c8 billing: Separate billing.js into multiple modules. 2019-01-04 23:52:00 +05:30
Vishnu Ks
343e124270 billing: Remove get_form_input function. 2019-01-04 23:52:00 +05:30
Aditya Bansal
26c6ef1834 thumbnails: Fix bug with use of filters in thumbnail generation.
We used to add sharpen filter for all the image sizes whereas it was
intended for resized images only which would have been smoothened
out a bit by the resize operation.
This unnecessary use of the filter used to result in weird issues
with full size images.
For example: Image located at this url:-
http://arqex.com/wp-content/uploads/2015/02/trees.png
When rendered in full size would have just boundaries visible.
2019-01-04 19:06:01 +05:30
Vishnu Ks
7e8825bc6f emails: Change HSL colors to HEX for missed_message styles. 2019-01-03 17:55:29 -08:00
Vishnu Ks
81e6a022e6 emails: Inline CSS in missed_message.
As part of this change, we port into the .messages class the work in
4e8e7348da to change overflow-y to auto,
not scroll (skipping that would result in a regression).
2019-01-03 17:55:29 -08:00
Vishnu Ks
4e1c0589c2 emails: Refactor if condition from style tag in missed_message_email. 2019-01-03 17:55:29 -08:00
Steve Howell
56ee70e2a9 refactor: Re-organize some logic in message view.
We calculate a few values higher up in the function.
This reduces a bit of code duplication and removes
a somewhat janky expression that happens against
a mutated list.
2019-01-03 17:33:47 -08:00
Steve Howell
b88c3cd0d4 refactor: Rename vars in floating_recipient_bar.js.
The "label" made it sound these vars are strings, when
they are actually jQuery objects.
2019-01-03 17:33:44 -08:00
Steve Howell
78a3cb5887 Extract helper functions in floating_recipient_bar.js.
I use shorter var names in frb_botom() and do early
return in obscured_recipient_bar().

Also, we always call exports.hide() if we don't find
a valid recipient bar to "float."
2019-01-03 17:28:58 -08:00
Tim Abbott
4df618f584 portico: Order jquery.validate before signup.js.
This is important, because the signup.js module uses jquery.validate.
2019-01-03 15:22:57 -08:00
Tim Abbott
4eb80bf3b4 decorators: Don't attempt to rate-limit AnonymousUser.
This fixes our support for sending browser errors to the server for
portico pages in production, which previously hit a rate-limiter
exception.
2019-01-03 15:17:50 -08:00
rht
008879eb22 puppet: Add postgresql.conf path for CentOS. 2019-01-03 14:36:43 -08:00
rht
dce43e1a0e puppet: Add CentOS-version of pg data path at pg_backup_and_purge. 2019-01-03 14:36:43 -08:00
rht
59993aea80 puppet: Abstract out path to postgresql.conf. 2019-01-03 14:36:43 -08:00
rht
c189409ffd puppet: Initialize yum_repository.pp to wrap setup-yum-repo. 2019-01-03 14:36:43 -08:00
rht
1b02fb6d6d puppet: Add CentOS packages to rabbit.pp. 2019-01-03 14:36:43 -08:00
rht
a3d67e52fe puppet: Add CentOS packages to redis.pp. 2019-01-03 14:36:43 -08:00
rht
788128f05c puppet: Add CentOS packages to nginx.pp. 2019-01-03 14:36:43 -08:00
rht
1965cc1491 puppet: Add CentOS packages to base.pp. 2019-01-03 14:36:42 -08:00
rht
0caaed4e1f puppet: Add CentOS packages to apache_sso.pp. 2019-01-03 14:36:41 -08:00
rht
9fd18a2c7f puppet: Detect CentOS for release_name. 2019-01-03 14:35:09 -08:00
AsociTon
0ce7e613c7 message_edit: Add maxlength attribute in template.
Previously, we didn't enforce the maximum length of a message in the
browser, resulting in potential bad experiences for users.

Fixes #11137.
2019-01-03 14:31:00 -08:00
Steve Howell
f985125eb0 js: Initialize people.js earlier.
There is no reason not to initialize people.js
super early in the process, as it only reads
data from page_params.  Also, other modules
are likely to want its data during their own
initialization steps.
2019-01-03 13:49:44 -08:00
Steve Howell
5a313ccb90 presence: Use people.is_my_user_id() for check.
This is the preferred way to check that a user
id belongs to the current user.

We have a recent bug where the current user's
circle doesn't turn green right away.  It's not
clear this is the fix, though.  (It's hard to
repro locally.)
2019-01-03 13:49:44 -08:00
varunvaruns9
517718de02 user settings: Fix the position of get api key text and button.
Fix the alignment of "Current password" and move the
"Get API key" button to next line.

Fixes: #10535.
2019-01-03 13:48:25 -08:00
Steve Howell
6b7a4f8611 tests: Add unit tests for ui_init.js.
This test tries to find obvious dependency bugs, but
it really doesn't do anything other than fail when
it tries to use unavailable resources.
2019-01-03 13:44:38 -08:00
Tom Daff
f2e06128c6 email_mirror: Add email address parsing.
When trying to find the email gateway address, use the
`email.util.getaddresses` function to deal with cases
where multiple recipients are included in the email header
or the stream address appears as an angle-addr with a
name given (e.g. if someone added it to their address book).

Added some other headers where the required address may
appear: "Resent" headers are sometimes used for forwarding,
and streams may also be found in CC. There is no way to find
the address if the email was recieved as a BCC.
2019-01-03 13:34:20 -08:00
Tim Abbott
e3c8e8a839 models: Add __str__ method for emoji reactions.
This makes it more convenient to print them.
2019-01-03 13:26:25 -08:00
Tim Abbott
a1919971e4 import: Handle invalid data-user-id values for mentions.
This is an issue with zulip -> zulip server data imports.
2019-01-02 15:23:09 -08:00
Tim Abbott
b63f8b59b2 import: Handle corner case around EMAIL_GATEWAY_BOT emails. 2019-01-02 15:23:09 -08:00
Tim Abbott
8cfea958de import: Fix pointer logic for zulip->zulip imports.
Previously, the pointer was almost guaranteed to be an invalid random
value, because we renumber message IDs unconditionally now.
2019-01-02 15:23:09 -08:00
Tim Abbott
c03615b982 import: Fix uploading avatars with S3 upload backend.
This should hopefully be the last commit of this form; ultimately, my
hope is that we'll be able to refactor the semi-duplicated logic in
this file to avoid so much effort going into keeping this correct.
2019-01-02 15:23:09 -08:00
Tim Abbott
1ff3dd0ef7 clubhouse: Don't 500 for unhandled event types. 2019-01-02 15:23:09 -08:00
Tim Abbott
2e533f32c2 thumbor: Fix handling of upgrades from 1.8.0 and older.
Apparently, our thumbor logic assumed S3_REGION would be present in
prod_settings.py.  While it is in newer Zulip releases, upgraded
servers won't have a copy of this field.
2019-01-02 13:33:41 -08:00
Tim Abbott
ff9714eb32 register_server: Prompt for ToS inside the command.
This way, we don't need to tell new sysadmins how to rerun the script.
2019-01-02 11:19:36 -08:00
Tim Abbott
af6f45adab presence: Fix a mypy error with useless result object. 2019-01-02 11:06:20 -08:00
Shubham Dhama
092b73d0b7 ui: Fix wrong usage of scrolling to top in ui.updateScrollbar.
This was a bug introduced in 2363c9955a.

Fixes: #11141.
2019-01-02 11:00:01 -08:00
Tim Abbott
1a72256e05 settings: Fix hiding of email address visibility.
Apparently, the only development-only logic system broke saving this
settings block in production.

Fixes #11168.
2019-01-02 10:56:21 -08:00
Tim Abbott
5d550145bd docs: Document need for zulip group for some nagios checks. 2019-01-02 10:22:48 -08:00
Fabian Tribrunner
013b169469 check_email_deliverer_backlog: Switch down from root if required.
This now checks if the user is zulip, and if not, switches to the
zulip user, making it possible to run it as root.

Significantly modified by tabbott to not break existing behavior.
2019-01-02 10:16:56 -08:00
Steve Howell
8444326bf3 status: Add menu option to "View PMs to myself". 2019-01-02 09:27:33 -08:00
Steve Howell
7b5f282aee status: Show "(away)" next to yourself if you're away. 2019-01-02 09:27:16 -08:00
Steve Howell
cb691694d1 status: Add user menu options to set/revoke away status. 2019-01-02 09:23:20 -08:00
Steve Howell
6507804637 status: buddy list: Add basic UI to show away status.
Right now we do very simple things:

    you: make the green circle empty

    them: make the circle empty and demote to last group
2019-01-02 09:23:19 -08:00
Steve Howell
bb8750c22b refactor: Export buddy_data.level().
This is mostly for testing purposes.  The code
structure here is pretty stable--we will probably
always use level() here to either sort or
group users, and being able to test it directly
is nice, rather than bringing in all the other
machinery.
2019-01-02 09:16:31 -08:00
Steve Howell
4fed3d2014 frontend: Add event handling for user status.
The UI part of this commit isn't really turned on
yet, but it works in theory.
2019-01-02 09:16:31 -08:00
Steve Howell
d8d703af45 frontend: Add basic user_status module.
So far this processes page_params, but it's otherwise
an unused internal API.
2019-01-02 09:16:31 -08:00
Steve Howell
a2614956d5 status: Add away_user_ids to page_params.
(Also, any client that registers for 'user_status'
will see `away_user_ids`.)
2019-01-02 09:16:31 -08:00
Steve Howell
423db23c36 status: Add endpoint to toggle "away" status. 2019-01-02 09:16:30 -08:00
Steve Howell
7d58b05a51 tests: Add capture_event() helper.
For many actions, we make a single call to
send_event, and it's kind of heavy now to
properly assert we made one call, and we
don't need to exercise all the tornado code
to prove that the action was written correctly.
2019-01-02 09:12:10 -08:00
Steve Howell
a8301ca14a status: Add UserStatus model and core library for away status. 2019-01-02 09:12:03 -08:00
Hemanth V. Alluri
e3aed0f7bc custom profile fields: Markdown rendering for custom profile field values.
This makes it possible it include our standard markdown formatting in
one's custom profile fields, allowing for links, emphasis, emoji, etc.

Fixes #10131.
2019-01-01 21:06:21 -08:00
Hemanth V. Alluri
28d344b4b5 custom profile fields: Pass value as part of a dictionary.
While we're at it, we remove the JSON parsing that was part of the
user field code path, since this function isn't responsible for
rendering user fields.
2019-01-01 21:05:28 -08:00
Tim Abbott
bdaeccbca1 custom profile fields: Remove unnecessary JSON parsing step.
Apparently, our custom profile fields feature was parsing the "user
list" field type in multiple places, and ignoring the results in one
of them.  That code had been causing some confusion; the correct
solution is to just delete it, since the template rendering process
ignores that value for this field type.
2019-01-01 21:04:23 -08:00
Steve Howell
0c668d13b6 subject -> topic: Make get_event_topic() more flexible. 2019-01-01 20:52:10 -08:00
Steve Howell
55b4646212 node: Remove spurious data from template tests. 2019-01-01 20:52:08 -08:00
Steve Howell
4d5ce0b285 lint: Exclude "subject" from JS files (except util.js).
We also exempt the frontend tests for now.
2019-01-01 20:52:07 -08:00
Steve Howell
1ad30c6858 subject -> topic: Sweep "message.subject" in frontend.
These were the last remaining files.  After this, only
util.js has a non-email-related use of "subject".
2019-01-01 20:49:38 -08:00
Steve Howell
7e17b8a392 subject -> topic: Use util.set_message_topic() to set subject. 2019-01-01 20:49:34 -08:00
Steve Howell
b4bc6b4445 emails: Fix subject -> email_subject in send_email.py. 2019-01-01 20:49:00 -08:00
Steve Howell
4da28efc90 emails: Fix subject -> email_subject in error_notify.py. 2019-01-01 20:48:59 -08:00
Steve Howell
16328732d4 refactor: Remove "subject" from stream_topic.py. 2019-01-01 20:48:56 -08:00
rht
d3139266c8 setup_venv: Uninstall typing on Python >3.4.
Otherwise this causes an error
```
AttributeError: type object 'Callable' has no attribute '_abc_registry'
```
on 3.7. While the error is specific to 3.7, it is safer to uninstall
typing for all the versions that don't require a pip-provided typing
library.
2019-01-01 19:34:48 -08:00
rht
e54a25070c docs: Update direct dev installation to mention RHEL7. 2019-01-01 19:34:48 -08:00
rht
c190959b58 provision: Move CentOS & Fedora venv deps construction to setup_venv.py.
They will be reused in production setup.
2019-01-01 19:34:46 -08:00
rht
17ffbdabe2 provision: Use virtualenv instead of python-virtualenv on Fedora.
The package name changed at some point.
2019-01-01 19:34:24 -08:00
rht
75134ef614 provision: Use generic python3 on Fedora dependencies.
It might be cleaner to add new variables in setup_venv.py, but we can
do that later.
2019-01-01 19:34:11 -08:00
Cynthia Lin
55c1a2e525 settings: Add guest avatar marker to account settings. 2018-12-30 11:07:00 -08:00
Cynthia Lin
053c4a2250 popovers: Add guest avatar marker to user profile popover. 2018-12-30 11:07:00 -08:00
Cynthia Lin
4d97909764 popovers: Add guest avatar marker to user info popover. 2018-12-30 11:07:00 -08:00
Cynthia Lin
bcea4f10e6 message view: Add guest avatar markers to message sender avatars. 2018-12-30 11:07:00 -08:00
Cynthia Lin
022c6d1e52 components: Add basic styling component for guest avatar marker.
Fixes #10754.
2018-12-30 11:07:00 -08:00
Tim Abbott
f51ca9f398 backends: Don't try to process userAccountControl unless configured.
This fixes an exception in manage.py sync_ldap_user_data if
userAccountControl is not setup on the system yet.
2018-12-30 11:05:14 -08:00
Tim Abbott
22f39ff8e7 list_realms: Display '' as string_id for root domain realm. 2018-12-30 10:36:18 -08:00
Tim Abbott
e48c9245ff list_realms: Fix the --all option.
I don't think anyone's used this in years, but it could be handy.
2018-12-30 10:36:18 -08:00
Hudda
50e14dbe97 list_realms: Print the full domains of the organizations.
This adds a column to display the full domains of realms.  Tweaked by
tabbott to use fewer columns.

Fixes part of #11015.
2018-12-30 10:36:00 -08:00
Shubham Dhama
93e3543e5e user: Extend do_create_user for guest users. 2018-12-30 10:16:17 -08:00
Shubham Dhama
235b0db82b preregistrationuser: Add a model field for all type of invited users.
This adds a model field `invited_as` to PreregistrationUser model class
which will replace `invited_as_admin` in future. Intentions behind adding
this are that we can specify "types" of users for an invited person other
than admin or regular that is, guest user or maybe many others in the
future.
2018-12-30 10:16:17 -08:00
Fabian Tribrunner
4612a84a67 check_email_deliverer_process: Fix typo in process name.
This nagios check has never worked, since it had the wrong process
name from the beginning.
2018-12-30 09:41:42 -08:00
Tim Abbott
74ff77d366 import: Always set a valid content-type for S3 backend.
The octet-stream content type is potentially under-specified, but it's
better than potentially submitting None and increases consistency of
this part of the codebase.
2018-12-29 22:13:11 -08:00
Tim Abbott
f0c7424957 import: Fix sending floats to boto S3 metadata keys.
The boto library's s3 interface allows setting only string-format
metadata keys.  So we need to cast the last_modified floating-point
timestamp into a string before storing on the S3 object.

This bug mostly broke uploading avatars when using the S3 storage backend.
2018-12-29 22:09:31 -08:00
Tim Abbott
e7ef0904f5 accept_terms: Somewhat fix ugly white box.
This page could definitely use further design work, but at least this
doesn't look completely broken.
2018-12-29 22:06:07 -08:00
Tim Abbott
edd3699e4f templates: Update zulipchat migration ToS text.
The old text was written for a single migration, but now with Zulip
export/imports happening, this is a case that users will see more often.
2018-12-29 22:02:42 -08:00
Tim Abbott
41b7d9a4c8 hipchat: Handle unusual emoticons.json format.
Apparently, hc-migrate can generate emoticons.json files with a
somewhat different format.  Assuming that other files are in the
normal format, we should be able to handle it like this.

See report in #11135.
2018-12-29 18:59:31 -08:00
Tim Abbott
44f117ac72 hipchat: Handle case where emoticons.json is not in export.
Apparently, some methods of exporting from HipChat do not include an
emoticons.json file.  We could test for this using the
`include_emoticons` field in `metadata.json`, but we currently don't
even bother to read that file.  Rather than changing that, we just
print a warning and proceed.  This is arguably better anyway, in that
often not having emoticons.json is the result of user error when
exporting, and it's nice to flag that this is happening.

Fixes #11135.
2018-12-29 18:54:50 -08:00
Vishnu Ks
e35fa80745 billing: Fix the position of 'processing' text. 2018-12-30 08:00:23 +05:30
Vishnu Ks
806fa1a834 billing: Make card change use create_ajax_request. 2018-12-30 08:00:23 +05:30
Vishnu Ks
41fbc699ad billing: Make invoice upgrade use create_ajax_request. 2018-12-30 08:00:23 +05:30
Vishnu Ks
938438364f billing: Use form.serializeArray in create_ajax_request. 2018-12-30 08:00:23 +05:30
Vishnu Ks
b655cfe379 billing: Extract autopay ajax request code as function. 2018-12-30 08:00:23 +05:30
Vishnu Ks
93b1795ed1 billing: Don't pass csrf token in Ajax requests.
The Ajax request will automatically fetch the value
from input[name='csrfmiddlewaretoken'] and set the
headers. This is done in csrf.js.
2018-12-30 08:00:23 +05:30
Vishnu Ks
ed196bb980 billing: Rename #invoice_seat_count to #invoiced_licenses.
Followup of b4a28f3147
2018-12-30 08:00:23 +05:30
Vishnu Ks
eebf526657 billing: Check for min license count in frontend. 2018-12-30 08:00:23 +05:30
Tim Abbott
331984c322 ldap: Cast account_control_values to int.
This value will usually apparently come through the LDAP API as a
string, apparently.
2018-12-29 16:35:13 -08:00
Tim Abbott
772026e66b ldap: Don't crash if some users don't have a thumbnailPhoto.
It's normal for an LDAP database to have some users with a
thumbnailPhoto field set and others without one, so we should support
this configuration.
2018-12-29 16:32:16 -08:00
Tim Abbott
25793aefa7 hotkey: Fix using pageup/pagedown inside message edit.
Our logic for doing pageup/pagedown calculation inside compose was
written too tightly, and ended up breaking the keys inside message
editing.

Fix this by using generic selectors that don't hardcode compose.
2018-12-29 15:59:28 -08:00
Vaibhav
93914d8cd8 markdown: Parse '/me' for multi-line messages.
Previously, messages with more than one line did not parse '/me' at
the beginning of the message.  Since there's a reasonable way to
render multi-line messages, this commit adds support for doing so.

This change does potentially break with the expected behavior of other
slash commands, but it seems worth providing useful functionality over
a blind focus on consistency.

Fixes #11025.
2018-12-29 15:32:50 -08:00
Tim Abbott
5a8ad84381 test-documentation: Exclude the 500ing Citizen Code of Conduct.
We might want to eventually remove this, but I'm holding out hope that
it'll be fixed.
2018-12-29 15:30:19 -08:00
Vishnu Ks
13f8eeb1ac docs: Update git/overview docs to reflect CI changes. 2018-12-29 15:28:27 -08:00
Vishnu Ks
6f5b1903c4 docs: Update code-reviewing docs to reflect CI changes. 2018-12-29 15:28:26 -08:00
Vishnu Ks
cddce5bd34 docs: Rename travis.md to continuous integration and add more content. 2018-12-29 15:26:36 -08:00
Vishnu Ks
96bb27fa84 signup: Fix bug in import settings when subdomain is root.
If branch for showing the profile details would
not have executed if the subdomain was root ("").
The check was changed to check for select input
instead of checking for subdomain.
2018-12-29 15:01:09 -08:00
Vishnu Ks
e5f7d65231 signup: Set oldest account as default option in import settings.
Fixes: #11018
2018-12-29 15:01:09 -08:00
Eeshan Garg
d999e79a8b webhooks/bitbucket2: Decode improperly encoded stream names and topics. 2018-12-29 14:51:38 -08:00
Eeshan Garg
31f82705e2 webhooks/bitbucket: Decode improperly encoded stream names and topics. 2018-12-29 14:51:38 -08:00
Archit Kaushik
830dd68e45 message_list: Hide the message control icons when editing.
This avoids a bunch of potential confusion around users trying to
interact with these UI in situations that don't make sense.

(E.g. showing a menu to start editing the message when the menu is
already open).

Fixes #3802.
2018-12-29 14:37:56 -08:00
Abhigyan Khaund
104c6ea3f3 docs: Desktop AppImage updates automatically. 2018-12-29 14:36:27 -08:00
Steve Howell
053a41d816 subject -> topic: Fix notifications.js. 2018-12-29 14:34:06 -08:00
Steve Howell
56a893cd94 subject -> topic: Fix hash_util.js.
This includes using a more modern URL for topic links.
(We already supported "../topic/..." urls.)
2018-12-29 14:34:06 -08:00
Steve Howell
95e213df87 subject -> topic: Fix message_list_view.js. 2018-12-29 14:34:06 -08:00
Steve Howell
4fec91d5b1 subject -> topic: Fix message_events.js. 2018-12-29 14:34:06 -08:00
Steve Howell
3fc8597119 popovers: Avoid passing message to actions popover template.
We instead get the specific fields from message
that we use.  This is particularly helpful
for subject -> topic migration; we no longer
have to account for "subject" fields in
client-side templates.
2018-12-29 14:19:18 -08:00
Steve Howell
c293e37237 unread: Rename zero-subject-unreads to zero-topic-unreads. 2018-12-29 14:18:32 -08:00
Steve Howell
1903cc8ac7 refactor: Use message/topic in muting_ui.toggle_mute(). 2018-12-29 14:15:43 -08:00
Steve Howell
411743e6dd narrow: Use get_message_topic() helper. 2018-12-29 14:15:43 -08:00
Steve Howell
dc5321fed3 message_edit: Add util.get_edit_event_topic(). 2018-12-29 14:14:43 -08:00
Steve Howell
9b4f804fd1 message_edit: Add util.get_edit_event_orig_topic().
This extracts this bit of parsing logic for message_edit events.
2018-12-29 14:14:40 -08:00
Tim Abbott
a52eeb364b reactions: Avoid 500 when trying to double-add a reaction.
This IntegrityError has been happening occasionally in production due
to races, likely due to some sort of mobile app double-post bug.
Handle this by avoiding a 500, and returning the same 400 we would do
if there hadn't been a race.
2018-12-29 14:10:48 -08:00
Steve Howell
bcc92744c2 compose fade: Use "topic" internally. 2018-12-29 11:40:59 -08:00
Steve Howell
773e85309c topics: Make util more flexible about subject/topic. 2018-12-29 11:40:57 -08:00
Steve Howell
4e0969bb49 Rename util.set_topic -> set_message_topic(). 2018-12-29 11:38:39 -08:00
Steve Howell
4b2181ffa2 Rename util.get_topic -> get_message_topic().
The specific name will help us when we fully cut
over to "topic" on message objects.
2018-12-29 11:38:39 -08:00
Steve Howell
2fdb44803d filter: Eliminate a few "subject" references.
This continues the effort to isolate "subject" references
to util calls.

Also, we fix a comment.

Finally, we use canonicalized operators in a switch
statement.
2018-12-29 11:38:39 -08:00
Steve Howell
8121d19122 minor: Change "subject" to "topic" in comments. 2018-12-29 11:38:39 -08:00
Steve Howell
76a73e00f4 unread: Use topic_name as var. 2018-12-29 11:38:39 -08:00
Hemanth V. Alluri
b928bb3b26 static: Replace an if-else block in popovers.js with a switch statement. 2018-12-29 11:24:10 -08:00
Archit Kaushik
43fd8e658d notifications: Fix styling for long compose alerts.
This adjusts the spacing so that the out-of-view notifications for
group PMs (which have particularly long text) don't end up with the
"x" to close the notification overlapping the text.

Fixes #11058.
2018-12-29 11:15:39 -08:00
AsociTon
7a80456832 reactions: Make styling for night mode reactions more distinctive.
Fixes #10840.
2018-12-29 10:40:32 -08:00
Eeshan Garg
c4fd0a659f webhooks/statuspage: Update docs, logo and screenshots. 2018-12-29 10:29:16 -08:00
Eeshan Garg
1b539a51de webhooks/opsgenie: Update docs, logo and screenshots.
Note that the word "genie" in Opsgenie is not supposed to be
capitalized.
2018-12-29 10:29:16 -08:00
Eeshan Garg
8bab4ceba4 webhooks/bitbucket2: Update docs, logo and screenshots. 2018-12-29 10:29:16 -08:00
Eeshan Garg
9c584e6bb8 webhooks/trello: Remove superflous Advanced section.
This section is largely unnecessary, doesn't convey any useful
information, and is probably a remnant from an older version of
this doc that we forgot to remove.
2018-12-29 10:29:16 -08:00
Eeshan Garg
da663104f3 webhooks/trello: Update logo and screenshots. 2018-12-29 10:29:16 -08:00
Eeshan Garg
776bdab567 webhooks/jira: Update logo and screenshots. 2018-12-29 10:29:16 -08:00
Sumanth V Rao
ccd0badeed test-documentation: Simplify --skip-external-links code path.
The crawler used to be called directly for checking external links.
Now the scrapy command calls the crawl_with_status wrapper.
Crawl_with_status has been modified to pass the external parameter in
the previous commit, so we can now use this simpler approach.
2018-12-29 09:09:18 -08:00
Sumanth V Rao
776b981dde test-help-documentation: Skips checking external links.
This option causes test-help-documentation to verify internal links only.
This prevents documentation from flaking in CI due to links from
external websites having failed in the documentation.

Based on conversation:
https://chat.zulip.org/#narrow/stream/43-automated-testing/subject/quora.20404/near/674997
2018-12-29 20:15:30 +05:30
Steve Howell
015af605cf Use stream_id in web app for muting endpoints.
This is set up by the previous commit, which allows
stream_id as alternative for stream on the server side.
2018-12-27 20:26:30 -08:00
Steve Howell
c35afb942f Accept stream_id for muting endpoints. 2018-12-27 20:26:30 -08:00
Eeshan Garg
4a2a3e3640 webhooks/gitlab: Support issues with multiple assignees.
The fixtures added in this commit were generated by Adam Birds.
2018-12-27 20:15:00 -08:00
Eeshan Garg
488f558d49 test_docs: Print better error messages for failed responses. 2018-12-27 20:13:08 -08:00
Eeshan Garg
8a02e177e3 bugdown: Trigger test failure for invalid Markdown include statements.
This commit adds a custom Markdown include extension which is
identical to the original except when a macro file can't
be found, it raises a custom JsonableError exception, which
we can catch and then trigger an appropriate test failure.

Fixes: #10947
2018-12-27 20:13:08 -08:00
Abhinav Singh
a378407c57 emails: Fix inconsistent email UI for different email clients.
This commit replaces hsl color codes to hex color codes to render
colors in different email clients consistently.
2018-12-27 18:02:08 -08:00
Tim Abbott
c995e8e2ae import: Ensure presence of basic avatar images for HipChat.
Our HipChat conversion tool didn't properly handle basic avatar
images, resulting in only the medium-size avatar images being imported
properly.  This fixes that bug by asking the import tool to do the
thumbnailing for the basic avatar image (from the .original file) as
well as the medium avatar image.
2018-12-27 17:47:09 -08:00
Steve Howell
e8f2d6f32b Fix false positives in message view tests.
The `assert_message_groups_list_equal` and
`assert_message_list_equal` helpers were
always returning `true`, as they were doing
a bogus traversal of the data structures and
always comparing empty arrays, even when there
was real data.

To prevent this pitfall in the future, we assert
that the extracted data is truth-y, and for the
empty cases we just directly assert deep equality
to `[]`.
2018-12-25 09:30:03 -08:00
Rishi Gupta
955dfc6397 billing: Remove references to Realm.has_seat_based_plan. 2018-12-24 10:27:56 -08:00
Rishi Gupta
7c38300949 billing: Add info line to logger for failed upgrades. 2018-12-24 10:27:56 -08:00
Rishi Gupta
653416ab23 billing: Update /billing to work with new subscription model. 2018-12-23 00:18:21 -08:00
Rishi Gupta
e7220fd71f billing: Do subscription management in-house instead of with Stripe Billing.
This is a major rewrite of the billing system. It moves subscription
information off of stripe Subscriptions and into a local CustomerPlan
table.

To keep this manageable, it leaves several things unimplemented
(downgrading, etc), and a variety of other TODOs in the code. There are also
some known regressions, e.g. error-handling on /upgrade is broken.
2018-12-22 13:39:30 -08:00
Rishi Gupta
5633049292 billing: Restructure validation of upgrade parameters. 2018-12-22 13:30:15 -08:00
Rishi Gupta
b4a28f3147 billing: Rename seat_count to licenses where appropriate. 2018-12-22 13:30:15 -08:00
Rishi Gupta
7ab1406962 billing: Prepare for moving Plan to CustomerPlan.billing_schedule. 2018-12-22 13:30:15 -08:00
Vishnu Ks
8176d112fe billing: Add frontend for license-based billing system. 2018-12-22 13:30:15 -08:00
Vishnu Ks
d086efd33f billing: Deduplicate get_form_input in billing.js. 2018-12-22 13:30:15 -08:00
Rishi Gupta
7b5d15d254 billing: Move discount to local Customer object.
A lot of the seemingly unrelated test fixture changes are because we're
removing a query to stripe in the upgrade path, in cases when the user's
realm has an existing Customer object.
2018-12-22 13:30:15 -08:00
Rishi Gupta
8ec91fc42d billing: Remove process_downgrade. 2018-12-22 13:30:15 -08:00
Rishi Gupta
84a31ca800 billing: Remove BillingProcessor.
Leaving the model in place, so that we can do the database migration by
hand.
2018-12-22 13:30:15 -08:00
Steve Howell
72576b3a77 compose: Fix recent autocomplete regression.
As part of giving the stream/topic fields in the
compose box longer ids, I broke the autocomplete
code that handles re-focusing the cursor after
a user hits enter.  The worst symptom of this was
that we tried to send a message before compose
finished (although it wouldn't fully deliver the
message).

The new code should be a bit easier to grep for
if we rename these fields again, as we explicitly
use selector syntax.
2018-12-22 08:07:23 -08:00
Steve Howell
ca22302763 minor: Avoid ui_util.focus_on() call.
The helper is unnecessary at this point and obscures
greps for selectors.  We completely eliminate it in
the next commit.
2018-12-22 08:07:23 -08:00
Steve Howell
a3000940f7 Remove Slack/PHP link to fix builds.
The link is broken, and I'm not sure we want this
paragraph in there, as it's somewhat speculative
(we don't know how extensively Slack uses PHP any
more, nor do we know how much of a factor it is in
any security issues) and is probably mostly
preaching to the choir.  The "bounty" link should
suffice.
2018-12-22 08:07:23 -08:00
Vishnu Ks
30a61d7505 billing: Fix plan input bug in upgrade. 2018-12-21 09:34:27 -08:00
Vishnu Ks
bcae08470c emails: Use ugettext instead of ugettext_lazy in signals.
ugettext_lazy was printing the object in the email template
instead of the string.
2018-12-20 19:35:23 -08:00
Rishi Gupta
bf8db6f634 emails: Update text for confirm_registration. 2018-12-20 16:26:19 -08:00
Rishi Gupta
0844c9a6ec emails: Update text for password_reset.
Note that a pretty common use case for this is a realm admin sending this to
everyone after an import from HipChat or Slack. So this adds the realm_name
to the title (so that there is something they might recognize) and kept the
wording generic enough to accommodate the user not having clicked anything
to get this email.

Also strengthens the tests a bit to better test the complicated template
logic.
2018-12-20 16:26:19 -08:00
Rishi Gupta
2da0cb7a44 emails: Update text of realm_reactivation. 2018-12-20 16:26:19 -08:00
Rishi Gupta
f8720fddd6 emails: Update text of notify_new_login. 2018-12-20 16:26:19 -08:00
Rishi Gupta
dc39d66bca emails: Update text for notify_change_in_email. 2018-12-20 16:26:19 -08:00
Rishi Gupta
fb56720054 emails: Update text for invitation and invitation_reminder. 2018-12-20 16:26:19 -08:00
Rishi Gupta
d8e16143d4 emails: Clean up code surrounding the call to find_team. 2018-12-20 16:26:19 -08:00
Rishi Gupta
292683f0d5 emails: Add a few more emails to email_log.py. 2018-12-20 16:26:19 -08:00
Rishi Gupta
abbe7b8f65 context_processors: Add user_name to common_context. 2018-12-20 16:26:19 -08:00
Rishi Gupta
19645354c7 user docs: Update about-streams-and-topics. 2018-12-20 16:26:19 -08:00
Steve Howell
1656fd7729 Fix recent regression with mute undo.
The undo button was bound to the stream id
and topic for only the first call, when
the click handler was set.
2018-12-20 15:58:05 -08:00
Akash Nimare
bd49b2ad63 portico: Fix height of carousel container. 2018-12-20 18:49:41 +05:30
Vishnu Ks
6d29525ef0 emails: Fix broken email revert process in email_log. 2018-12-19 11:24:57 -08:00
Tim Abbott
9c3f38a564 docs: Automatically construct OpenAPI metadata for help center.
This is somewhat hacky, in that in order to do what we're doing, we
need to parse the HTML of the rendered page to extract the first
paragraph to include in the open graph description field.  But
BeautifulSoup does a good job of it.

This carries a nontrivial performance penalty for loading these pages,
but overall /help/ is a low-traffic site compared to the main app, so
it doesn't matter much.

(As a sidenote, it wouldn't be a bad idea to cache this stuff).

There's lots of things we can improve in this, largely through editing
the articles, but we can deal with that over time.

Thanks to Rishi for writing all the tests.
2018-12-19 10:18:20 -08:00
Vishnu Ks
0fb90dcdb3 emails: Tag followup_day2 email for translation. 2018-12-19 09:21:09 -08:00
Vishnu Ks
f9e4d5d28e emails: Tag password_reset for translation. 2018-12-19 09:21:09 -08:00
Vishnu Ks
0960e654ab emails: Tag notify_new_login email for translation. 2018-12-19 09:21:09 -08:00
Vishnu Ks
78fea79c06 emails: Simplify new_login device info section. 2018-12-19 09:21:09 -08:00
Tim Abbott
a4dccec356 linkifiers: Fix the new linkifier field widths.
This makes it much more reasonable to enter a longer URL.
2018-12-19 09:15:41 -08:00
rht
acbb174100 provision: Add RHEL 7 support. 2018-12-18 17:13:56 -08:00
rht
84c968ab36 provision: Include scripts/lib/setup-* and scripts/lib/build-* for sha1 sum check. 2018-12-18 16:56:27 -08:00
Tim Abbott
0510424e1c auth: Remove some now-unused auth_backend_enabled helpers.
These were causing coverage errors, and in any case are now useless.
2018-12-18 16:51:57 -08:00
Tim Abbott
af1c7a9573 docs: Improve documentation for adding a new authentication backend.
Now that we have the Azure Active Directory integration cleaned up and
merged, we can nicely link to it as an example.
2018-12-18 16:49:01 -08:00
Tim Abbott
00a75bda3b docs: Fix a few broken link anchors. 2018-12-18 16:49:01 -08:00
seresheim
49dbd85a89 auth: Add support for Azure Active Directory authentication.
This takes advantage of all of our work on making the
python-social-auth integration reusable for other authentication
backends.
2018-12-18 16:39:03 -08:00
Tim Abbott
9d058f9193 test_auth_backends: Eliminate manual lists of authentication backends.
This should dramatically reduce the manual work involved with
correctly adding a new authentication backend to Zulip with this test
suite.
2018-12-18 16:36:45 -08:00
Tim Abbott
11fcbe52a6 auth: Automate calculation of get_auth_backends_data.
This change lets us eliminate the need for new authentication backends
to edit get_auth_backends_data, since we're just computing it from the
official registry in zproject/backends.py.  Should save a few lines of
work whenever we add a new auth backend, and make that more accessible
to new contributors.
2018-12-18 16:23:21 -08:00
Tim Abbott
bd0596e711 context_processors: Automated oauth backend enabled logic. 2018-12-18 16:23:21 -08:00
Tim Abbott
ba77303ee4 message_list: Slightly optimize content editing logic.
Previously, we were searching the whole message_row object for emoji,
mentions, etc., which has a bunch of UI elements that can't contain
the syntax we want to modify.  This should be a slight improvement in
the performance of message post-processing, which runs a lot of times
and thus is fairly important.
2018-12-18 14:50:05 -08:00
varunvaruns9
c2ced75d5a message_list_view: Rerender names of user groups and streams on change.
Rerender the mentions for user groups and streams when
they are not in search.

Fixes part of #11026.
2018-12-18 14:44:11 -08:00
varunvaruns9
424127012f message_list_view: Add highlight for user group mentions.
Add green highlight to mentions of user groups the current user
is a member of.

Fixes part of #11026.
2018-12-18 14:43:32 -08:00
varunvaruns9
eca1ce7f1f message_list_view: Remove check for mention class.
This check caused us to only run the code inside that block if the
message mentioned the current user (since that's when the `mention`
class is added to the main message row).

While this was a useful performance optimization, it probably was a
small one, not worth it for the correctness cost.
2018-12-18 14:41:46 -08:00
Eeshan Garg
6d51c065d3 webhooks/gitlab: Add support for confidential issues and notes.
With some minor changes by Eeshan Garg.

Fixes #10478.
2018-12-18 14:37:44 -08:00
Eeshan Garg
124cb9cca3 webhooks/zabbix: Handle payloads with missing data properly. 2018-12-18 13:44:35 -08:00
Tim Abbott
3c70a61132 models: Deduplicate definitions of push tokens.
Since c57c4cf703, these are no longer
different implementations, so we can deduplicate them.  Because Django
is smart, no migration is required.
2018-12-18 13:05:23 -08:00
varunvaruns9
8426785286 message_list_view: Fix mention text in search condition.
Use length property of find function to check if highlight
class was present because find return an object even if
highlight class was not present.
2018-12-18 12:55:03 -08:00
Rishi Gupta
ca89e9aec0 help docs: Document scalability for Slack/HipChat import tools. 2018-12-18 12:54:46 -08:00
Eeshan Garg
a56dbdb0f3 webhooks/clubhouse: Ignore requests with empty request body. 2018-12-18 12:54:04 -08:00
Eeshan Garg
dedf56bf31 webhooks/clubhouse: Support story/epic deletion. 2018-12-18 12:54:04 -08:00
Rishi Gupta
d813d29290 billing: Add mypy daemon warning to stripe stubs file. 2018-12-18 12:48:22 -08:00
Rishi Gupta
fc41360ed9 billing: Update stripe python package.
Needed for stripe.Invoice.finalize_invoice().
2018-12-18 12:48:22 -08:00
Joshua Pan
ad1df0ebeb settings: Add support for customizing the top-left logo.
This adds a new realm_logo field, which is a horizontal-format logo to
be displayed in the top-left corner of the webapp, and any other
places where we might want a wide-format branding of the organization.

Tweaked significantly by tabbott to rebase, fix styling, etc.

Fixing the styling of this feature's loading indicator caused me to
notice the loading indicator for the realm_icon feature was also ugly,
so I fixed that too.

Fixes #7995.
2018-12-18 12:44:52 -08:00
Tim Abbott
34f5218a0d ui_report: Add support for passing "".
I'm not really a fan of the "Failed:" pattern in some places, and this
lets us avoid it.
2018-12-18 12:33:42 -08:00
Tim Abbott
dd946fff1f lint: Improve ui_report.error linter rule.
We now allow passing "" as the first argument.
2018-12-18 12:33:15 -08:00
Joshua Pan
5c196d70bd css: Switch upper left logo and text to a single image.
This is preparation for allowing customization of this field.
2018-12-18 12:19:56 -08:00
rht
a093d45064 provision: Check for pg_hba.conf existence for doing postgres initdb.
Apparently, an empty pg_datadir is initialized after postgresql-10 is
installed.
2018-12-18 12:07:45 -08:00
rht
3f1005dab1 setup-advanced: Update section anchor on "installing directly ...". 2018-12-18 12:07:22 -08:00
rht
3060ee9397 provision: Fix typo when checking that vendor is Fedora. 2018-12-18 12:07:03 -08:00
rht
ac8a164709 setup-advanced: Add notice on bootstrap requirement for CentOS & Fedora. 2018-12-18 12:07:03 -08:00
Vaibhav
7371fd2647 notifications: Refactor code using logic from message_viewport.
Logic for checking if the last message in the current table is visible was
already written in message_viewport.js; Code in notifications.js is changed
to reduce redundancy.
2018-12-18 11:53:08 -08:00
Steve Howell
f4f59a7557 presence: Rename presence.set_user_status() -> set_info_for_user(). 2018-12-18 11:01:10 -08:00
Steve Howell
ba69dcc74c presence: Rename activity.set_user_status().
We are trying to carve room for a more specific
"user_status" concept, which refers to statuses
that users specifically set, like "I'm away".

So we call this function "update_presence_info",
which reflects that it's more about actual
"presence"--i.e. the user really is present
in the browser, even though the actual human
may not want to be disturbed.
2018-12-18 11:01:06 -08:00
Steve Howell
2c719bdb3f buddy list: Exclude current user from searches.
The current user gets excluded from all non-empty
searches, even ones that match the user, since
it can look funny when the user's at the top of a
search, and you'd never need to search for yourself
(again, since the current user is at the top of
the buddy list).
2018-12-18 11:01:06 -08:00
Steve Howell
712054e128 node tests: Clean up buddy_data test.
It's still a bit messy, but we add a real
user for "me", add a specific human user (Selma),
and make the setup an ordinary function.
2018-12-18 11:01:05 -08:00
Steve Howell
bf152b94b5 presence: Put current user back at the top of the buddy list.
We tried this out, reverted it, and then put it back.
2018-12-18 11:01:01 -08:00
Tim Abbott
bdb3da4504 eslint: Add key-spacing linter rule.
Apparently, we didn't have one of these, and thus had a moderate
number of generally very old violations in the codebase.  Fix this and
clear the ones that exist..
2018-12-18 10:41:06 -08:00
Anders Kaseorg
392175d6e8 Use #!/usr/bin/env for bash shebangs.
/bin/sh and /usr/bin/env are the only two binaries that NixOS provides
at a fixed path (outside a buildFHSUserEnv sandbox).

This discussion was split from #11004.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2018-12-17 17:21:08 -08:00
rht
66c02e4dc7 docs: Update direct dev installation to mention Centos & Fedora.
Tweaked by tabbott to also deprecate the older instructions.
2018-12-17 16:33:31 -08:00
rht
5e12eb8d34 provision: Fix typo in list of services on RedHat. 2018-12-17 16:30:48 -08:00
rht
42cbf2071b provision: Skip RedHat postgresql initdb if already initialized.
We only need to initialize a postgres database once in the lifetime of
a system.
2018-12-17 16:29:50 -08:00
rht
295cbe7b9c provision: Add build-pgroonga and use it for Fedora. 2018-12-17 16:23:57 -08:00
rht
80ba105be5 provision: Abstract out SYSTEM_DEPENDENCIES. 2018-12-17 16:23:46 -08:00
rht
b732fe819e provision: Add Fedora support. 2018-12-17 16:23:44 -08:00
Eeshan Garg
88cf6777d0 python-zulip-api: Upgrade to latest PyPI release (0.5.6). 2018-12-17 18:37:20 -03:30
Eeshan Garg
ebf5104923 bot_lib: Add user_id attribute to EmbeddedBotHandler.
Support for extended mention syntax was added as a part of
commit fbe99b812ee8fbca7257a5b7156c57a6cd74195b in the
python-zulip-api repository. The relevant function,
extract_query_without_mention now relies on the client's ID
in order to check for the extended syntax. Since the
EmbeddedBotHandler has no user_id attribute, the latest
python-zulip-api release broke a test in the main repo.
2018-12-17 18:37:20 -03:30
Tim Abbott
d84d3777fd casper: Fix admin tests failing.
This was broken with the recent realm filters commits.
2018-12-17 13:43:13 -08:00
Rishi Gupta
d2b47dc270 org settings: Rename linkification regular expression field to pattern.
We use pattern in the table, so we should match that in the form.
2018-12-17 12:58:52 -08:00
Tim Abbott
d469c14d11 docs: Advertise arbitrary org GitHub patterns for linkifiers.
Now that we support this, we should make it really obvious that we do.

Also, link to the Help Center article.
2018-12-17 12:58:52 -08:00
Tim Abbott
ad9e063a5c settings: Rename realm_filters template to use linkifiers. 2018-12-17 12:29:39 -08:00
Tim Abbott
12b3e79661 settings: Rename "settings_filters" to "settings_linkifiers".
This makes the JS codebase match the UI for how to describe this
feature.  No user-facing effect.
2018-12-17 12:28:55 -08:00
Tim Abbott
c87a533b3b realm filters: Make validation error messages more useful. 2018-12-17 12:25:12 -08:00
Tim Abbott
34e39248fc linkifiers: Add validation support for multiple items.
This is a simple change to our validation, to allow multiple copies of
the main linkifier syntax, which lets us support things like generic
GitHub URLs.

Fixes #10914.
2018-12-17 12:19:59 -08:00
rht
2dc1dc8ec2 provision: Replace overwrite_symlink with sudo ln -sf.
overwrite_symlink doesn't work for a non-root user when accessing root
content.
2018-12-17 11:50:15 -08:00
rht
888388cf89 setup-yum-repo: Add -y flag to yum update. 2018-12-17 11:49:43 -08:00
Tim Abbott
a0da4f6d30 python: Clean up various if False blocks.
Most of these are now-unnecessary typing imports; some are just
improved comments for those with other mypy motivations.
2018-12-17 11:14:47 -08:00
Tim Abbott
2558f101af docs: Add documentation for if False mypy pattern in scripts.
This should help make it clear what's going on with these scripts.
2018-12-17 11:12:53 -08:00
Tim Abbott
209df75ffa lint: Enforce use of Python 2 style typing in zulint.
This is intended to be extracted as an external project that supports
Python 2+3.
2018-12-17 11:00:08 -08:00
Tim Abbott
35901cc955 lint: Fix a tooling test failure in last commit.
This is what I get for copy-pasting lint rule blocks.
2018-12-17 10:53:08 -08:00
Tim Abbott
bce90a3340 lint: Add lint rule for scripts importing typing improperly.
This is a common bug that users might be tempated to introduce.

And also fix two instances of this bug that were present in our
codebase, including an important one in our upgrade code path.
2018-12-17 10:46:37 -08:00
Tim Abbott
47c4a2d21a upgrade-zulip-from-git: Remove buggy typing import.
This broke running this on Python 3.4, where typing isn't in stdlib.
2018-12-17 10:33:52 -08:00
Tim Abbott
128a08e0a4 docs: Rearrange mypy docs to deprioritize stubs section.
The stubs section is less important than the discussion of how to
handle mypy trouble.
2018-12-17 10:30:51 -08:00
Tim Abbott
612e70a64b docs: Add a warning about editing mypy stubs and the daemon. 2018-12-17 10:28:18 -08:00
Steve Howell
7a44d99b96 settings: Eliminate admin_sections module.
We move all of its logic into settings_sections.

Note that this is slightly more than a refactor.
We are slightly more aggressive about resetting
sections.  For example, if you go into Settings,
then exit the overlay, then go into Manage
Organization, we will now reset sections for both
groups.
2018-12-17 10:13:20 -08:00
Steve Howell
0543e8fbc1 settings: Call maybe_disable_widgets() in set_up() methods.
We now rely on set_up() methods to call their
own module-specific versions of maybe_disable_widgets()
in the codepath for admin_sections.load_admin_section().

And then for live updates, we just explicitly call
all four modules that support maybe_disable_widgets().

This should make switching between sections slightly faster,
and it also reduces the risk of module A messing with
module B's state.  (Granted, we have lots of other ways
that modules can mess with each other's state.)
2018-12-17 10:13:18 -08:00
Steve Howell
b88a5700f6 settings: Extract multiple versions of maybe_disable_widgets(). 2018-12-17 10:13:16 -08:00
Tim Abbott
b29d66f34b i18n: Rename email subject files so i18n detects them.
Apparently, when we renamed these files to no longer have a .txt
extension, we accidentally removed them from the set of strings for
translation, because `manage.py makemessages` by default only
processes .txt and .html files under the templates/ directory.

Fix this by adding a .txt extension.
2018-12-17 10:00:49 -08:00
Tim Abbott
b2fc017671 i18n: Use the recipient's language when sending outgoing emails.
It appears that our i18n logic was only using the recipient's language
for logged-in emails, so even properly tagged for translation and
translated emails for functions like "Find my team" and "password
reset" were being always sent in English.

With great work by Vishnu Ks on the tests and the to_emails code path.
2018-12-17 09:49:36 -08:00
Vishnu Ks
b10c23c233 emails: Call send_email when DEVELOPMENT_LOG_EMAILS is enabled.
The previous version was also doing almost the same thing.
But checking for DEVELOPMENT_LOG_EMAILS would allow us
to control the call of send_email by altering the value
of DEVELOPMENT_LOG_EMAILS in tests.
2018-12-17 09:40:32 -08:00
Tim Abbott
cb9b526f0c third: Extract bootstrap typeahead to its own module.
Bootstrap's typeahead is the main part of the project that we've
forked, and moving it to its own module should help unlock our ability
to upgrade bootstrap itself.
2018-12-17 09:06:52 -08:00
Steve Howell
d8c454b097 todo lists: Make lists sharable.
We no longer restrict who can add tasks or check
them off.

Fixes #10440
2018-12-17 07:40:27 -08:00
Tim Abbott
e9f889d57e portico: Fix totally broken ToS re-accept form styling.
This form isn't actively used, which is how it ended up broken, but it
basically didn't display its content properly at all.

Convert it to use our standard white-box framework.

This still doesn't look great in various ways, but it's at least not
obviously totally busted now.
2018-12-17 07:28:29 -08:00
Tim Abbott
d005f4edd3 management: Fix incorrect create_user docsting on ToS. 2018-12-16 22:23:35 -08:00
Tim Abbott
d9912cb23c management: Fix buggy create_user management command.
The create_user management command incorrectly was double-calling
notify_new_user.
2018-12-16 22:22:52 -08:00
Tim Abbott
cf445861f1 docs: Clean up blog post link in our mypy documentation. 2018-12-16 21:52:53 -08:00
Tim Abbott
6b69cc0b39 lint: Run mypy as part of main linter.
To support this, we add a pass_targets option to the main linter
library, because with current mypy, it's generally counterproductive
to pass the list of files in (can produce spurious errors; isn't
faster).
2018-12-16 21:52:53 -08:00
Tim Abbott
3003517430 docs: Move mypy documentation from contributing to testing.
The testing section is more appropriate, since it's fundamentally part
of our CI system.

While we're at it, fix the fact that we were linking to GitHub, not
ReadTheDocs, in the run-mypy output.
2018-12-16 21:52:53 -08:00
Tim Abbott
a3c4ea51f0 docs: Simplify discussion of where mypy is installed. 2018-12-16 21:52:53 -08:00
Tim Abbott
dc54d290fc docs: Rearrange mypy documentation ordering.
Installation/running is definitely higher priority than stubs for
third-party modules.
2018-12-16 21:52:53 -08:00
Tim Abbott
8637bdeb30 mypy: Provide a clear message when starting daemon.
Previously, when the mypy daemon was starting up, it was very unclear
from the linter context what was happening.
2018-12-16 21:52:53 -08:00
Tim Abbott
f3c6d91e69 mypy: Switch default to daemon mode.
There isn't any real advantage to running the non-daemon mode at this
point.
2018-12-16 21:37:58 -08:00
Tim Abbott
7485cb2a50 widgets: Rename voting_widget to poll_widget.
This ensures greater consistency with our other widgets' naming
convention.
2018-12-16 19:46:48 -08:00
Tim Abbott
8a90441d2f slack import: Import long-inactive users as long-term idle.
This avoids creating UserMessage rows for long-inactive users in
organizations with many thousands of users.
2018-12-16 18:52:20 -08:00
Tim Abbott
37189e1f9d soft deactivation: Handle case where a user has no message history.
I'm aware of at least one case where this happened with some imported
data history; better to not have that crash.
2018-12-16 18:52:20 -08:00
Tim Abbott
f47f263655 soft deactivation: Avoid giant transaction.
The previous logic for soft deactivation ended up doing a giant
transaction in the case that there were thousands of users to
deactivate; this was messy and potentially buggy.

The batched transactions were useful for RealmAuditLog management,
however.  So the right solution is to do reasonably sized batches
(e.g. 100 users).
2018-12-16 18:52:19 -08:00
Tim Abbott
430ed061c1 migrations: Fix do_batch_update for postgres 10.
Apparently, our do_batch_update method (used, e.g., in a pgroonga
migration) was using semi-invalid syntax that was removed in postgres
10.

Thanks to Ilya Evseev for the report.

Fixes #11063.
2018-12-16 17:46:11 -08:00
Tim Abbott
2cca6a1be8 csrf: Improve API for when no CSRF input is available.
Since we're adding this to a large number of portico pages, there's no
guarantee that these pages actually have a CSRF input.

Though given that the logout template contains a CSRF input,
realistically it should always be present.
2018-12-16 16:19:23 -08:00
Tim Abbott
adebe1bd4e js: Extract csrf.js and include in common bundle.
This should make it possible to use this AJAX setup code in logged-out
code as well, which is necessary to use blueslip from portico pages.
2018-12-16 16:18:42 -08:00
Tim Abbott
ed9430f3a6 Revert "js: Extract csrf.js and include in common bundle."
This reverts commit dbffa66b6d.

This broke the logged-in app, due to some webpack issue.
2018-12-16 16:16:06 -08:00
Tim Abbott
6416737e70 Revert "csrf: Improve API for when no CSRF input is available."
This reverts commit 9198fa4ec9.
2018-12-16 16:15:54 -08:00
Steve Howell
7d23076a0e drafts: Fix bug in finding current element.
We weren't using the actual sorted data to find
the last element.  This probably worked by accident
in some cases, but this commit makes it more
deterministic.
2018-12-16 15:46:41 -08:00
Steve Howell
ebd6d84326 refactor: Call format_drafts() more directly.
We want the return value from this for the next
commit, so we no longer call `format_drafts` indirectly
from `populate_and_fill`, and we rename the latter
to `render_widgets`.
2018-12-16 15:46:41 -08:00
Steve Howell
1584789916 refactors: Move format_draft() to module level.
This is a pure code move.
2018-12-16 15:46:41 -08:00
Steve Howell
e22a50a3e3 drafts: Use lists instead of dicts.
We were using a dict to return a sorted list of
formatted drafts, instead of building a list.
2018-12-16 15:46:41 -08:00
Steve Howell
29052b36a5 minor: Rename last_draft -> curr_draft. 2018-12-16 15:46:41 -08:00
Steve Howell
c82233c435 drafts: Avoid callback mechanism.
We had an anonymous callback for drafts that was
hard to read.  It's much easier to flatten the code,
give functions actual names, and stub them as needed
in the unit tests.
2018-12-16 15:46:41 -08:00
Tim Abbott
142d9cb63f report: Allow error-reporting views from unauthed users.
This should make it possible for blueslip error reports to be sent on
our logged-out portico pages, which should in turn make it possible to
debug any such issues as they occur.
2018-12-16 15:44:48 -08:00
Tim Abbott
9198fa4ec9 csrf: Improve API for when no CSRF input is available.
Since we're adding this to a large number of portico pages, there's no
guarantee that these pages actually have a CSRF input.

Though given that the logout template contains a CSRF input,
realistically it should always be present.
2018-12-16 15:35:54 -08:00
Tim Abbott
dbffa66b6d js: Extract csrf.js and include in common bundle.
This should make it possible to use this AJAX setup code in logged-out
code as well, which is necessary to use blueslip from portico pages.
2018-12-16 15:35:54 -08:00
Steve Howell
840210a0ba minor: Move setup_event_handlers() in code.
We place this code under populate_and_fill().

And instead of calling this at the end of
populate_and_fill(), we call it AFTER
populate_and_fill().
2018-12-16 14:38:28 -08:00
Steve Howell
e38496ddc0 drafts: Show active element clearly. 2018-12-16 14:38:28 -08:00
Tim Abbott
0779d343fa message_list: Fix handling of unknown email in mentions.
If a user has an old mention and has since been renamed, there's
really nothing for us to do to render it; we should just return as
though we have no data.
2018-12-16 14:36:26 -08:00
Marco Burstein
046ecc5d50 styles: Fix compose options hidden when editing.
Fix an issue that when a message is being edited, sometimes compose
options are hidden if there is no time limit. Also, move the options
further from the time limit to make them more noticeable.

Fix #11056.
2018-12-16 13:45:43 -08:00
Tim Abbott
fc7639ed39 docs: Update changelog with commits since 1.9.1 release. 2018-12-16 13:41:12 -08:00
Tim Abbott
9059c4d223 provision: Make apt/yum retry logic more coherent.
This changes a few things:
* Deplicates deps_to_install logic.
* Has a retry flag, under which we can guard the apt retry print statements.
* Makes the install_system_deps flow more parallel.
2018-12-16 13:41:12 -08:00
rht
c6cde1cf5c provision: Rename install_apt_deps to a more generic install_system_deps. 2018-12-16 13:39:00 -08:00
rht
389c46b4e5 provision: Extract yum-specific part of install_apt_deps. 2018-12-16 13:39:00 -08:00
rht
30834b7dd8 build-tsearch-extras: Abstract out postgres version. 2018-12-16 13:26:29 -08:00
rht
2be3065249 provision.py: Abstract out postgres version for CentOS. 2018-12-16 13:26:28 -08:00
rht
3afb299aec setup-yum-repo: Abstract out postgres version. 2018-12-16 13:21:55 -08:00
rht
43bedc0909 provision: Use vendored pg_hba.conf on CentOS. 2018-12-16 13:21:54 -08:00
Tim Abbott
728c601ff4 poll widget: Only show "Add option" if a question has been set.
This makes the UI less confusing.
2018-12-16 11:59:21 -08:00
Tim Abbott
5d31c57638 poll widget: Move the "Add option" feature below options.
This is the more normal ordering for a poll.  Fixes part of #11010.
2018-12-16 11:39:04 -08:00
Tim Abbott
f2173bc2a7 check-capitalization: Add a few exclude rules for new strings. 2018-12-16 11:34:31 -08:00
Steve Howell
35b904b184 subject -> topic: Fix subject in opts.
It's kinda difficult to track down all the interactions
with the opts that go through compose_actions.start(),
but I think I got everything.
2018-12-16 11:26:18 -08:00
Steve Howell
057ee6633a reload: Use "topic" to encode compose topic. 2018-12-16 11:26:18 -08:00
Steve Howell
9861cdfeb6 drafts: Use "topic" internally.
We still have to support "subject" for old drafts,
but we write "topic" for new drafts.
2018-12-16 11:26:18 -08:00
Steve Howell
9ba7b4fcbb drafts: Extract drafts.restore_message().
We make our deep-copy more explicit, change
the var name from draft_copy to compose_args,
and clean up some code formatting.
2018-12-16 11:26:16 -08:00
Steve Howell
d7aa5fcc38 compose: Remove obsolete references to replying_to_message.
The `replying_to_message` field was used in some
early versions of compose fade, but it has no more
use in the current code.

The drafts implementation didn't really make any sense,
anyway, as we were claiming to reply to the same
message we were drafting.
2018-12-16 11:26:02 -08:00
Tim Abbott
bdc4876948 notifications: Fix missing translation tags for above-compose alerts.
Apparently, these had never made it to being translated.  Since
they're an important part of the user experience, we add translation
tags for them now.
2018-12-16 11:14:09 -08:00
Tim Abbott
6c7725d21f notifications: Compute link earlier in mix notifications code.
This should make it more obvious how to later add a feature to include
a link for out-of-view-scroll-down notifications, should we ever want
that.
2018-12-16 11:02:52 -08:00
Vaibhav
372cb20f9e notifications: Notify when sent message is scrolled down in view.
A common source of confusion for new users is sending a message when
you're scrolled up in the message feed; in this case, it's nice to
communicate to the user why the message is not in view.

Fixes #10792.

Restructured by tabbott to replace overly complex logic for getting
the position of the new message with a `message_list.get_row()` call.
2018-12-16 10:59:25 -08:00
rht
022e926d64 provision: Setup services for CentOS. 2018-12-16 10:14:51 -08:00
rht
9c776f4fcf provision: Provide tsearch stopwords path for CentOS. 2018-12-16 10:14:08 -08:00
rht
8b5a86b992 provision: Initialize Postgres db on CentOS. 2018-12-16 10:11:55 -08:00
rht
41a5f6a49d provision: Create symlink for pg_* on CentOS. 2018-12-16 10:11:54 -08:00
rht
903bce9bdd provision: Install pycurl manually on CentOS.
This works around a pycurl bug on EL7 where the fix hasn't been
released yet.
2018-12-16 10:09:07 -08:00
rht
10786375db provision: Do not use apt-specific retry when a failure happens. 2018-12-16 10:04:27 -08:00
rht
25a8dbef11 provision: Build tsearch_extras from source for CentOS support. 2018-12-16 10:04:27 -08:00
rht
448303b3f0 provision: Initialize setup-yum-repo. 2018-12-16 10:04:27 -08:00
rht
85b2627191 provision: Add experimental support for CentOS. 2018-12-16 10:04:27 -08:00
rht
79bcb4af47 provision: Remove unused comment. 2018-12-16 10:04:27 -08:00
shubham-padia
3231306736 upgrade-zulip: Use deploy_options specified in zulip.conf.
Fixes #10534.
upgrade-zulip can now also accept the same deploy options as
upgrade-zulip-from-git and pass it as arguments to
upgrade-zulip-stage-2.
2018-12-16 07:52:47 -08:00
shubham-padia
29dce7c9b9 upgrade-zulip-from-git: Refactor deploy_options logic to zulip_tools.py.
This a preparatory commit moving the deploy_options logic to
zulip_tools.py so it can be imported and used in upgrade-zulip.
2018-12-16 07:52:47 -08:00
Tim Abbott
32f24bff8d stripe: Fix exception handling for suppressed event types. 2018-12-15 14:14:09 -08:00
Tim Abbott
930e65d1be push: Include type in add-push-notification events.
This should make us able to clean up the logic for this in the future
(right now, we still need to do the .get() for backwards compatibility).
2018-12-15 13:58:52 -08:00
Tim Abbott
008722b809 portico: Fix logic for whether a password field is present.
Now, we correctly avoid calling various password quality/strength
functions in the registration flow in the event that there isn't a
password form on the current page.

Before, some code wasn't inside a block at all, while other code was
using an incorrect check (an empty jQuery object is not falsey).

The overall result was that this would often crash on certain
pages/flows, stopping JS execution and causing various secondary
problems.
2018-12-15 13:58:38 -08:00
Steve Howell
a4c80089f3 page load: Fix two bugs related to muting/unreads.
The first bug fixed here has been around for a long
time--we were redundantly updating unread counts
indirectly via muting_ui.initialize(). The
unread counts also get updated in
unread_ui.initialize(), when we have more valid
state.  (And it's worth noting here that the unread
counts get updated yet again once message fetches
complete.)

The second bug was a very recent regression from
my recent stream name -> stream id cleanup in the
muting system.  We now depend on stream_data to
initialize muting data, so we need to initialize
muting.js slightly later in the process.

These fixes are intertwined, because they were both
somewhat caused by the anti-pattern of having
muting_ui.js initialize unread_ui.js and muting.js,
instead of doing more direct, fine-grained initialization
from ui_init.js.

Essentially we replace this code:

    exports.update_muted_topics = function (muted_topics) {
        muting.set_muted_topics(muted_topics);
        unread_ui.update_unread_counts();
    };

with this:

    exports.initialize = function () {
        exports.set_muted_topics(page_params.muted_topics);
    };

And the modules load like this:

    stream_data
    ...
    muting
    ...
    unread_ui

And we don't need any page-load initialization for muting_ui,
which is mostly used for Settings/Muted topics.
2018-12-15 13:44:30 -08:00
Steve Howell
625388ccf0 refactor: Call stream_data.initialize() more directly.
This function used to be called initialize_from_page_params(),
and we called it indirectly through `subs.js`.

Now we call it directly from `ui_init.js`, which gives us a
bit more control over how things are initialized.  In fact,
this sets us up for the next commit, where I fix a recent
regression I introduced.
2018-12-15 13:44:30 -08:00
Steve Howell
e0c8492464 node: Fix undefined senders in notifications test. 2018-12-15 11:13:31 -08:00
Steve Howell
401ac7702d node: Clean up node tests for notifications.
This is mostly about cleaning up the naming convention
for streams and topics, but it also adds a test that
specifically tests the muted-topic case (without any
other factors that would prevent a notification).

Before this commit, it was possible to change the
API for muting topics and get false positives, even
when the test setup was clearly broken.
2018-12-15 11:13:28 -08:00
ishanrai05
4105fb683b notifications: Optimize push notifications code path in tests.
This checks if push_notification_enabled() is set to false in
handle_push_notification and adds an early return statement.

This is a significant performance optimization for our unit tests
because the push notifications code path does a number of database
queries, and this migration means we don't end up doing those queries
the hundreds of times we send PMs or mentions in our tests where we're
not trying to test the push notifications functionality.

This should also have a small message sending scalability improvement
for any Zulip servers without push notifications enabled.

Tweaked by tabbott to fix a few small issues.

Fixes #10895.
2018-12-15 11:12:43 -08:00
Tim Abbott
a63eae48cc test_push_notifications: Fix leak that can leak to test flakes.
While reviewing #11012, I discovered a nondeterministic result for
test_signup, which I tracked down to specifically this triple of tests
failing when run in this order:

test-backend GCMSuccessTest \
  zerver.tests.test_push_notifications.TestAPNs.test_get_apns_client \
  zerver.tests.test_signup.LoginTest.test_register

with a query count mismatch like this:

expected length: 73
actual length: 79

Comparing the list of queries, it's clear that test_register was
seeing `push_notifications_enabled()` returning True in this test order.

It's not clear why GCMSuccessTest was required here (it was!), but
further debugging determined the problem was that
`test_get_apns_client` left the _apns_client initialization system in
a state where get_apns_client would return a non-None value, resulting
in push_notifications_enabled() returning True for future tests.

The immediate fix is to just reset the `_apns_client` and
`_apns_client_initializedstate` state properly after the test runs;
but arguably we should do a larger refactor to make this less
fragile.
2018-12-15 11:12:43 -08:00
Rishi Gupta
111eda604b portico: Add /atlassian for Zulip users migrating from HipChat. 2018-12-14 23:42:47 -08:00
Steve Howell
c8cee5d900 topic list: Remove unnecessary markup.
The data attribute here has some value if you're
inspecting the HTML in the browser, but it's not
worth the extra code.

All the list items have data-stream-id, so there's
no need for the parent to have it.
2018-12-14 16:05:40 -08:00
Steve Howell
012bb7b6c7 Use stream_id for by_stream__uri().
The stream_list test that was fixed here was sort of
broken.  It accomplished the main goal of verifying
what gets rendered, but now the data setup part is
more like the actual app code (and simpler, too).
2018-12-14 16:05:40 -08:00
Steve Howell
aea074e744 Use stream_id for by_stream_topic_uri(). 2018-12-14 16:05:40 -08:00
Steve Howell
7a22d47338 Use stream_id for mark-topic-read handler. 2018-12-14 16:05:40 -08:00
Steve Howell
87851b0db0 muting: Use stream_id in muting.get_muted_topics(). 2018-12-14 16:05:37 -08:00
Steve Howell
f18ce4f923 muting: Use stream_id in markup for action menus. 2018-12-14 16:05:37 -08:00
Steve Howell
d75ff80eb2 muting: Add stream_id to markup for mute settings.
We also prefer `attr` over `data` (it's more greppable).
2018-12-14 16:05:35 -08:00
Steve Howell
bf6f5e7bc5 muting: Pass stream_id to muting_ui.mute and unmute.
We temporarily allow settings_muting to have
incomplete line coverage--we will fix this soon.
2018-12-14 16:02:48 -08:00
Steve Howell
10b045f91b muting: Use stream_id as arg for notify_with_undo_option.
Also remove the unused meta.stream and meta.topic variables.
2018-12-14 16:02:40 -08:00
Steve Howell
ba04ec7e85 muting: Use stream_id for persist_mute/persist_unmute. 2018-12-14 16:02:37 -08:00
Steve Howell
a8718c9051 muting: Use stream_id for internal data structures.
This fixes the most core data structures inside of
muting.js.  We still use stream names for incoming
data to set_muted_topics and outgoing data from
get_muted_topics.

This will make us more resilient to stream name changes.
Before, if you were logged on when a stream rename
occured, topics that were muted under that stream would
appear to be unmuted.  (You could fix it with a reload,
but it can be jarring to have a bunch of unread messages
appear in your feed suddenly.)

Fixes #11033
2018-12-14 15:58:35 -08:00
Roger Souza
69da22d998 api docs: Document the custom emoji upload endpoint.
Tweaked by tabbott to fix some English phrasing and make the file
pointer thing require less Python knowledge.

Fixes: #10746.
2018-12-14 14:19:28 -08:00
Tim Abbott
67981725ec send_email: Fix migration code path for ScheduledEmail.
The previous migration code path was broken in two ways:

* ScheduledEmail objects generally contain a `None` value for
  whichever of `to_user_id` and `to_email` isn't in use; this could
  result in us sending a [None] to send_email(), which doesn't make
  sense.

* We were calling handle_send_email_format_changes in the wrong order
  with respect to the JSON loading process.

Thanks to Tom Daff for the report!
2018-12-14 12:46:31 -08:00
Tim Abbott
8c30c36006 realm filters: Expand set of characters allowed in prefixes.
Our list of allowed characters in realm filter patterns has long been
too string; fix this by extending the pattern.

Also, extend the tests to have examples of actual strings one would
use with the patterns, for clarity.

Fixes #10953, fixes #6835.
2018-12-14 11:33:13 -08:00
rht
501ae0c3d6 provision: Add centos7 postgresql dependencies. 2018-12-14 04:59:48 +00:00
rht
e8c602ec58 provision: Rename APT_DEPENDENCIES -> SYSTEM_DEPENDENCIES. 2018-12-14 04:59:48 +00:00
rht
d54fb5f40d provision: Add venv dependencies for Centos 7. 2018-12-14 04:59:46 +00:00
Vishnu Ks
0fd6ff722b billing: Migrate /upgrade endpoint to JSON.
The fixture changes are because self.upgrade formerly used to cause a page load
of /billing, which in turn calls Customer.retrieve.

If we ran the full test suite with GENERATE_STRIPE_FIXTURES=True, we would
likely see several more Customer.retrieve.N.json's being deleted. But
keeping them there for now to keep the diff small.
2018-12-13 17:01:12 -08:00
Rishi Gupta
647103a4e0 message visibility: Make stylistic improvements to history-limited-box. 2018-12-13 16:50:52 -08:00
Tim Abbott
d815e5a299 docs: Document how to sync additional fields in LDAP.
This probably isn't something folks will use a lot, but it is a
question we get.

Fixes #9710.
2018-12-13 16:24:15 -08:00
Tim Abbott
626e191201 ldap: Add support for automatic user deactivation/reactivation.
As part of this, extend our documentation on synchronizing data from
Active Directory.
2018-12-13 16:24:15 -08:00
Tim Abbott
81271b0d20 sync_ldap_user_data: Process deactivated users as well.
Technically, we will only need to process deactivated users for the
purpose of reactivating them (and can ignore, e.g., name changes).
But it's simplest to just process them unconditionally.
2018-12-13 16:24:15 -08:00
Tim Abbott
0a5221a819 ldap: Extract dev_ldap_directory.py.
This gets what is fundamentally unit testing code out of backends.py.
2018-12-13 16:24:15 -08:00
Rishi Gupta
fdf3114f59 help: Add decryption instructions for HipChat import. 2018-12-13 16:22:59 -08:00
Tim Abbott
5dd646f33f ldap: Add support for syncing avatar images from LDAP.
This should make life a lot more convenient for organizations that use
the LDAP integration and have their avatars in LDAP already.

This hasn't been end-to-end tested against LDAP yet, so there may be
some minor revisions, but fundamentally, it works, has automated
tests, and should be easy to maintain.

Fixes #286.
2018-12-13 13:39:22 -08:00
Cynthia Lin
c9b75a8a65 night mode: Alter compose warning background to fit night mode.
Fixes #10916.
2018-12-13 13:29:14 -08:00
Rishi Gupta
8a95526ced billing: Always transition to Realm.LIMITED via do_change_plan_type.
Fixes a bug in import_realm where secondary attributes like message
visibility weren't being set, and also makes bugs like this less likely in
the future.

Also, putting the plan_type change at the end of import_realm, so that
future restrictions to LIMITED realms don't affect the import process.
2018-12-13 13:26:24 -08:00
Rishi Gupta
b245c661da billing: Change do_change_plan_type to take a realm instead of a user.
More often than not, changes in plan type are not directly due to user
action.
2018-12-13 13:26:24 -08:00
Tim Abbott
e7746809d2 stripe: Fix exception handler for suppressed events.
Apparently, we incorrectly placed the try/except block around the
common code, not the code that can actually raise these exceptions.
2018-12-13 10:22:19 -08:00
Sumanth V Rao
76c6cf8c3a upgrade-zulip-stage-2: Added argument to skip purging old deployments.
This makes it possible to add --skip-purge-old-deployments in the
deploy_options section of /etc/zulip/zulip.conf, and control whether
old deployments are purged automatically on a system.

We still need to do https://github.com/zulip/zulip/issues/10534 and
probably also to add these arguments to be directly passed into
upgrade-zulip, but that can wait for future work.

Fixes #10946.
2018-12-13 10:10:43 -08:00
Steve Howell
08e315e962 minor: Remove unused stub in node test. 2018-12-13 10:07:56 -08:00
Tim Abbott
af78800525 node: Fix test failure introduced in last merge.
e5b3d39ce9.
2018-12-13 09:31:09 -08:00
Vishnu Ks
e5b3d39ce9 messages: Show banner when message history is limited.
This communicates to users clearly about the situation when the
history_limited flag is set by the backend (because message history
was cutoff).
2018-12-13 09:02:11 -08:00
Tim Abbott
1054d63820 message_fetch: Deduplicate logic for finish_newer_batch.
Like the other similar commits, we were doing the same work in all
code paths, just with a much more error-prone approach.

We can also now remove the now-unused finish_initial_narrow function.
2018-12-13 08:43:56 -08:00
Tim Abbott
ce187b0899 message_fetch: Deduplicate logic for start_newer_batch.
Like the other commits in this series, we were already doing this in
all of the callers of load_messages; this centralizes that logic in a
less ad-hoc feeling way.

We no longer use or need the start_initial_narrow function.
2018-12-13 08:43:56 -08:00
Tim Abbott
7febf724f3 message_fetch: Deduplicate logic for start_older_batch.
We were doing this work individually in all the callers of
load_messages; better is to just do it in one place.
2018-12-13 08:43:56 -08:00
Tim Abbott
9ccb3a2ad1 message_fetch: Deduplicate logic for finish_older_batch.
Previously, each individual caller of load_messages that passed
num_before > 0 would do its own manual management of fetch_status;
now, we just do it inside load_messages.
2018-12-13 08:43:56 -08:00
Tim Abbott
cd118bbc7e message_fetch: Track history_limited property. 2018-12-13 08:43:56 -08:00
Tim Abbott
b8a45d889e message_fetch: Fix home_msg_list older FetchStatus tracking.
Apparently, the older side of the FetchStatus object for home_msg_list
was incorrectly not being maintained.  We got away with this, because
the do_backfill code path (which runs after we're done with the
load_more cycle) will correct the error for found_oldest.  But we
didn't have proper handling for history_limited here.
2018-12-13 08:43:56 -08:00
Tim Abbott
ba6ef745fe message_fetch: Fix home_msg_list newer FetchStatus tracking.
When we're doing the load_more frontfill, we were not correctly
declaring that we were in the process of doing a fetch.  Because the
next load_more call clears this state anyway, this was generally a
short race, off-screen, but it is still a data flow bug.

See the upcoming commits for a refactor that will eliminate the
possibility of this sort of bug.
2018-12-13 08:43:56 -08:00
Tim Abbott
a6ca95dfc4 slack import: Fix all messages being imported to one channel.
This was an ugly variable-escape-from-loop regression introduced in
e59ff6e6db.
2018-12-12 17:54:37 -08:00
Vishnu Ks
8a1794caa3 message: Store the value of first_visible_message_id in Realm table.
This eliminates a bunch of potentially buggy caching code, with no
material negative side effects.
2018-12-12 15:11:17 -08:00
Tim Abbott
ee901ac8b1 django: Remove the Django contrib Sites app to fix 2FA QR codes.
Apparently, Django's get_current_site function (used, e.g., in
django-two-factor to look up the domain to use in QR codes) first
tries to use the Sites framework, and if unavailable, does the right
thing (namely, using request.get_host()).

We don't use the Sites framework for anything in Zulip, so the correct
fix is to just remove it.

Fixes #11014.
2018-12-12 15:01:55 -08:00
Tim Abbott
982a70431f message_list_view: Rerender mentions when user names change.
When a user's name is edited, currently we still show the old name is
mentions (though clicking on the item does the right thing).

However, at present, it creates a new problem in search results, where
the highlighting is removed by this substitution.
2018-12-12 13:38:12 -08:00
Tim Abbott
d6217eb862 slack import: Fix empty values for custom profile fields.
The Slack import process would incorrectly issue
CustomProfileFieldValue entries with a value of "" for users who
didn't have a given CustomProfileField (especially common for the
"skype" and "phone" fields).  This had no user-visible effect, but
certainly added some clutter in the database.
2018-12-12 12:58:27 -08:00
Tim Abbott
5d5b1afd2d rate_limiter: Improve handling of deadlocks.
We should rate-limit users when our rate limiter deadlocks trying to
increment its count; we also now log at warning level (so it doesn't
send spammy emails) and include details on the user and route was, so
that we can properly investigate whether the rate-limiting on the
route was in error.
2018-12-12 12:19:01 -08:00
Tim Abbott
e92e982342 docs: Add a troubleshooting note about cookies on root domain. 2018-12-12 12:08:25 -08:00
Tim Abbott
8a11c94a2d fakeldap: Add thumbnailPhoto/jpegPhoto for testing avatar syncing. 2018-12-12 11:23:33 -08:00
Tim Abbott
b5e65a2ea0 fakeldap: Move fakeldap configuration into ZulipLDAPAuthBackendBase.
This allows us to use this for testing the ZulipLDAPUserPopulator code
as well.
2018-12-12 11:07:05 -08:00
Tim Abbott
33fb750275 fakeldap: Invert order of loop/conditionals.
This is about to save us some work when we add image attributes.
2018-12-12 10:46:54 -08:00
Tim Abbott
e9900b2bdf gitter: Do something reasonable with invalid fullnames. 2018-12-12 10:07:52 -08:00
Tim Abbott
27f3919259 push_notifications: Also treat ConnectionError as a retry.
It's a bug that the HTTP20 library isn't catching these, but we just
have to work around it.
2018-12-12 09:40:51 -08:00
Tim Abbott
914ae88c62 push_notifications: Expand APNS main try/except block.
We should be catching exceptions trying to send the notice as well as
in the result section.
2018-12-12 09:40:51 -08:00
Anders Kaseorg
149132348f lint: Update ShellCheck to 0.6.0.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2018-12-12 08:24:01 -08:00
Roman Godov
9c8eeaed85 digest_email: Add endpoint for rendering digest to the web.
Adds "/digest/" endpoint for rendering content of digest email
to the web.

Fixes #9974
2018-12-11 13:38:30 -08:00
rht
a0b0ccf972 provision: Do not require lsb_release for centos. 2018-12-11 13:08:27 -08:00
rht
e0ec288928 parse_lsb_release: Add CentOS support. 2018-12-11 13:08:26 -08:00
rht
c9d54f7854 puppet: Remove vendored puppetlabs apt and stdlibs dependencies.
This commit works by vendoring the couple functions we still use from
puppetlabs stdlib (join and range), but removing the rest of the
puppetlabs codebase, and of course cleaning up our linter rules in the
process.

Fixes #7423.
2018-12-11 13:03:26 -08:00
rht
d2aa81858c puppet/zulip_ops: Replace apt::source with setup-apt-repo-debathena.
Tweaked by tabbott to use a clearer name.
2018-12-11 13:02:56 -08:00
rht
711b0fda8b scripts: Initialize setup-apt-repo-debathena. 2018-12-11 13:01:26 -08:00
rht
97766102df puppet/zulip: Replace apt::source and apt::ppa with setup-apt-repo. 2018-12-11 13:01:26 -08:00
Vishnu Ks
c3aa7909ce docs: Update docs/git/ directory to reflect CI changes.
This isn't complete, in that we still need to rename the ReadTheDocs
articles (e.g.).
2018-12-11 12:46:18 -08:00
Tim Abbott
15d4b71e2e decorator: Skip rate limiting when accessing user uploads.
The code paths for accessing user-uploaded files are both (A) highly
optimized so as to not require a ton of work, and (B) a code path
where it's totally reasonable for a client to need to fetch 100+
images all at once (e.g. if it's the first browser open in a setting
with a lot of distinct senders with avatars or a lot of image
previews).

Additionally, we've been seeing exceptions logged in the production
redis configuration caused by this code path (basically, locking
failures trying to update the rate-limit data structures).

So we skip running our current rate limiting algorithm for these views.
2018-12-11 12:43:21 -08:00
Tim Abbott
9f8cc925b8 i18n: Update translation data from Transifex. 2018-12-11 11:31:00 -08:00
Tim Abbott
b7127a395b server_settings: Use a reasonable default when User-Agent not specified.
Apparently, some Zulip clients don't send a User-Agent in their
requests to /server_settings, and this makes that not 500.
2018-12-11 11:30:11 -08:00
Tim Abbott
2a39852e91 auth: Add logging for which client does /server_settings requests.
This is generally helpful for debugging.
2018-12-11 11:30:11 -08:00
Tim Abbott
88368996fb decorator: Rename remote_server_request to skip_update_user_activity.
This makes it reasonable to call process_client from other contexts,
like /server_settings, where we don't have an authenticated
UserProfile object.
2018-12-11 11:30:11 -08:00
Tim Abbott
0d48f47eba scripts: Make setup-apt-repo a no-op if nothing has changed.
This performance optimization is important for being able to run this
from puppet in our production environment.
2018-12-10 17:36:28 -08:00
rht
05c4855cc9 circleci: Merge install dependencies step of trusty setup into the rest. 2018-12-10 17:06:37 -08:00
Steve Howell
dfddb0a636 left sidebar: Remove unneeded overlay code.
These handlers are not reachable if overlays are
open.
2018-12-10 16:55:25 -08:00
Tim Abbott
14bfa74069 registration: Enable copying profile settings in production.
Now that we've styled this feature properly, this makes it possible to
copy various user-preferences type profile data in production when
making a new account with the same email address as an existing
account.
2018-12-10 16:55:07 -08:00
Tim Abbott
354109e5e9 casper: Fix test broken by recent signup refactor. 2018-12-10 16:55:07 -08:00
Max Nussenbaum
536de666df register: Style avatar that shows when importing settings.
This styles the avatar and username that show when the registering
user is importing their settings from an existing Zulip account.

Tweaked by tabbott to fix the test/linter failures, a bit of styling,
and tag strings for translation.
2018-12-10 15:40:30 -08:00
rht
de9cefff8c circleci: Use CIRCLE_JOB env var for distro in cache filenames.
This lets us remove the ugly _dist.txt hack from our CircleCI
configuration.
2018-12-10 15:12:47 -08:00
Jack Zhang
be9b6a6dee compatibility: Add a compatibility check to api_get_server_settings.
This should make it convenient for the mobile app to present errors of
the form "Your Zulip app is not new enough for this Zulip server".
2018-12-10 15:06:09 -08:00
Jack Zhang
8711fe7bae compatibility: Respond with HTTP 400 when no User-Agent header.
Prior to this commit, a request to /compatibility without a User-Agent
header would result in the server 500ing.
2018-12-10 15:04:34 -08:00
Vishnu Ks
a86faecff5 tools: Rename tools/travis directory to tools/ci. 2018-12-10 11:07:26 -08:00
Tim Abbott
a1d99adce7 auth: Handle SSO_APPEND_DOMAIN in remote_user SSO for mobile.
Apparently, while the main code path through
login_or_register_remote_user was correctly calling
remote_user_to_email(username) to get a proper email address for
situations where auth username != email (i.e. when SSO_APPEND_DOMAIN
is set), we neglected to do so in the mobile_flow_otp corner case.

Fixes #11005.
2018-12-10 10:36:15 -08:00
Aditya Jain
8f0ccdf1c9 user settings: Fix active background links when a modal is visible.
A bug caused background links to open even when a modal in the user
settings overlay was active in the foreground. This commit fixes this
by disabling mouse events for the background when the modal is active,
and restoring them as soon as the modal starts closing.

Fixes #10654.
2018-12-09 22:32:53 -08:00
Akash Nimare
b90eeee1ec stream: Vertically align check icons on the left of streams list. 2018-12-09 22:25:36 -08:00
konraddeka
e6be407e34 provision: Avoid spending time on update-authors-json.
This optimizes tools/provision by not running
`tools/update-authors-json --use-fixture` unless either the script
itself or its fixtures file (zerver/tests/fixtures/authors.json) was
changed.

Fixes #10991.
2018-12-09 22:21:51 -08:00
neiljp (Neil Pilgrim)
63768858ff dependencies: Upgrade mypy to version 0.650.
Broaden the type of the AbstractEnum __reduce_ex__ parameter to object; this
matches the parameter type specified in the latest enum.pyi file in typeshed.

Fixes #10996.
2018-12-09 22:20:12 -08:00
rht
9bfea2adba provision.py: Translate COMMON_APT_DEPENDENCIES to yum. 2018-12-09 21:54:02 -08:00
rht
37d2a831d3 docs: Use shorthand name for the Centos EPEL release. 2018-12-09 21:53:59 -08:00
Amadeo234
38aa44ef31 message_edit: Fix tab navigation to "Close" button.
This adds a line to static/js/hotkey.js for focusing the "Close"
button.  Tweaked by tabbott to make more clear that we don't expect
there to ever be both a close button and a save button, since in that
case this code would be busted.

Fixes: #3830.
2018-12-09 21:50:39 -08:00
Sumanth V Rao
7d12e2019d provision: Generate static bots files using a function call.
This shaves about 350ms from the no-op provision runtime.

Fixes #10990.
2018-12-09 21:44:45 -08:00
Sumanth V Rao
cae718f184 provision: Rename generate_zulip_bots_static_files to .py.
This should make it possible to call this script as a function without
starting up a new Python interpreter.
2018-12-09 21:42:40 -08:00
Steve Howell
d7c2577ffb subject -> topic: Rename compose fields.
The stream/topic edit areas now have these ids:

        #stream_message_recipient_stream
        #stream_message_recipient_topic

They are pretty verbose, but being able to grep
for these without noise does have some value.
2018-12-09 21:28:45 -08:00
Marco Burstein
ba46dc83c6 notifications: Add a setting for changing the notification sound.
Also, add a new notification sound, "ding". It comes from
https://freesound.org, where the original Zulip notification sound comes
from as well. In the future, new sounds can be added by adding audio
files to the `static/audio/notification_sounds` directory.

Tweaked significantly by tabbott:
* Avoided removing static/audio/zulip.ogg, because that file is
  checked for by old versions of the desktop app.
* Added a views check for the sound being valid + tests.
* Added additional tests.
* Restructured the test_events test to be cleaner.
* Removed check_bool_or_string.
* Increased max length of notification_sound.
* Provide available_notification_sounds in events data set if global
  notifications settings are requested.

Fixes #8051.
2018-12-09 21:25:30 -08:00
Realmagnum
7026a8c574 docs: Fix typo in russian.md. 2018-12-09 21:11:48 -08:00
Tim Abbott
5b8997754c docs: Update GSoC ideas list to be current for 2019.
A bunch of details were out of date about the current state of Zulip
and thus what projects make sense; while this isn't likely to be our
final 2019 ideas list, this should help avoid confusion about what's
happening.
2018-12-07 17:14:04 -08:00
Tim Abbott
9423f8e31c node cache: Don't shell out to yarn to get the version.
This can easily be done by just reading the package.json file and
extracting the version value, just like we now do in install-node.
2018-12-07 14:44:52 -08:00
Tim Abbott
630968b632 provision: Use a more efficient approach for getting yarn version.
Since yarn has a package.json conveniently available, we can parse
that with jq, saving the expensive operation of starting up yarn.

This saves ~300ms in a no-op provision.
2018-12-07 14:36:54 -08:00
rht
a1ca8c262a setup-apt-repo: Add set -e and ensure the sources file exists. 2018-12-07 14:00:59 -08:00
rht
a1ff44a230 refactor: Add a helper function to create s3 buckets.
This refactor makes upgrading boto to boto3 easier.
Based on 43d2f6286c
2018-12-07 13:58:11 -08:00
Tim Abbott
b218c2a70e loadbalancer: Use same certbot cert for zulipstaging.com.
This is a simple configuration improvement.
2018-12-07 13:43:21 -08:00
Tim Abbott
467694c1fa nginx: Enable http2 in external nginx configuration.
This should be a nice performance improvement for browsers that
support it.

We can't yet enabled this in the Zulip on-premise nginx configuration,
because that still has to support Trusty.
2018-12-07 13:43:02 -08:00
Tim Abbott
b2939cdf19 lint: Fix comma spacing in node tests.
I apparently failed to check the tests codebase before merging the
last linter commit.  Oops.
2018-12-07 13:14:28 -08:00
Tim Abbott
838dd6d273 lint: Add eslint enforcement for comma-spacing.
We've been enforcing this manually for a long time, and hadn't
realized it was missing from our eslint configuration.
2018-12-07 12:22:24 -08:00
Tim Abbott
46d0ecdfe8 css: Organization account-settings specific CSS.
This puts most of our account-settings specific CSS into a single
block for better readability.
2018-12-07 12:07:34 -08:00
Akash Nimare
e827e36429 settings: Show current user's role in Your Account.
This makes it easier to figure out what's going on if you're a guest.

Fixes: #10969.
2018-12-07 12:07:12 -08:00
Steve Howell
78e20c82a8 settings: Handle back button within settings/orgs panels.
The Casper code that I eliminated here seems to be
bogus, in that I don't think it really waited for
all the clicks.

I **think** the intent of the test was to verify that
when you leave settings and go back into it, it remembers
the panel.  I was able to verify this manually.
2018-12-07 11:45:25 -08:00
Steve Howell
3544688b35 settings: Call replaceState() when entering settings/orgs.
We have an upcoming change that lets us use the
back button after going arrowing through multiple
settings pages.

Without first adding this commit, we would have an
infinite loop when you came back to '#settings' and
then '#settings' would rewrite the url with the current
hash.

Just replacing the browser state allows the browser
to do the right thing.

The history protocol is pretty well supported:

    https://caniuse.com/#search=history
2018-12-07 11:45:23 -08:00
Steve Howell
2a1a55af8a settings: Streamline how we launch settings.
We can eliminate the janky `setup_page` methods
and just pass in section from `hashchanged`.

This sets us up to handle browser history more
nicely when you load '#settings' and we could essentially
redirect you to '#settings/your-account' (or similar
things).  A future commit will address that.

We also use `launch` as the new entry point, which
is more consistent with other modules.
2018-12-07 11:40:56 -08:00
Steve Howell
5a4a357afc cosmetic: Use early-return instead of else/if. 2018-12-07 11:40:56 -08:00
Steve Howell
3acc6fe080 settings: Extract admin.build_page(). 2018-12-07 11:40:54 -08:00
Steve Howell
b9aecabdb7 settings: Extract settings.build_page(). 2018-12-07 11:40:50 -08:00
Steve Howell
fcf31cedbc settings: Extract gear_menu.update_org_settings_menu_item().
The prior name of this was a bit inaccurate, as we no
longer ever hide the menu item for non-admins.  Also,
it belongs more naturally in `gear_menu.js` at this point.

Also, we remove one call to this, which was in a place
where it was no longer necessary.
2018-12-07 11:40:40 -08:00
Steve Howell
1d07d0a532 settings: Extract admin_sections.maybe_disable_widgets().
We now run the code to disable widgets every time
we reload a section, which was the original intention
of the code, but the call to it only happened when
you first launched the page.

We also continue to run this logic for live updates
of is_admin, although it's worth noting that the
code still only handles the "demotion" case of going
from admin to non-admin. (If somebody makes you an
admin, you continue to need to reload to get
widgets enabled.)
2018-12-07 11:40:37 -08:00
rht
a0dbcde063 export_files_from_s3: Move saving s3 object to local file to a separate function.
This refactor makes upgrading boto to boto3 easier.
Based on 24bf813e8a
2018-12-07 11:37:46 -08:00
rht
0ddb242583 export_files_from_s3: get s3 object info in dict to a separate function.
This refactor makes upgrading boto to boto3 easier.
Based on 24bf813e8a
2018-12-07 11:37:46 -08:00
rht
1cecf0f142 export_files_from_s3: Move checking for s3 oject's metadata to a separate function.
This refactor makes upgrading boto to boto3 easier.
Based on 24bf813e8a
2018-12-07 11:37:46 -08:00
Akash Nimare
1dc741b963 help: Fix left sidebar content in smaller window.
This fixes an issue where some of the content of left
sidebar gets visible even in smaller window which looks ugly.

Fixes: #10898.
2018-12-07 08:20:45 -08:00
Steve Howell
b5645848d6 minor: Move line of code to set default language.
There was no reason for this code to be separated
from similar lines of code.
2018-12-07 08:04:09 -08:00
Steve Howell
ead356971c hashchange: Pass in a "section" to subs.change_state.
We also eliminate get_hash_components() and clean up the
code a bit in change_state().
2018-12-07 08:03:55 -08:00
Steve Howell
a2fd901bec hashchange: Add hash_util.get_hash_section().
We'll use this mostly for streams/settings URLs at first.
2018-12-07 08:03:41 -08:00
Steve Howell
7cbf031f18 hashchange: Add warning if pushState is not available. 2018-12-07 08:03:39 -08:00
Steve Howell
0914037bed hashchange: Extract get_full_url(). 2018-12-07 08:03:29 -08:00
Steve Howell
ef77496897 hashchange: Use '#streams/subscribed' from the gear menu.
If you go to "Manage streams" in the gear menu,
it's now a direct link to '#streams/subscribed'
instead of just '#streams'.  This makes our
back button behavior more predictable.
2018-12-07 08:03:24 -08:00
Steve Howell
a39c7096c0 hashchange: Use overlays.close_active() in a few places.
The `change_tab_to` calls are a relic of very
early versions of Zulip.
2018-12-07 08:03:20 -08:00
Steve Howell
6d22634e56 streams: Remove subs.show_and_focus_on_narrow().
We stopped calling this in this commit:

    3d77aa49db

We also remove its helper function and the obsolete
event that only it was looking for.
2018-12-07 08:03:14 -08:00
Steve Howell
75bdd2c62c hashchange: Remove unreachable code for drafts.
I missed this in an earlier commit where I swept
the overlays for unreachable code.
2018-12-07 07:39:51 -08:00
Joshua Pan
bc74abae41 user_events: Create delivery_email update event procedure.
This ensures the "account settings" UI for managing a user's own email
address uses the delivery email, since that's what users care most about.

Eventually, we'll need to add support for at least viewing both email
addresses in "account settings", but this is the right long-term
behavior.
2018-12-06 20:09:57 -08:00
Joshua Pan
441dca0eaf email: Support delivery email in email change system. 2018-12-06 17:43:26 -08:00
Tim Abbott
5c2e7a169f test_events: Use a better assertion when comparing event count. 2018-12-06 17:43:26 -08:00
Tim Abbott
7e6f30caab actions: Extract send_user_email_update_event.
This will make it easy for us to reuse this event-sending logic for
the email_address_visibility change code path.
2018-12-06 16:26:46 -08:00
Tim Abbott
e603237010 email: Convert accounts code to use delivery_email.
A key part of this is the new helper, get_user_by_delivery_email.  Its
verbose name is important for clarity; it should help avoid blind
copy-pasting of get_user (which we'll also want to rename).
Unfortunately, it requires detailed understanding of the context to
figure out which one to use; each is used in about half of call sites.

Another important note is that this PR doesn't migrate get_user calls
in the tests except where not doing so would cause the tests to fail.
This probably deserves a follow-up refactor to avoid bugs here.
2018-12-06 16:21:38 -08:00
Joshua Pan
67f0b1bbca admin: Add UI for editing realm_email_address_visibility.
This new setting is still hidden in the UI when not in the development
environment, because the feature isn't ready for production, but
merging this will help simplify future work on the feature.
2018-12-06 16:01:09 -08:00
Tim Abbott
9d32857c37 realm: Add new Realm.email_address_visibility field.
This is preparatory work for settings controlling who can see user
emails; it includes the API-level support for editing it, but no code
to actually enforce the policy.
2018-12-06 15:56:30 -08:00
Tim Abbott
7ddcbd0d3a analytics: Set delivery_email in hacky test user creation code. 2018-12-06 15:33:28 -08:00
Tim Abbott
b3a4b78c6d puppet: Pass zulip scripts path as a FACTER to puppet.
This makes it possible for the Puppet codebase to access the path to
the relevant /home/zulip/deployments type directory that puppet was
run from, which in turn makes it possible to safely call scripts from
here.

Based on work by Rein Zustand.
2018-12-06 11:38:55 -08:00
Tim Abbott
978b37379b team: Relabel Greg Price as mobile.
Since that's what he does these days.
2018-12-06 11:34:51 -08:00
Akash Nimare
1b18f8b896 team: Update list of core team members.
This removes Brock from the team section.
2018-12-06 11:34:51 -08:00
Akash Nimare
3bcb524d33 team: Add Desktop app team member to core team. 2018-12-06 11:34:51 -08:00
Rishi Gupta
82ee496efc webhooks/stripe: Update fixture for customer_subscription_created. 2018-12-06 11:29:16 -08:00
Rishi Gupta
76aebac568 webhooks/stripe: Format timestamps as dates. 2018-12-06 11:29:16 -08:00
Rishi Gupta
027d5e90c5 webhooks/stripe: Update how we handle updated events.
Also more explicitly ignores the Stripe Connect related events in the
'account' category.
2018-12-06 11:29:16 -08:00
Rishi Gupta
5fb683e788 webhooks/stripe: Use exceptions instead of json_success to exit main body. 2018-12-06 11:29:16 -08:00
Tim Abbott
9e48b2f17f provision: Update comment for why we need puppet in development.
This should help avoid confusion like #10972.
2018-12-06 11:13:04 -08:00
Tim Abbott
fc1c146d31 export: Remove assertion on current working directory.
This command hasn't made deep assumptions about CWD for a long time,
and this enables users to run it through a symlink (etc.).

Fixes #10961.
2018-12-06 11:05:40 -08:00
Tim Abbott
15e0304d95 settings: Compute STATIC_ROOT using absolute paths.
This makes it possible to use absolute paths to commands in a
development environment.
2018-12-06 11:05:40 -08:00
Tim Abbott
be0604dcf0 left sidebar: Show recipients in "private messages" hover.
When the list of recipients of a group private message conversation is
truncated due to being long in the "Private messages" area, we didn't
provide easy access to the full list of people.  Fix this by adding a
title attribute for the area.

Fixes #10978.
2018-12-06 10:23:10 -08:00
Tim Abbott
9da4b58c8e docs: Fix /help/ sidebar being accidentally missing.
Apparently, we didn't have a test for this, and it was broken in a
recent refactoring.
2018-12-06 10:13:51 -08:00
Vishnu Ks
55b875f6c9 portico: Check for GET params in realm_redirect.html. 2018-12-06 09:24:55 -08:00
Vishnu Ks
51b39901b9 portico: Add create organization link to goto realm page. 2018-12-06 09:24:54 -08:00
Vishnu Ks
18f90754da portico: Change wording of finding organization in /accounts/go. 2018-12-06 09:24:22 -08:00
Vishnu Ks
2a0b23df46 portico: Move goto account page styles to portico-signin.scss. 2018-12-06 09:23:13 -08:00
Vishnu Ks
18233654d0 plans: Change buy standard button url to /upgrade. 2018-12-06 09:23:13 -08:00
Tim Abbott
cc54dddd84 settings: Fix settings UI indicators for guest users.
This correctly shows guest users that they cannot interact with
anything in the "Organization" tab, though we preserve the read-only
access to it so that they can (e.g.) browse the organization's custom
emoji.
2018-12-05 17:41:48 -08:00
Tim Abbott
950d592279 docs: Remove outdated subsystems article on guest users.
This page was no longer up to date, and these details should be
covered in more user-facing sections of our documentation.
2018-12-05 17:41:44 -08:00
Tim Abbott
a4a25c3e14 docs: Expand security model documentation to cover guests.
This is a pretty minor update, just clarifying the discussion of what
types of users exist.
2018-12-05 17:25:12 -08:00
Tim Abbott
2507c90381 portico: Advertise support for HipChat import. 2018-12-05 17:07:47 -08:00
Rishi Gupta
ff6c81b0c3 billing: Change active users to users on /plans. 2018-12-05 16:38:37 -08:00
Tim Abbott
460249704e send_email: Fix cleanup for incorrectly migrated jobs.
This logic, unfortunately, had a typo.
2018-12-05 16:30:28 -08:00
Tim Abbott
1adc40f014 import: Deduplicate functions for uploading to S3/files.
We've had a long stream of bugs existed because only one of these two
code paths was tested (usually the local uploads backend).  By
deduplicating these functions, we ensure that this category of bugs no
longer happens.

Following my recent refactor, this is just a straightforward merge,
with code for one or the other backend ending up inside an if
statement.
2018-12-05 16:15:01 -08:00
Tim Abbott
c9b801efde import: Use the s3_path attribute for path_maps unconditionally.
While the s3_path is almost always the same as the path, structurally,
`path` is the location in the export object, whereas s3_path is the
URL path.
2018-12-05 16:15:01 -08:00
Tim Abbott
f4c5a45f4f import: Fix S3 paths for imported avatar PNG.
Previously, we were incorrectly importing avatar PNGs to a filename
without the .png extension, resulting in them effectively not being
imported.

This was mitigated by the fact that we imported the originals and ran
the appropriate `ensure_` functions, but still a bug.
2018-12-05 16:15:01 -08:00
Tim Abbott
412dc8dcda import: Set last_modified in import_uploads_local.
This has no effect other than to make the S3 and local code paths more
nearly identical.
2018-12-05 16:15:01 -08:00
Tim Abbott
d8d0492d64 import: Restructure uploads path logic to be more similar.
This is preparation for future deduplication of the two redundant
uploads backends.
2018-12-05 16:15:01 -08:00
Tim Abbott
671ceccd78 import: Deduplicate medium avatars special logic.
This requires a bit of care with upload_backend to avoid breaking how
we mock that class in our tests.
2018-12-05 16:15:01 -08:00
Tim Abbott
36b43a6d7a import: Deduplicate first block of import_uploads logic. 2018-12-05 16:15:01 -08:00
Tim Abbott
f80bab58c0 import_realm: Add progress indicator for importing uploads.
This makes it easier to see how we're doing when uploading a very
large number of files.
2018-12-05 16:15:01 -08:00
Tim Abbott
9e06ab45bf webhooks: Fix HttpResponse with notify_bot_owner_on_invalid_json.
Apparently, there was a bug in notify_bot_owner_on_invalid_json, where
we didn't reraise the JsonableError.

We fix this with a refactoring that makes the exception layering
clearer as well.
2018-12-05 15:17:31 -08:00
Tim Abbott
9de1bd44e2 compatibility: Clean up linter logic for too-old client. 2018-12-05 15:04:21 -08:00
Greg Price
32c6b81b3a compatibility: Add test data from real server logs.
In a quick scan of today's nginx logs on chat.zulip.org, there
were 20 distinct user-agents that begin with 'ZulipMobile/'.
Here's a representative sampling of them, such that the rest
were all boringly similar to one of these.

First, to make room for these without an excess of copy-paste and
overlong lines, convert this test to a data-oriented style.  The
existing, synthetic cases appear in the new data followed by the
seen-in-the-wild cases.

Happily, the code being tested passes all these new cases unchanged.
2018-12-05 14:58:13 -08:00
Greg Price
fb7bfbe9ab compatibility: Require version 16.2.96+ for our Android app.
This release is from 2018-08-22, a little over 100 days ago.

It was the first release with the important fix so that when the
server advises it to stop displaying a notification because the user
has read the message (as the SEND_REMOVE_PUSH_NOTIFICATIONS server
setting enables), the app doesn't instead replace the notification
with a broken one reading "null".  We have that setting running now
on chat.zulip.org, and intend to roll it out more broadly soon.

The `# take 0` thing is a slightly absurd workaround for the fact
that our funky out-of-line way of marking lines to ignore doesn't
work right if there are multiple such lines in a given file that
are equal modulo leading and trailing whitespace.
2018-12-05 14:58:13 -08:00
Greg Price
0fa4fdcff9 compatibility: Rewrite verbose test for compact legibility.
This will facilitate adding a bunch more test cases shortly.
2018-12-05 14:58:13 -08:00
Greg Price
2bac6de6c6 compatibility: Add and test a helper find_mobile_os. 2018-12-05 14:58:13 -08:00
Greg Price
1859faccb7 compatibility: Treat empty version as unknown, not old. 2018-12-05 14:58:13 -08:00
Greg Price
ebfa4b746d compatibility: Make 1.2 < 1.2.3; rewrite version_lt internals. 2018-12-05 14:58:13 -08:00
Greg Price
557aca2aa7 compatibility: Implement a version comparator. 2018-12-05 14:58:13 -08:00
Greg Price
60de598cb5 user_agent: Use re.X to make the regex a little more readable. 2018-12-05 14:58:13 -08:00
Tim Abbott
cfeb87c1c9 tornado: Require non-negative lifespan_secs.
Previously, our validation for this field only checked it was an
integer, and you could in theory send invalid negative values here.
2018-12-05 14:50:37 -08:00
Tim Abbott
8e4d6fa045 event_queue: Rename IDLE_EVENT_QUEUE_TIMEOUT_SECS.
This is a default value, not an always-used value, and its name should
reflect that.
2018-12-05 14:48:40 -08:00
Tim Abbott
94dfff1c4e event queue: Don't set a minimum for lifespan_secs.
This makes it more convenient for developers to set very short values
for this (e.g. 1 minute) for the purposes of testing/debugging; there
aren't obvious problems with letting users set short values for this.
2018-12-05 14:47:53 -08:00
Tim Abbott
a3c2d49f0c event_queue: Change garbage-collection frequency to 1 minute.
This is designed to help make it more convenient to do manual testing
where we need event queues to be garbage-collected.
2018-12-05 14:42:53 -08:00
Tim Abbott
6dd69b9bff event_queue: Rename ClientDescriptor.idle to expired.
This better reflects the situation with these event queues -- they're
not idle, they are expired and to be garbage collected.
2018-12-05 14:42:53 -08:00
Tim Abbott
408af032a0 event_queue: Remove queue_timeout migration code from 2013.
There's never going to be an event queue without a queue_timeout
property anymore.
2018-12-05 14:24:38 -08:00
Archit Kaushik
5254d77b7c onboarding: Fix help text overflow on new organization registration page.
Fixes #10866.
2018-12-05 12:44:32 -08:00
Tim Abbott
6689913f77 ci: Enable test-documentation --skip-external-links in CI.
Fixes #10942.
2018-12-05 12:39:59 -08:00
Sumanth V Rao
e1f33e0f6b test-documentation: Add --skip-external-links option.
This option causes test-documentation to only verify internal links
that we control and are important to be correct.  This prevents
test-documentation from flaking in CI due to issues with the dozens of
third-party blocks that we link to from various parts of our
documentation.

Tweaked by tabbott for comment clarity, and to also include
github.com/zulip links.

Fixes #10942.
2018-12-05 12:39:59 -08:00
rht
8ed4933005 setup-advanced: Fix a subsubsection header formatting. 2018-12-05 12:24:15 -08:00
Akash Nimare
3d935a957c Merge pull request #10963 from akashnimare/desktop-snap-guide
help: Add installation guide for snap installer.
2018-12-05 12:22:58 -08:00
rht
e59ff6e6db slack import: Eliminate need to load all messages into memory.
This works by yielding messages sorted based on timestamp.  Because
the Slack exports are broken into files by date, it's convenient to do
a 2-layer sorting process, where we open all the files for a given
day, and then sort their messages by timestamp before yielding them.

Fixes #10930.
2018-12-05 12:20:50 -08:00
Tim Abbott
0ff3a7da05 circleci: Document the story with hashing the distribution name. 2018-12-05 12:03:41 -08:00
rht
3c91c9c927 circleci: Remove unused spaces and a useless comment.
With the new names, we really don't need the comment.
2018-12-05 12:03:17 -08:00
rht
93ef3795b4 circleci: Use alias for save cache. 2018-12-05 11:48:41 -08:00
rht
d2454142da circleci: Use alias for restore cache. 2018-12-05 11:48:41 -08:00
rht
53ec6ab45e circleci: Use alias for upload coverage report. 2018-12-05 11:48:41 -08:00
rht
badc0eff0d circleci: Use alias for run frontend tests. 2018-12-05 11:48:41 -08:00
rht
83424381cd circleci: Use alias for run backend tests. 2018-12-05 11:48:41 -08:00
rht
c476f0eca0 circleci: Use alias for install dependencies. 2018-12-05 11:48:41 -08:00
rht
2fe128d8e9 circleci: Use alias for create cache directories. 2018-12-05 11:48:41 -08:00
Tim Abbott
f5f320d5fc mypy: Print out link to documentation in error output.
This should help make details about how mypy works discoverable for
developers who are new to it.
2018-12-05 11:23:55 -08:00
Tim Abbott
f694d01a1b test-backend: Expand desired files with full test coverage.
This should help catch a few classes of files that we weren't
correctly considering for potentially having full test coverage.
2018-12-05 11:01:55 -08:00
Tim Abbott
380231af9d push_notifications: Add tests for BrokenPipeError case.
This was missing in d723dbfef7.
2018-12-05 10:44:25 -08:00
Tim Abbott
b47535d8bb push notifications: Fix exception when handling deleted messages.
If a user deletes message between when it triggered a potential push
notification for another user, and when that notification was actually
sent, we'd end up with a situation where the `Message` table didn't
have an entry for the requested message ID.

The clean fix for this is to still throw an exception in the event
that the message doesn't exist at all, but if it exists in
ArchivedMessage, don't throw a user-facing exception.
2018-12-05 10:38:37 -08:00
Tim Abbott
d723dbfef7 push_notifications: Handle BrokenPipeError from APNS.
This seems to happen when Apple is having a partial outage on some of
their APNS shards; it should be treated like other networking errors
connecting to APNS (with an automatic retry).
2018-12-05 10:02:18 -08:00
Tim Abbott
196ec78261 logging_handlers: Fix unnecessary broken import. 2018-12-04 18:18:07 -08:00
Jack Zhang
c26f5c6ee3 Rename check_compatibility to check_global_compatibility. 2018-12-04 17:56:12 -08:00
Jack Zhang
ce95973c22 Expand the comment contextualizing the /compatibility endpoint. 2018-12-04 17:56:12 -08:00
onkar shedge
ba7e78bc65 message_edit: Allow editing topics indefinitely.
Previously, Topic editing was offered in the UI even to message
senders and organizations admins only if the message was no more than
one day old.  This was correct for the "community topic editing" case,
but not for message senders and organization admins.

While we're at it, this also centralizes some previously haphazard
logic to always call message_edit.is_topic_editable().

Tweaked significantly by tabbott to fix the logic.

Closes #10568.
2018-12-04 17:41:21 -08:00
Tim Abbott
c21247abf9 Revert "Position sidebars with top instead of margin-top."
This reverts commit c4620af2161283fe2cff0ba8f89789211d02bbdd.

This broke the positioning of the permissions request layer when that
appears.
2018-12-04 17:26:37 -08:00
Steve Howell
44ef8baff1 hashchange: Add hash_util.get_hash_category().
This replaces hashchange.get_main_hash(), which had
a slightly misleading name.  Also, moving this to
hash_util forces us to keep 100% coverage on it.
2018-12-04 17:16:40 -08:00
Steve Howell
67fba69b0c hashchange: Go to home page for bogus narrows.
This was the original intent of the code, and I think
it's the right behavior.
2018-12-04 17:16:38 -08:00
Steve Howell
bcb142e68e hashchange: Move parse_narrow to hash_util.js.
The goal here was to enforce 100% coverage on
parse_narrow, but the code has an unreachable line
and is overly tolerant of bogus urls.  This will
be fixed in the next commit.
2018-12-04 17:16:32 -08:00
Steve Howell
dac543891f hashchange: Move functions around in file.
This just puts similar functions near each other.
2018-12-04 17:16:29 -08:00
Steve Howell
d9439e819e hashchange: Remove block comment.
This comment is less necessary now that we have docs
and have cleaned up the code a bit.
2018-12-04 16:13:18 -08:00
Anders Kaseorg
9ba860b4f2 Avoid double redirects to /login and then to /login/.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2018-12-04 16:12:58 -08:00
Tim Abbott
02a79b677b send_email: Extract handle_email_format_changes and use.
Apparently, we have a second code path where we might try to call
send_email library functions on old data, namely in the
queue_processors codebase.  So we apply the same migration logic here.
2018-12-04 16:08:18 -08:00
Tim Abbott
d5f2eb3790 Revert "buddy list: Put "me" at the top of the list."
This reverts commit 1890c30ee1.
2018-12-04 16:08:18 -08:00
Rohitt Vashishtha
ee3b4f3ee9 hotkeys: Map CTRL + . to narrow to compose box target.
Also adds relevant tests and documentation. We currently
do not narrow to a new topic, and instead just narrow to
the stream. Similarly, we do not narrow to a PM if any of
the recipients are invalid.
2018-12-04 13:58:00 -08:00
Tim Abbott
3079cf803c Revert "typeahead: Tab opens typeahead if not open with a non-empty input."
This reverts commit 0e2c509a24.
2018-12-04 13:58:00 -08:00
Tim Abbott
9ea4f50c1b Revert "search: Open typeahead on empty string only if lookup triggered by Tab."
This reverts commit b961093c14.
2018-12-04 13:58:00 -08:00
Tim Abbott
250a2b5164 docs: Fix documentation details for boto configuration.
This fixes a couple key gaps in our documentation of the #9376
workaround.
2018-12-04 13:28:13 -08:00
Roger Souza
a0ca502f16 hello: Fix a header alignment issue when page is around 375px.
Fixes: #10771

This commit fixes the alignment of the header inside integration section
when page is around 375px of width.
2018-12-04 12:45:55 -08:00
Steve Howell
4af1061974 Remove unused expected_hash variable.
We stopped setting this nearly five years ago, as part
of bd9cccffce

The big conditional that I removed here should have
always evaluated to false, as I understand the code.
Presumably either the browsers handle # -> '' redirects
better now, or we address this somewhere else in our
codebase.
2018-12-04 12:24:39 -08:00
Steve Howell
a9391e0499 keydown_util: Ignore alt-arrow and similar things.
We ignore keystrokes like alt-left-arrow and alt-right-arrow,
so that the browser can do back/forward.

We may need to refine the handling of ctrl/alt/shift in the
future, but now we only support single-key operations.
2018-12-04 12:24:39 -08:00
Steve Howell
7a2527aed1 hashchange: Call stop_auto_scrolling() directly. 2018-12-04 12:24:39 -08:00
Steve Howell
6bfcebe6da Update hashchange docs and tweak function names.
This is mostly doc updates, and we also rename
a couple functions to have more consistent naming.
2018-12-04 12:24:39 -08:00
Steve Howell
1804d6c9ce Make back button work for some Settings/Org changes.
This change removes all the complexity around
get_hash_group(), and we now only go into the
"same overlay" logic within Settings or within
Manage Organization, but not between them.

This means if you're in Settings but hit the back
button to something under "#organization" we now
do "more stuff", since we want to err on the side
of reloading sections, etc.

There's not much flicker in my testing, and
this is not a super common transition, anyway.
2018-12-04 12:24:39 -08:00
Abhinav Singh
979fae0406 portico: Add autofocus to the first input field with errors.
This code brings the focus to the first input field with errors rather
than just the first input field present in the form after the sign up
form is rendered again after invalid data is submitted.

Note from tabbott: This still doesn't handle the ToS checkbox being
the source of the error, but that's an independent issue.

Fixes #10869.
2018-12-04 12:22:09 -08:00
Abhinav Singh
586ce70b8b portico: Auto-detect field to focus for registration page.
This replaces the manually-curated logic for which field to focus.
2018-12-04 12:22:09 -08:00
Vishnu Ks
a8113ae296 billing: Remove dont_mock argument from mock_stripe. 2018-12-04 12:19:57 -08:00
varunvaruns9
4ff25d0366 org settings: Add lock icon next to uneditable tabs.
Add a lock icon to the right of tabs on which nothing is editable
for normal users. Add lock next to Custom emoji option if only admin
can edit them.

Tweaked by tabbott to use title for the lock icons, rather than
aria-hidden, since they do convey useful information.

Fixes: #10893.
2018-12-04 09:50:39 -08:00
Tim Abbott
86536059b4 tools: Fix linter tests after SCSS rename.
This was introduced in 815388b023.
2018-12-04 09:43:56 -08:00
Vishnu Ks
fc4b6d8f5e auth: Redirect login to realm_redirect page instead of find_accounts. 2018-12-04 09:35:35 -08:00
Vishnu Ks
788b98d041 portico: Add page for redirecting to a realm subdomain. 2018-12-04 09:35:35 -08:00
Tim Abbott
815388b023 lint: Fix CSS linter rules not running.
Apparently, our CSS linter rules haven't been running since we
migrated to SCSS.
2018-12-04 09:35:34 -08:00
Vishnu Ks
6de6b0ed31 emails: Extract CSS to email.css in digest.html. 2018-12-03 17:43:53 -08:00
Tim Abbott
e7c5bc0cee lint: Fix broken whitespace in landing-page.scss.
This is a classic race between linter expansions and an old PR.
2018-12-03 17:42:52 -08:00
Eeshan Garg
901100bebf webhooks/jira: Decode topics on our end.
The problem addressed in 006e47198c
resurfaces with topics when a user provides a custom topic in the
webhook URL.
2018-12-03 17:37:36 -08:00
Aditya Bansal
7d0d4b5eec integrations: Start to use flex box for positioning in dropdown.
Positioning using flexbox makes life much easier for everyone. With
this change we make positioning of icon relative to the label in the
dropdown menu much easier to do and alter if required. We now no
longer need to fiddle with tedious pixel measurements for placing the
icon in the right place.

As a result of this commit we had to change a click event binding
back to be associated with .dropdown-toggle class rather than being
associated with the h3, i because of the re-arrangement of the
dropdown configs.
2018-12-03 17:29:47 -08:00
Aditya Bansal
7db1dc2434 integrations: Fix cursor changing to a pointer at the wrong location.
Basically cursor used to change to a pointer hand (which indicates
something clickable) in area around the actual dropdown.
2018-12-03 17:28:58 -08:00
Aditya Bansal
5875eea1b5 integrations: Fix alignment of categories dropdown with the lozenges.
The integration categories dropdown was too wide in comparison to
the category lozenges and hence this commit attempts to smooth up
the UI a bit on that front.
2018-12-03 17:28:58 -08:00
Aditya Bansal
9a9dd158c4 integrations: Fix behaviour of angle icon associated with the dropdown.
Here we just fix the behaviour of angle icon which is present
in the integration categories dropdown. It used to change direction
from down to right only if "All" options from the dropdown was
selected (which is also the initial and default option). This behaviour
was pretty inconsistent and looked odd. Rather than having a direction
changing icon here, it migth be just better to stick with just the
down facing angle arrow. Arrow direction in general represents in
which direction the dropdown is gonna open up (in addition to the
fact that a dropdown exits here).
2018-12-03 17:21:17 -08:00
Aditya Bansal
b32f54e775 integrations: Add animation to integrations dropdown.
We make the integration categories dropdown gradually slide down/up
rather than appearing instantenously. I believe this gives a better
look to the dropdown and how it behaves.

We also fiddle a bit with the code relating to angle icon in the
dropdown. Basically though its behaviour was already buggy and
will be addressed in an upcoming commit, we try to maintain whatever
behaviour it had before introduction of the annimation effect.
2018-12-03 17:21:17 -08:00
Aditya Bansal
11f896809f integrations: Fix issue with area from where dropdown can be toggled.
The issue here was that if we opened up integrations page in
responsive mode (so the integrations category sidebar turns into a
dropdown) and click a few centimeters outside the actual dropdown
or perhaps the dropdown menu when its open, it is possible to toggle
or select a integration category.
What this essentially means is that clicking in blank area outside
visible boundaries of dropdown menu its possible to interact with it.

Fix: We change elements on which the click event is tied to and
adjust a bit of CSS for relevant elements so things look as they
used to but function in correct or better manner.
2018-12-03 17:21:17 -08:00
Aditya Bansal
98cab354bd integrations: Fix buggy behaviour around categories dropdown.
What is the buggy behaviour?
Before this commit if you were to open the integrations docs page
in a smaller window so that the integrations categories sidebar
changed into a dropdown (so that our page is responsive to
screen size), one would notice that selecting a category from the
dropdown menu didn't make dropdown to auto collapse. This feels very
uncomfortable from users prespective since an ugly dropdown with all
the categories sticking around uncollapsed kind of defeats the purpose
of having a dropdown.

Fix: We make the categories dropdown toggle/auto collapse upon
selection of a category.
2018-12-03 17:21:17 -08:00
psg0796
90def916bc left-sidebar: Match line spacing of user list on left sidebar.
Vertically aligned presence indicator with names on left sidebar.

Fixes: #10554
2018-12-03 17:03:37 -08:00
Shubham Padia
b961093c14 search: Open typeahead on empty string only if lookup triggered by Tab.
Fixes part of #10026.
Adds additional option to typeahead:
`tabOpensEmptyTypeahead`(default: false):
tabOpensEmptyTypeahead overrides helpOnEmptyStrings.
This commit sets helpOnEmptyStrings to false and
tabOpensEmptyTypeahead to true. Now typeahead will
open on an empty string only if Tab has been pressed.
2018-12-03 16:54:38 -08:00
Shubham Padia
0e2c509a24 typeahead: Tab opens typeahead if not open with a non-empty input.
Fixes part of #10026.
NOTE: The Tab key will select option from typeahead if the typeahead
is already open i.e the same behaviour as Enter.
NOTE: This behaviour applies irrespective of search pills are enabled
or not.
2018-12-03 16:54:38 -08:00
dipu989
524ef509fe user settings: Fix download zuliprc button styling. 2018-12-03 16:30:58 -08:00
Tim Abbott
fa59573a65 mypy: Fix mypy errors in send_email logic.
mypy should be able to figure this out given the xor just above, but
it's not surprising that it doesn't.
2018-12-03 16:30:48 -08:00
Rishi Gupta
c21a05a3b1 billing: Zero out timestamps that aren't being tested.
f52e9d1 ended up not going far enough. Keeping f52e9d1 in place in case we
ever want to go back to that sort of solution.

Also removes the keep argument from test_billing_quantity_changes_end_to_end,
since that test is actually testing the arguments to
stripe.Subscription.save(), not what is returned by Stripe.
2018-12-03 16:25:21 -08:00
Rishi Gupta
2453ab2a21 billing: Normalize a few more fields in normalize_fixture_data. 2018-12-03 16:24:16 -08:00
Rishi Gupta
84f7a779c4 billing: Take advantage of re match notation in normalize_fixture_data.
No change in behavior; just visual code cleanup.
2018-12-03 16:24:16 -08:00
Rishi Gupta
f52e9d143b billing: Further normalize timestamps in tests.
Hopefully this will make it easier still to look at diffs with
GENERATE_STRIPE_FIXTURES = True.
2018-12-03 16:24:16 -08:00
Scott Lee
e542ff0e62 css: Clean up spacing in the "your bots" cards.
These cards somehow ended up a bit malformed, with uneven spacing
between widgets and the icons hanging below the avatar.
2018-12-03 16:18:47 -08:00
Raymond Akornor
92dc3637df send_email: Add support for multiple recipients.
This adds a function that sends provided email to all administrators
of a realm, but in a single email. As a result, send_email now takes
arguments to_user_ids and to_emails instead of to_user_id and
to_email.

We adjust other APIs to match, but note that send_future_email does
not yet support the multiple recipients model for good reasons.

Tweaked by tabbott to modify `manage.py deliver_email` to handle
backwards-compatibily for any ScheduledEmail objects already in the
database.

Fixes #10896.
2018-12-03 15:12:11 -08:00
Tim Abbott
0fddf9a610 docs: Fix 500s with super long fake /help/ article URLs.
While this would never happen for a real article, this prevents a 500
in this case for a situation which is definitely user error and should
be a 40x (in this case, 404).

As part of this, we refactor the main view code to do validation in a
single code path, since the semi-duplicated-in-3-places logic was
getting pretty buggy.
2018-12-03 14:43:45 -08:00
Tim Abbott
c740d1b093 clubhouse: Fix typoed include statement. 2018-12-03 14:31:44 -08:00
Tim Abbott
333b8ef668 signup: Move registration JS to signup.js.
Also, fix a linter error encountered in the process.
2018-12-03 12:22:59 -08:00
Tim Abbott
4c1e80032a push notifications: Fix unnecessary warning in development.
This prevents the warning about push notifications not being
registered for from being printed in development environment startup
by default.  In development, that's the expected state, and we don't
need to spam up the output with that notice.
2018-12-03 12:03:56 -08:00
Tim Abbott
e13de3e629 scripts: Fix incorrect garbage-collection of emoji/node caches.
Apparently, we were incorrectly expressing the paths in the
caches_in_use data structures for these two cache-cleaning algorithms,
resulting in the default threshhold_days algorithm controlling which
caches could be garbage-collected.  While the emoji one was just a
performance optimization for upgrade-zulip-from-git, it was possible
for the main `node_modules` cache in use in production to be GCed,
resulting in LaTeX rendering being broken.
2018-12-03 11:59:08 -08:00
Tim Abbott
74007e7f00 bots: Make REMINDER_BOT still a valid setting.
This makes it possible to still run the deliver_scheduled_messages
queue worker, even though we're not creating reminder-bot by default
in new organizations.
2018-12-03 11:43:27 -08:00
Vishnu Ks
24917f2e9b billing: Maintain a global list of stripe functions to mock.
Looks like payment_method_string was missing a Customer.save before. Not
sure how it was passing tests in that case.
2018-12-03 11:38:54 -08:00
Tim Abbott
d96624490e bulk_add_subscriptions: Fix confusing access to user_profile.realm.
Previously, we frequently accessed user_profile.realm from outside the
loops that interact with UserProfile objects.  This variable reuse
outside the loop could be confusing and should be a style/lint
violation.

While in this case, the behavior was correct (in that all users in the
loops were within the same realm), extracting a separate `realm`
variable significantly clarifies what's going on here.
2018-12-03 10:38:10 -08:00
Steve Howell
779ed37cfa hashchange: Fix update_browser_history() call for settings.
Even prior to my recent change in settings_panel_menu.js,
we were assigning window.location.hash a value that doesn't
have a '#' prefix.  This probably doesn't matter too much
for the browser, but it does confuse our own checks about
whether we're redundantly updating browser history.

Now we prefix the settings hash with '#' and we encorce
this convention with a blueslip error.
2018-12-03 10:09:35 -08:00
Steve Howell
05be16e051 hashchange: Remove is_exit_overlay code.
Just calling update_browser_history is sufficient
here, and we end up short-circuiting some code
in hashchanged():

    * we don't need to set state.old_hash, because
      that's what update_browser_history does
    * we bypass the is_overlay_check, which is always
      false in this context
2018-12-03 10:09:35 -08:00
Rishi Gupta
22d8de73e9 webhooks/stripe: Change update_string to provide updated values. 2018-12-03 09:24:52 -08:00
Tim Abbott
e8742f1dd5 docs: Expand documentation for running management commands. 2018-12-03 09:16:05 -08:00
Marco Burstein
307799113e right sidebar: Fix night-mode presence styling.
Fix the background color of night-mode presence indicators by setting
the background color to transparent instead of white when inactive.

Fix #10932.
2018-12-02 19:14:40 -08:00
Marco Burstein
339fa86373 tooling: Fix manage.py failing if /etc/zulip/zulip.conf exists.
If `/etc/zulip/zulip.conf` exists in development, `manage.py` fails
unnecessarily. Instead, check if `deploy_type` is set, as done in
`settings.py`.

Fix #10931.
2018-12-02 19:13:02 -08:00
Steve Howell
c8cbf39a16 Avoid fake clicks when launching settings pages.
Fake clicks sometimes require more code, and they're
brittle to selectors changing, and it's harder to
debug.
2018-12-02 19:07:24 -08:00
Steve Howell
c4d3578de3 Move more code into activate_section().
This code was added to the click handler, but it can
really go into activate_section().  This way the code
also runs when we first launch settings.
2018-12-02 19:07:24 -08:00
Steve Howell
473f2650fd refactor: Change settings_panel_menu.activate_section().
We now have activate_section take a section, rather than
an li, so it will be easier to call directly.
2018-12-02 19:07:24 -08:00
Steve Howell
ec3f6434a6 subs: Remove complicated onlaunch triggers.
We can reliably just use hashchange.go_to_location()
when you click on "Stream Settings" in the left
sidebar popover.
2018-12-02 19:07:24 -08:00
Steve Howell
623e3f3c9f hashchange: Extract hash_util.stream_edit_uri. 2018-12-02 19:07:19 -08:00
Steve Howell
bc18eb1d41 stream links: Use more standard API to go to location.
For stream links inside messages (like "#social") we
now use these functions:

    hashchange.go_to_location:

        We don't need to set href.  Relative paths
        are more standard, and the url is already
        encoded.

    hash_util.by_stream_uri:

        This saves a step in building the URL.
2018-12-02 19:07:19 -08:00
Steve Howell
846dfb2fe4 hashchange: Extract hashchange.go_to_location().
We use this API when we want the machinery
of the hashchanged system to come into play.
2018-12-02 19:07:15 -08:00
Steve Howell
636e54389b settings: Streamline code for navigating panels.
We call hashchanged.update_browser_history() when
we switch panels.  This API short circuits the
hashchanged callback and avoids code churn.

(We weren't actually double rendering, as the downstream
code does nothing at this point, so this is more
just preventig a pitfall and moving to a consistent
API.)
2018-12-02 19:07:15 -08:00
Steve Howell
f930502312 stream settings: Streamline up/down arrow code.
We can eliminate export_hash() and just directly
call switch_to_stream_row().
2018-12-02 19:07:15 -08:00
Steve Howell
b4d5c7e68a hashchange: Avoid double-rendering Subscribed/All tabs.
Before this commit, we would sometimes have
the toggler handle clicking or arrowing to
the All tab, but then also rewrite the hash
which caused us to re-process the event.

Now we only call update_browser_history()
in the callback handler from the toggle widget.

There's a bit of refactoring to make this happen,
but the call stacks end up being this:

    call toggler.goto(...)
        # callback is dispatched
            call subs.switch_stream_tab
                actually_filter_streams
                update_browser_history
2018-12-02 19:07:13 -08:00
Steve Howell
45227e84fc refactor: Flatten code in subs.change_state(). 2018-12-02 19:07:13 -08:00
Steve Howell
84d0b541e3 hashchange: Add hashchange.update_browser_history().
This helps us encapsulate the situation where we don't
want to trigger hashchanged(), without having to do it
within sub.js with prevent_once().
2018-12-02 19:07:10 -08:00
Steve Howell
212ee015d4 refactor: Extract subs.switch_to_stream_row. 2018-12-02 18:40:00 -08:00
Steve Howell
bea328b8b6 refactor: Split out functions for opening edit panel.
While they can share some code, opening the edit panel
for a stream and clearing the panel are pretty different
actions, so we simplify the API for each thing.

You no longer have to pass in booleans, and for the clear
case, you don't have to pass in a bogus node that just
gets ignored.
2018-12-02 18:40:00 -08:00
Steve Howell
43f25eb4a5 Clean up code to open "Create stream" panel.
This fixes a bug where hitting the "n" hotkey was
causing double work related to the hashchange system.

The code is now organized like this:

    do_open_create_stream() does the GUI piece

    We call the above directly for hash changes.

    For in-app actions, whether clicks or hotkeys,
    we call open_create_stream(), which delegates
    most of the work to do_open_create_stream() but
    also updates the hash.
2018-12-02 18:40:00 -08:00
Steve Howell
13af91869d Deprecate unreachable code in hashchange.
The overlay URLs are never handled in this function,
and the prior code just created confusion.
2018-12-02 18:40:00 -08:00
Steve Howell
7859a441ac bug fix: Avoid spurious calls to subs.change_state.
This diff looks a bit more complicated than it really is.

We had a bug where we'd call subs.change_state for
non-streams-related changes.  The bug probably barely
impacted customers, since it's hard to get into that
situation unless you're in "Settings", and then the
code mostly did nothing.  There's still a deeper issue
of what we actually do want to for settings changes,
but this fix does not address that.

We invert the conditionals related to internal state
changes, so that we can handle internal state changes.

And we make sure to only call subs.change_state if our
"base" is "streams".
2018-12-02 18:40:00 -08:00
Steve Howell
b80de69932 hashchange: Rename ignore to state. 2018-12-02 18:40:00 -08:00
Steve Howell
4b6ae10fb7 Rename group to old_overlay_group. 2018-12-02 18:40:00 -08:00
Steve Howell
d11d1313d9 refactor: Flatten code for hashchanged().
Using early-exit make the 3 cases a bit more clear.

    opening overlay
    closing overlay
    "normal"
2018-12-02 18:40:00 -08:00
Steve Howell
1f41a65c88 Rename ignore.flag to is_exiting_overlay. 2018-12-02 18:40:00 -08:00
Steve Howell
cee29483cf hashchange: Extract hashchanged_overlay().
This is mostly extracting the code within the `if`
block, as well as setting `base`, which wasn't used
elsewhere.

Also, the `else` no longer calls `is_overlay_hash`,
which was a redundant check.
2018-12-02 18:40:00 -08:00
Steve Howell
20bbc375a5 Rename ignore.prev to ignore.hash_before_overlay. 2018-12-02 18:40:00 -08:00
Steve Howell
53e99c0a55 hashchange: Remove unused ignore.last. 2018-12-02 18:40:00 -08:00
Steve Howell
682235af80 Rename hashchange.should_ignore to is_overlay_hash. 2018-12-02 18:40:00 -08:00
Tim Abbott
07adda84da Revert "ci: Re-enable testing documentation links."
This reverts commit d8e5e2d960.

See https://github.com/zulip/zulip/issues/10942 for a plan for making
this something we can re-enable.
2018-12-02 18:34:35 -08:00
Tim Abbott
48a3975ec0 import: Avoid unnecessary forks when downloading attachments.
The previous implementation used run_parallel incorrectly, passing it
a set of very small jobs (each was to download a single file), which
meant that we'd end up forking once for every file to download.

This correct implementation sends each of N threads 1/N of the files
to download, which is more consistent with the goal of distributing
the download work between N threads.
2018-12-02 13:50:27 -08:00
Vishnu Ks
0191bb593a billing: Make test functions accept *mocks instead of separate args. 2018-12-02 13:42:38 -08:00
Vishnu Ks
48618adf13 billing: Normalize several additional keys in mock_stripe.
Reran every test with GENERATE_STRIPE_FIXTURES = True, which also caused a
few fixtures to get updates unrelated to these changes (likely due to API
updates that hadn't been previously applied).
2018-12-02 13:32:19 -08:00
Rishi Gupta
36f54e689b integrations/stripe: Fix bug in charge.succeeded.
There are (at least) two types of objects that could be sent with a
charge.succeeded event, a Charge (e.g. for credit cards) or a Payment (if
they pay by ACH). We were handling the first but not the second.

This commit also updates the fixture for the existing charge.succeeded event
to the latest API version.
2018-12-02 00:25:52 -08:00
Tim Abbott
5696ad5490 sessions: Suppress coverage error until we can debug. 2018-12-01 10:08:57 -08:00
Rishi Gupta
c9c842ae2b billing: Add randomness to idempotency key while testing.
Makes it easier to test or regenerate fixtures for
test_billing_quantity_changes_end_to_end with generate=True.
2018-11-30 23:14:52 -08:00
Tim Abbott
18e2118fc8 Revert "sessions: Stop using the cached_db sessions engine."
This reverts commit 2fa77d9d54.

Further investigation has determined that this did not fix the
password-reset problem described in the previous commit message;
meanwhile, it causes other problems.  We still need to track down the
root cause of the original password-reset bug.
2018-11-30 15:54:32 -08:00
Tim Abbott
34bf5412b1 Add changelog and version updates for Zulip Server 1.9.1.
The actual changes in 1.9.1 are already present in master.
2018-11-30 15:51:02 -08:00
Tim Abbott
06f25115d8 docs: Add Docker to release checklist. 2018-11-30 13:19:04 -08:00
Tim Abbott
1303f8df20 docs: Fix missing quotes in su zulip -c documentation.
This fixes an actual user-facing issue in our mobile push
notifications documentation (where we were incorrectly failing to
quote the argument to `./manage.py register_server` making it not
work), as well as preventing future similar issues from occurring
again via a linter rule.
2018-11-30 12:12:27 -08:00
Tim Abbott
72db5d5a48 docs: Document how to setup system postfix email with Zulip. 2018-11-30 12:06:25 -08:00
Rishi Gupta
c59da02936 billing: Reflect discounts on /upgrade. 2018-11-30 11:19:07 -08:00
Rishi Gupta
16b7737da3 billing: Fix enforcement of seat_count in tests. 2018-11-30 11:19:07 -08:00
Rishi Gupta
5a47ac96de billing: Fix test flake in test_payment_method_string. 2018-11-30 11:19:07 -08:00
Rishi Gupta
1ba037201c billing: Move all price computations into billing.js. 2018-11-30 11:19:07 -08:00
Rishi Gupta
7523282e48 billing: Move cost calculation from upgrade.html to billing.js. 2018-11-30 11:19:07 -08:00
Rishi Gupta
60d3c17b6b billing: Enable tab navigation on /upgrade. 2018-11-30 11:19:07 -08:00
Tim Abbott
e609e10229 puppet: Fix missing dependency of tsearch-extras on apt repository.
This isn't super required, in that we add these repositories via
`setup-apt-repo` in any case, but the previous code was wrong and
worth fixing in any case.
2018-11-30 10:45:04 -08:00
Tim Abbott
31556e45d8 setup-apt-repo: Install gnupg as part of installation.
Apparently, on Debian stretch, the gnupg package isn't installed by
default, which means that our `apt-key add` commands were failing with
these errors on an ultra-minimal Debian installation:

+ apt-key add ./scripts/setup/packagecloud.asc
E: gnupg, gnupg2 and gnupg1 do not seem to be installed, but one of them is required for this operation
+ apt-key add ./scripts/setup/pgroonga-debian.asc
E: gnupg, gnupg2 and gnupg1 do not seem to be installed, but one of them is required for this operation

Fixes #10480.
2018-11-30 10:45:04 -08:00
Tim Abbott
81b99782b9 docs: Clean up unfinished sentence in sending-messages doc. 2018-11-30 10:06:04 -08:00
Tim Abbott
df5475996f docs: Add prod auth docs link to dev auth docs.
This should be helpful for folks working on things like a Facebook
OAuth2 integration.
2018-11-29 20:45:02 -08:00
Tim Abbott
a3b38d8402 docs: Document nginx configuration for development SSL.
This is a useful technique for developing OAuth integrations with Zulip.
2018-11-29 20:45:02 -08:00
Steve Howell
b827efb461 refactor: Extract maybe_reset_right_panel(). 2018-11-29 20:09:24 -08:00
Steve Howell
c5b2cfd777 refactor: Extract get_search_params(). 2018-11-29 20:09:24 -08:00
Steve Howell
8f915da2ca refactor: Extract add_tooltips_to_left_panel(). 2018-11-29 20:09:24 -08:00
Steve Howell
3190c3ffeb refactor: Extract show_active_stream_in_left_panel(). 2018-11-29 20:09:24 -08:00
Tim Abbott
d0f71881f4 docs: Add detailed documentation on the process for sending messages.
This has long been something missing from our suite of documentation.
2018-11-29 16:25:35 -08:00
Rohitt Vashishtha
82ea61a3cc scripts: Cleanly exit manage.py when run with python2.
Fixes #10854.
2018-11-29 14:20:27 -08:00
Tim Abbott
30e5b5fe55 docs: Increase highlighting of our linters in documentation. 2018-11-29 14:17:13 -08:00
Tim Abbott
4f022d3428 docs: Move zulip-specific tools earlier in the Git guide. 2018-11-29 14:03:29 -08:00
Steve Howell
d8c8fc1f03 streams: Optimize stream_data.create_sub_from_server_data.
This is definitely a micro-optimization, but avoiding
creating an extra object speeds up page loads by about
20ms per 1000 streams.

It's slightly sketchy to mutate the value in place, but
the original value never gets used again.
2018-11-29 13:29:17 -08:00
Tim Abbott
6781345b9b message_fetch: Fix a linter error introduced on rebase. 2018-11-29 13:29:12 -08:00
Steve Howell
ba243416e3 stream_color: Make stream color assignment more efficient.
We now let color_data keep its own state for
unused_colors, so that we longer have to pass in
a large list of unused_colors every time we want
to assign a new stream color.

This mostly matters at startup, where we might
be cycling through 5000 streams.  We claim all
the unused colors up front.

Each operation now has an upper bound of expensiveness,
where the worst case scenario is basically popping
off the first element of a list of <= 24 colors.

The algorithm is now deterministic, too, to make
it easier to test.  It's unclear whether random color
assignment ever had much benefit, and it made unit
testing the algorithm difficult.  Now we have 100%
line coverage.

Fixes part of #10902.
2018-11-29 13:00:25 -08:00
Shubham Dhama
990d7fb37d narrow: Remove narrow_activated.zulip event trigger. 2018-11-29 12:36:00 -08:00
Shubham Dhama
654c3240e4 narrow: Remove narrow_deactivated.zulip event trigger. 2018-11-29 12:36:00 -08:00
Shubham Dhama
42f1d2a33b tab_bar: Make explicit call of narrow change handle function. 2018-11-29 12:36:00 -08:00
Shubham Dhama
b726cd4b3e typing_events: Make explicit call of narrow change handle function. 2018-11-29 12:36:00 -08:00
Shubham Dhama
e908da7831 narrow: Remove some narrow_deactivated.zulip event handling. 2018-11-29 12:36:00 -08:00
Shubham Dhama
209dd6dd37 narrow: Extract processes needed to be executed after narrow deactivate. 2018-11-29 12:36:00 -08:00
Tim Abbott
83b127cec1 server_events: Extract functions for managing connection errors.
This cuts a bit of code duplication.
2018-11-29 12:31:08 -08:00
Shubham Dhama
01927fb470 message view: Fix hiding of connection-error message on narrowing streams.
When there is some error in connecting to server(more specifically to the
tornado server) the "Unable to connect to Zulip" connection error message
gets cleared as Django server could send the response of "get" request of
old messages and hence get_old_messages_success hides the error message
even though the connection is not properly established.

Fixes: #5599.
2018-11-29 12:26:41 -08:00
Vishnu Ks
2889de6d90 populate_db: Extract subscribe_users_to_streams function. 2018-11-29 12:15:58 -08:00
Vishnu Ks
f3033207b9 emails: Cover all LDAP cases when emailing login details.
This provides a nice user experience for folks where we do know what
their LDAP credentials are.

Though we need to fix #10917 before the content in the email with be
correct.
2018-11-29 12:14:22 -08:00
Tim Abbott
7a2d93ed6e show_admins: Add assertion to make mypy happy. 2018-11-29 11:51:39 -08:00
Tim Abbott
8a60ab7314 show_admins: Rewrite to use management library.
This makes this command more standardized, and helps avoid future bugs
like the one fixed in the last commit.
2018-11-29 11:40:17 -08:00
Tim Abbott
d828eba2f6 show_admins: Fix buggy realm parsing. 2018-11-29 11:40:17 -08:00
Rohitt Vashishtha
c4e50a34d3 bugdown: Refactor get_user to get_user_by_name.
Also adds a warning against the use of this function.
2018-11-29 10:19:08 -08:00
Hemanth V. Alluri
6b1d724f5c zerver: Add bugdown rendering for text custom profile fields.
This is the first step of letting users use Zulip markdown in their
SHORT_TEXT and LONG_TEXT custom profile fields, so that they can
include emphasis, links, etc.

This doesn't include any frontend logic yet, however.
2018-11-29 09:47:32 -08:00
Rishi Gupta
5fdc2e5161 billing: Ensure seat_count is always 8 in billing tests. 2018-11-28 23:08:27 -08:00
Rishi Gupta
f3ecb05762 billing: Rename stripeToken to stripe_token.
When we started the billing system we started by following conventions used
in the Stripe documentation, but in hindsight it makes more sense to follow
conventions used in the Zulip codebase.
2018-11-28 22:29:29 -08:00
Rishi Gupta
d302fae31b billing: Rename self.quantity to self.seat_count in tests. 2018-11-28 22:29:29 -08:00
Rishi Gupta
10d3d94a2a billing: Use common pathway for upgrading in tests. 2018-11-28 22:29:29 -08:00
Rishi Gupta
b3b1b47fb0 billing: Remove references to legacy stripe_fixtures.json. 2018-11-28 22:29:29 -08:00
Rishi Gupta
053778fdd7 billing: Update test_billing_quantity_changes_end_to_end to use mock_stripe. 2018-11-28 22:29:29 -08:00
Tim Abbott
02f09e2473 settings: Fix linter errors with user profiles. 2018-11-28 19:29:33 -08:00
Anders Kaseorg
8a6158c663 Position sidebars with top instead of margin-top.
This should make no visible changes.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2018-11-28 17:53:49 -08:00
Anders Kaseorg
10fb3539ae Position top-messages-logo statically.
This should make no visible changes.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2018-11-28 17:53:49 -08:00
Anders Kaseorg
ed0292629b zulip_tools.run: Remove shell=True support.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2018-11-28 17:48:23 -08:00
Anders Kaseorg
d581ad82ca scripts/upgrade-zulip-from-git: Avoid shelling out for mkdir, ln.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2018-11-28 17:48:23 -08:00
Anders Kaseorg
a61eebd9e3 scripts/lib/unpack-zulip: Avoid shelling out for rm, mv, mkdir, ln.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2018-11-28 17:48:23 -08:00
Anders Kaseorg
9bad4003c6 scripts/lib/upgrade-zulip-stage-2: Avoid shelling out for ln.
The original code was actually broken, in that it checked the wrong
path, but it didn't matter because it used `ln -nsf`.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2018-11-28 17:48:23 -08:00
Anders Kaseorg
0bfcd2294e tools/update-prod-static: Avoid shelling out for mkdir, cp, mv, rm.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2018-11-28 17:28:17 -08:00
Anders Kaseorg
19bdf54f33 tools/setup/emoji/build_emoji: Avoid shelling out for touch, rm, mkdir, cp.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2018-11-28 17:28:17 -08:00
Anders Kaseorg
1d15d72775 zerver/lib/export.py: Avoid shelling out for cp, rm, ln.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2018-11-28 17:28:17 -08:00
Anders Kaseorg
a694c3cafd scripts/restart-server: Avoid shelling out for ln.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2018-11-28 17:26:54 -08:00
Anders Kaseorg
d60b697cc5 scripts/lib/create-production-venv: Avoid shelling out for ln.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2018-11-28 17:25:01 -08:00
Anders Kaseorg
33a4d12101 scripts: Add zulip_tools.overwrite_symlink function to replace ln -nsf.
Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2018-11-28 17:24:59 -08:00
Anders Kaseorg
1597511de0 install: Check whether universe repository is enabled on Ubuntu.
Fixes #10417.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
2018-11-28 17:18:43 -08:00
Tim Abbott
e39ebb7358 settings: Fix "Preview profile" button.
This was apparently broken in the refactoring in
a394778cde.
2018-11-28 16:46:15 -08:00
Yashashvi Dave
fe3270d2b9 input pills: Fix modal gets closed when user click on remove-pill-btn.
This commit fixes bug: When user clicks on remove-user-pill-btn,
it closes the parent modal instead of removing user pill from input.
This happens because button has class `exit` and there is click
event listener on all `exit` class buttons, which closes modal.

Fix this by adding `e.stopPropogation` to remove-user-pill listener.
2018-11-28 16:33:08 -08:00
Yashashvi Dave
28c38a44c8 static/js/popover: Use predefine func to append user pills in field.
This commit remove repetitive code to append user pills in
custom field of user profile popover. And call already defined
function there.
2018-11-28 16:22:35 -08:00
Yashashvi Dave
20b6d08ef7 static/js/settings_account.js: Extract append_custom_profile_fields. 2018-11-28 16:22:35 -08:00
Yashashvi Dave
b2aeffd947 static/js/settings_account.js: Extract intialize_custom_user_type_fields. 2018-11-28 16:22:35 -08:00
Yashashvi Dave
cd8f4dfac0 statis/js/settings_account.js: Extract initialize_custom_date_type_fields. 2018-11-28 16:22:35 -08:00
Balaji2198
16967d6761 static/js/settings_streams.js: Refactor delete_default_stream method. 2018-11-28 16:17:21 -08:00
Nikhil Kumar Mishra
478674a6d6 analytics: Refactor to support more than one tooltip on same page.
While we don't actually need another tooltip on /stats right now, this
provides a clear approach for how to do that.  We've since added
tooltips in various other parts of the webapp, and that code is pretty
copy-pasteable, so I think it's reasonable to say this closes #4612.

Cleaned up by tabbott to remove a bunch of unnecessary changes.
2018-11-28 16:04:35 -08:00
Tim Abbott
0932a27647 docs: Move generic reverse proxy notes further down. 2018-11-28 15:53:54 -08:00
Igor Posledov
7aed0a2a66 docs: Add nginx reverse proxy basic config example. 2018-11-28 15:52:06 -08:00
Tim Abbott
d28527b629 portico: Fix bulleted list styling on privacy page.
Fixes #10787.
2018-11-28 15:04:47 -08:00
Steve Howell
6035304619 Extract color_data.js.
This code is pretty distinct from all the color-picking UI,
and we want to get it to 100% coverage and optimize it
more.
2018-11-28 14:51:51 -08:00
Eeshan Garg
5ef86b6d22 webhooks/stripe: Handle customer.discount events properly.
Recent changes merged in #10877 didn't handle these events
correctly. The linkified_id function breaks for the `discount`
object in the JSON payload. A cursory glance at Stripe's docs
tells me that since a discount is associated with a customer
or a coupon, it makes sense for a `discount` object to not have
an ID that can necessarily be linked to. So, we can just link
to the associated coupon instead.
2018-11-28 14:16:33 -08:00
Rohitt Vashishtha
681368b937 bugdown: Refactor get_possible_mentions_info and related functions.
This commit changes the return type of get_possible_mentions_info  to a
list instead of a dict, thus disposing off the hacky logic of storing
users with duplicate full names with name|id keys that made the code
obfuscated.

The other functions continue to use the dicts as before, however, there
are minor variable changes where needed in accordance with the updated
definition of get_possible_mentions_info.
2018-11-28 14:07:52 -08:00
Tim Abbott
e4946dd182 bugdown: Rename full_names to mention_texts.
This is another straight variable rename, which will help clarify the
upcoming commits.
2018-11-28 14:07:23 -08:00
Rohitt Vashishtha
ccdf893af7 bugdown: Rename get_full_name_info to get_possible_mentions_info. 2018-11-28 14:04:50 -08:00
Bruce
604364eb65 docs: Document how to use Zulip behind an haproxy reverse proxy.
With significant rearrangement by tabbott to have more common text
between different proxy implementations.
2018-11-28 13:56:26 -08:00
Tim Abbott
f1f60bc9bb docs: Document how to use AWS SIGv4 with boto.
This is required in some AWS regions.

The right long-term fix is to move to boto3 which doesn't have this
problem.

Allows us to downgrade the priority of #9376.
2018-11-28 12:25:45 -08:00
Tim Abbott
51950ad352 docs: Fix accidental repeat bullet #1 in S3 backend documentation.
Due to missing indentation, the numbering was resetting to 1 rather
than continuing to 6.
2018-11-28 12:19:37 -08:00
Tim Abbott
d8c5ad2a26 narrow: Add special text for conversation with yourself. 2018-11-28 11:59:16 -08:00
Abhinav Singh
0774bd7df0 portico: Fix password strength bar reset after form invalidation.
This code prevents the password bar from being incorrectly clear after
the sign up form is rendered again after invalid data is submitted
(generally due to forgetting to agree to ToS).

Fixes #10868.
2018-11-28 11:52:08 -08:00
butchyyyy
61c8247403 jenkins: Update integration doc with new plugin features. 2018-11-28 11:46:37 -08:00
Rishi Gupta
191d8101a3 billing: Update test_redirect_for_billing_home.
The part that was removed is better tested in many other tests, like
test_initial_upgrade.
2018-11-28 10:45:00 -08:00
Rishi Gupta
f0538293de billing: Update test_replace_payment_source to use mock_stripe. 2018-11-28 10:45:00 -08:00
Rishi Gupta
698aeddc85 billing: Delete test_subscribe_customer_to_second_plan.
This used to be a more likely codepath, before we introduced
Customer.has_billing_relationship. It is no longer literally impossible to
hit this race condition, so I'm not deleting the code, but it's unlikely
enough that it's not worth figuring out how to test it.
2018-11-28 10:45:00 -08:00
Rishi Gupta
33ec86aa00 billing: Delete test_extract_current_subscription.
Already better tested by the upgrade and downgrade tests using mock_stripe.

Note that the line that was removed is actually not possible to reach, since
canceled subscriptions aren't shown on the Customer object.
2018-11-28 10:45:00 -08:00
Tim Abbott
f43668a7ba docs: Add automated testing notes to our docs documentation. 2018-11-28 10:04:04 -08:00
Tim Abbott
d8e5e2d960 ci: Re-enable testing documentation links.
We've had a few unpleasant bugs with real documentation links being
broken, so we're going to make this more aggressive for now.

I think we instead want a more subtle option for suppressing failures
in some places but not others.
2018-11-28 09:52:04 -08:00
Tim Abbott
05c774bcbe docs: Update list of documentation types.
This had gotten somewhat out of date, and probably we should also
invest in a bit of a reorganization.
2018-11-28 09:49:39 -08:00
Tim Abbott
723fb60476 docs: Fix up some broken links output spam. 2018-11-28 09:49:39 -08:00
Tim Abbott
5f3c8be6d1 docs: Fix some broken links in security model doc.
Apparently, we haven't been running test-documentation in production
of late.
2018-11-28 09:49:39 -08:00
Steve Howell
b79d63e9c3 copy/paste: Try to fix Casper flake and add comments.
I think this will fix a Casper flake where there was a race
window with multiple temp DOM elements holding copied text.

I also add a comment to the code I think causes this race
for the tests.
2018-11-27 21:42:16 -08:00
Tim Abbott
65a9ee476c buddy list: Tweak styling for (you) marker. 2018-11-27 17:42:44 -08:00
Tim Abbott
5a56925495 restart-server: Fix restarting server with multiple tornado processes.
Previously, we unconditionally tried to restart the Tornado process
name corresponding to the historically always-true case of a single
Tornado process.  This resulted in Tornado not being automatically
restarted on a production deployment on servers with more than one
Tornado process configured.
2018-11-27 17:20:05 -08:00
Tim Abbott
d9e8380981 copy: Add whitespace before timestamps in messages without sender.
This changes:

  Iago 4:11 PM
test not edited

4:11 PM
test edited

to this:

  Iago 4:11 PM
test not edited

  4:11 PM
test edited
2018-11-27 16:29:32 -08:00
Tim Abbott
c43a00fd60 copy: Include EDITED notices in more copy-paste cases.
Previously, they were only included in messages that were the first in
their recipient block and were not /me (status) messages.
2018-11-27 16:24:04 -08:00
Tim Abbott
3ef0d6016c copy: Fix copy-pasting of EDITED notices in messages.
Previously, because the parens were added via CSS, copy-pasting the
EDITED notices resulted in junk like this:

 Iago 3:51 PMEDITED
edited message content

Now, you get:

 Iago 3:51 PM (EDITED)
edited message content
2018-11-27 16:20:46 -08:00
Tim Abbott
e159f052bb status: Allow selecting status message text.
Status messages were incorrectly not selectable, due to a bug in how
we setup the no-select hierarchy (for making copy-paste not have weird
whitespace issues).

Fixes #10456.
2018-11-27 15:55:51 -08:00
Jeswin
a5b533ba64 portico: Fix placement of "this field is required" notice.
The "This field is required" notice for the "organization URL" field
was improperly overlapping the server's root domain.

Fixes #10865.
2018-11-27 15:40:53 -08:00
Tim Abbott
b3c8e56913 node: Fix activity tests failing due to recent i18n addition.
Master was failing due to a regression I introduced in
c6fd9e27f5380f79ce793b8d8fa13694d7faf7fb.
2018-11-27 15:23:32 -08:00
Tim Abbott
bddf23894d buddy list: Add marker for which user is yourself.
This helps make clear what's going on with the potentially confusing
"you" user.
2018-11-27 15:07:58 -08:00
Steve Howell
1890c30ee1 buddy list: Put "me" at the top of the list.
I think people will want this, particularly folks
with names toward the back of the alphabet.
2018-11-27 14:52:19 -08:00
Steve Howell
3aa490edbe Add current user back to the buddy list.
For many years we have been excluding the current user
from the buddy list, since their presence is kind
of implicit, and it saves a line of real estate.

This commit removes various user-is-me checks
and puts the user back for the following reasons:

    * explicit is better
    * newbies will be less confused when they
      can see they're actually online
    * even long-time users like myself will
      feel more comfortable if it's just there
    * having yourself in the buddy list facilitates
      things like checking your presence or sending
      yourself a message
    * showing "me" reinforces the meaning of the
      green circle (if my circle is green and I'm
      active, then others with green circles must
      be active too)
    * If you're literally the first user in the
      realm, you can now see what the buddy list
      looks like and try out the chevron menu.

The biggest tradeoff here is the opportunity cost.
For an org with more people than fit on the screen,
we put the Nth person below the fold to show "me".
I think that's fine--users can still scroll or
search.

This commit doesn't do anything special with the
current user in terms of sorting them higher in the
list or giving specific styling.

Fixes #10476
2018-11-27 14:52:19 -08:00
Steve Howell
e978158519 casper test: Add helpers for buddy list checks. 2018-11-27 14:52:19 -08:00
Steve Howell
731f76cea1 refactor: Have buddy_data.level() take user_id.
All the callers were having to call get_status().
We now do it for them.
2018-11-27 14:52:19 -08:00
Steve Howell
1e9d0718eb refactor: Flatten code in presence.set_info().
We reduce nesting of code by just early-exiting
for the `is_current_user` check.

This also forces us to be a bit more thorough
with our tests if we want to maintain line
coverage.
2018-11-27 14:52:19 -08:00
Rishi Gupta
dd0126ff1b settings: Improve error message when deactivating the last user.
This PR was originally started by Rishi Gupta (see #10383).
2018-11-27 12:49:43 -08:00
Eeshan Garg
7fb674cc58 messages: Add Addressee.for_user_ids().
This commit is a part of our efforts surrounding #9474.
2018-11-27 12:09:41 -08:00
Eeshan Garg
91b90460ee lib/actions: Add helper recipient_for_user_ids().
This function is equivalent to recipient_for_emails, but fetches
user_profiles by IDs, not by emails.

This commit is a part of our efforts surrounding #9474, but is
more primarily geared towards adding support for sending typing
notifications by user IDs.
2018-11-27 11:59:11 -08:00
Eeshan Garg
8ffc437e70 addressee: Raise JsonableError in get_user_profiles().
Previously, get_user_profiles() was split into two functions:

* user_profiles_from_unvalidated_emails, which raised a
  ValidationError upon encountering a non-existent user email.
* get_user_profiles, which caught the ValidationError raised
  by user_profiles_from_unvalidated_emails and raised a
  JsonableError instead.

According to Steve Howell, this complexity is partly a relic
of past refactoring and is unnecessarily heavy. It is better to
just raise JsonableError directly.
2018-11-27 11:59:11 -08:00
Eeshan Garg
68a06abb79 actions: Stop using Addressee's helpers in recipient_for_emails.
recipient_for_emails is used by our typing notifications code.
user_profiles_from_unvalidated_emails is used by our typing
notifications code *and* for sending messages.
user_profiles_from_unvalidated_emails is a part of a larger
framework used by Addressee to validate recipient emails when sending
messages and will eventually need to be removed as we move forward
with #9474. So it makes sense to just inline this function within
recipient_for_emails so that we don't break our typing notifications
code in the future.

This commit is a part of our efforts surrounding #9474.
2018-11-27 11:59:11 -08:00
Tim Abbott
adf27aae4c python: Remove now-unnecessary str_utils library.
This library was absolutely essential as part of our Python 2->3
migration process, but all of its calls should be either no-ops or
encode/decode operations.

Note also that the library has been wrong since the incorrect
refactoring in 1f9244e060.

Fixes #10807.
2018-11-27 11:57:54 -08:00
Tim Abbott
6a9e6503b7 python: Remove unnecessary NonBinaryStr TypeVar.
This was a potentially useful value (later superceded by use of Text)
when first introduced, but now that we're on Python 3, it should just
be str.
2018-11-27 11:44:09 -08:00
Tim Abbott
c679920c01 python: Fix unnecessary uses of str_utils library. 2018-11-27 11:44:09 -08:00
Tim Abbott
e06668c7e8 queue_processors: Fix misleading copied comment.
This comment was clearly copied from the previous processor.
2018-11-27 11:44:09 -08:00
Tim Abbott
58a6dafa68 lint: Exclude outbox from linter checks on "subject". 2018-11-27 11:05:25 -08:00
Raymond Akornor
d00b889402 auth: Add an organization reactivation flow with admin confirmation.
This adds a web flow and management command for reactivating a Zulip
organization, with confirmation from one of the organization
administrators.

Further work is needed to make the emails nicer (ideally, we'd send
one email with all the admins on the `To` line, but the `send_email`
library doesn't support that).

Fixes #10783.

With significant tweaks to the email text by tabbott.
2018-11-27 10:58:34 -08:00
Tim Abbott
10e8e2acac push notifications: Tweak text for push notification message.
The previous content made it sound like we were actually sending a
push notification, which could be confusing/alarming in some cases
(see e.g. 9c224ccdd3).  Instead, we make
clear that we're sending it to all clients (which one might correctly
suspect is vacuous in the development environment).
2018-11-27 09:53:44 -08:00
Tim Abbott
9c224ccdd3 populate_db: Suppress logging output for push notifications.
This fixes a lot of spammy output of the form:

2018-11-27 17:46:48.279 INFO [zerver.lib.push_notifications] Sending push notification to user 46

when running populate_db, which is both confusing (since we're not
actually sending push notifications here) and spammy.
2018-11-27 09:50:17 -08:00
Tim Abbott
7b930124d9 push notifications: Add a logger (default-off in tests).
This should suppress some spammy logging output about push
notifications that we were seeing in a large number of unit tests.
2018-11-27 09:45:45 -08:00
Tim Abbott
38a6003472 push notifications: Improve logging for missing configuration.
While it could make sense to print these logging statements at WARN
level on server startup, it doesn't make sense to do so on every
message (though it perhaps did make sense to do so before more recent
changes added good ways to discover you forgot to configure push
notifications).

Instead, we now just do a WARN log on queue processor startup, and
then at DEBUG level for individual messages.

Fixes #10894.
2018-11-27 09:37:57 -08:00
Tim Abbott
beb80219a8 push notifications: Fix a comment typo. 2018-11-27 09:18:35 -08:00
Tim Abbott
3bb0956046 upload: Fix ensure_medium_avatar_image for S3 backend.
Previously, it tried to interact with the wrong path for the original
image.
2018-11-26 20:20:27 -08:00
Tim Abbott
00826486bd hipchat: Fix typo in logging output. 2018-11-26 16:44:31 -08:00
Steve Howell
38f81d5d20 hipchat: Skip public stream subs in slim mode. 2018-11-26 16:37:30 -08:00
Steve Howell
c2e9f5eb0a hipchat: Limit messages in slim mode.
For messages with strange senders, we don't import
messages.  Basically, we only import a message if
it has sender with an id that maps to a non-deleted
user.
2018-11-26 16:37:30 -08:00
Steve Howell
3a7788217e hipchat: Skip really long messages. 2018-11-26 16:37:30 -08:00
Steve Howell
e57a932692 hipchat: Fix avatars.
This code was not reading any avatars because
it was not referencing 'User' to get to the avatar,
and it was not re-mapping user ids for some reason.
2018-11-26 16:37:30 -08:00
Steve Howell
ad35e371fe hipchat: Support slim_mode flag.
We now skip deleted users.  There is a flag
here that's hard coded to True--we may decide
later to make this a command line option.
2018-11-26 16:37:30 -08:00
Steve Howell
bd1e96cf63 hipchat: Rework stream/subscriber logic.
We now account for streams having users that
may be deleted.  We do a couple things:

    - use a loop instead of map
    - only pass in users to hipchat_subscriber
    - early-exit if there are not users
    - skip owner/members logic for public streams
2018-11-26 16:37:30 -08:00
Steve Howell
1335dfd295 hipchat: Handle messages with missing recipients.
If a message is for a stream or user that we didn't
load, then we just skip it.
2018-11-26 16:37:30 -08:00
Steve Howell
ff68757358 hipchat: Just skip over missing attachments.
It seems like we get a lot of exports with bad
attachment data, and some folks don't necessarily
care, so we just skip for now.
2018-11-26 16:37:30 -08:00
Rishi Gupta
7bc23a8f85 billing: Turn off process_downgrade. 2018-11-26 16:24:54 -08:00
Vishnu Ks
8343ed6ceb billing: Use mock_stripe in test_downgrade_with_money_owed. 2018-11-26 15:59:19 -08:00
Vishnu Ks
a8b95ff801 billing: Use mock_stripe in test_downgrade_with_no_subscription. 2018-11-26 15:16:26 -08:00
Vishnu Ks
1ec9097f55 billing: Use mock_stripe in test_downgrade. 2018-11-26 14:59:46 -08:00
Vishnu Ks
a2c0ec207e billing: Use mock_stripe in test_attach_discount_to_realm. 2018-11-26 14:59:46 -08:00
Rishi Gupta
e2838a49db billing: Delete fixture data before regenerating it. 2018-11-26 14:59:46 -08:00
Rishi Gupta
0dffb58797 billing: Fix fixture_files_for_function including too many files.
Previously, this function would return the fixture files for any test that
had the test's name as a prefix.
2018-11-26 14:59:45 -08:00
Marco Burstein
6f569719c9 integrations: Change the truncation marker for long messages.
Change the truncation marker from `...` to `\n[message truncated]`
when receiving messages from the API or through e-mail. Also, update
tests to account for the new change.

Fix #10871.
2018-11-26 11:09:39 -08:00
Rishi Gupta
9f471a3e7d webhooks: Update Stripe integration. 2018-11-25 23:23:50 -08:00
Rishi Gupta
882cf224f8 billing: Update wording on /upgrade. 2018-11-24 16:06:52 -08:00
Vishnu Ks
189e5e1fbd billing: Add frontend for upgrading by invoice. 2018-11-24 11:56:13 -08:00
Rishi Gupta
6afbc2726f billing: Add billing_modality to upgrade form. 2018-11-24 11:56:13 -08:00
Rishi Gupta
08daefa4a3 billing: Update payment method string to incorporate billing by invoice.
Also fixes a bug in process_initial_upgrade. If you have a card on file
(e.g. from a previous subscription), and try to upgrade by billing by
invoice, neither the if nor the elif condition applies.
2018-11-24 11:56:13 -08:00
Tim Abbott
043baa2af8 realm filters: Add a test for a useful thing to support. 2018-11-20 19:34:28 -08:00
Tim Abbott
64960383e4 mypy: Fix missing type annotation in tornado code. 2018-11-20 19:08:14 -08:00
Rishi Gupta
6b637428a7 billing: Add Realm.seat_limit.
Currently unenforced, and will mostly need to be set by hand.
2018-11-20 18:50:43 -08:00
Tim Abbott
2fb1e51d71 dropbox: Fix incorrect placement of notify_bot_owner_on_invalid_json.
This was an error I introduced in editing
b79213d260.
2018-11-20 18:45:43 -08:00
Tim Abbott
46acb608b1 tornado: Include port number in logging statements. 2018-11-20 18:45:22 -08:00
Eeshan Garg
67d209ade9 webhooks/greenhouse: Update docs to conform to style guide. 2018-11-20 18:38:43 -08:00
Eeshan Garg
60d3e6b49b webhooks/gosquared: Support chat message events. 2018-11-20 15:59:51 -08:00
Eeshan Garg
b79213d260 webhooks: Notify bot owner on invalid JSON.
There are only a handful of non-JSON webhooks that wouldn't
benefit from the notify_bot_owner_on_invalid_json feature.

Specifically, these are the webhooks where the third-party product
uses another format, whether it be HTML form-encoded, XML, or
something else.

Tweaked by tabbott to correc the list of excluded webhooks.
2018-11-20 15:59:09 -08:00
Cynthia Lin
d36dc5e2d1 hello: Add link and label for latest Zulip release.
Tweaked by tabbott to add the plumbing for the 3 variables we need and
add the links, and move to a plain-text styling.
2018-11-19 12:00:40 -08:00
Tim Abbott
1abb1447df stripe: Be more explicit about the valid set of event types.
Previously, the Stripe webhook code was riddled with implicit
assertions that there were exactly N event types within a given
category, and we handled the last one in a final `else` clause in the
block.  This was likely to cause confusing problems in the event that
we're missing an event type (or Stripe adds a new one).

We fix this by just adding a few more conditionals and raising the
standard "unexpected event type" exception for the others.
2018-11-19 11:40:54 -08:00
Eeshan Garg
9afb1c3459 webhooks/stripe: Support customer.subscription.update events. 2018-11-19 11:33:41 -08:00
Vishnu Ks
ba640bf89d emails: Don't send day2 email if user already has an account. 2018-11-19 11:17:31 -08:00
Vishnu Ks
3258ce1fa4 emails: Cleanup followup day1 email. 2018-11-19 11:16:36 -08:00
Tim Abbott
3e3eb2aa7f scripts: Clarify names of running-as-root assertions.
This should make it more obvious that these functions will exit the
script if the check fails.
2018-11-19 10:58:34 -08:00
Rohitt Vashishtha
eae9251cb7 scripts: Make upgrade-zulip-* use root checking from zulip_tools.
This is mostly just a nice code deduplication/cleanup.
2018-11-19 10:58:34 -08:00
Rohitt Vashishtha
cfe603f342 scripts: Make manage.py use root checking from zulip_tools. 2018-11-19 10:58:34 -08:00
Rohitt Vashishtha
0975bbb39e scripts: Make zulip-puppet-apply check if the user is root.
Fixes #10833.
2018-11-19 10:58:34 -08:00
Rohitt Vashishtha
767acfa2ac scripts: Add util functions for checking root to zulip_tools. 2018-11-19 10:58:16 -08:00
Vishnu Ks
d8804a2474 billing: Change plan_interval to plan.interval.
There is no attribute called  plan_interval. The reason
this was missed by mypy is moost likely due to us using
Any instead of Subscription in extract_current_subscription.
2018-11-19 12:36:25 +05:30
Tim Abbott
541bc0afda sessions: Fix filling memcached caches.
Our recent change in 2fa77d9d54 to
disable the cached_db cache backend broke upgrade-zulip-from-git with
an attributeerror; we fix that by checking the session engine before
trying to access its cache-related attributes.
2018-11-18 20:02:28 -08:00
Tim Abbott
d5f53164b4 docs: Suppress markdown line length linter errors. 2018-11-18 18:56:44 -08:00
Cynthia Lin
fb408316f1 README: Normalize CircleCI badge styling. 2018-11-18 18:49:22 -08:00
Cynthia Lin
10a21ed949 README: Add latest GitHub release badge to README. 2018-11-18 18:49:22 -08:00
Rishi Gupta
99506b486a billing: Add backend for paying by invoice. 2018-11-17 23:08:48 -08:00
Rishi Gupta
61e0c2693d billing: Use Subscription.save() instead of calling save on instances.
Continuation of 03d77bc.
2018-11-17 18:59:21 -08:00
Rishi Gupta
8470affb5b billing: Add documentation on upgrading Stripe API versions. 2018-11-17 18:09:56 -08:00
Rishi Gupta
63614f28fe billing: Upgrade to Stripe API version 2018-11-08.
Was hoping to do this after adding timestamp normalization to
normalize_fixture_data, which would have turned this into a <10 line
diff. There is a potentially material change in this API upgrade though
(around how invoices are handled), so just doing it now.
2018-11-17 18:09:56 -08:00
Tim Abbott
1d1e209d15 bugdown: Import convert consistently as bugdown_convert. 2018-11-17 11:56:06 -08:00
Tim Abbott
6b99b53584 docs: Add docs for per-realm markdown fields. 2018-11-17 11:55:58 -08:00
Rishi Gupta
91b02373dc activity: Rename standard free to open source.
"standard free" looks too similar to "standard". Also it makes it hard to
Ctr+f for "standard".
2018-11-16 21:03:37 -08:00
Rishi Gupta
0670976cb1 billing: Remove PRINT_STRIPE_FIXTURE_DATA.
Made obsolete by mock_stripe.
2018-11-16 19:41:46 -08:00
Rishi Gupta
b847a100a3 billing: Prevent setup_stripe from being run in production. 2018-11-16 19:29:31 -08:00
Vishnu Ks
2e04cdbe5e billing: Show estimated subscription revenue on /activity.
[Substantial edits by Rishi Gupta]
2018-11-16 13:30:16 -08:00
Vishnu Ks
a7c33e12cb billing: Make mock_stripe handle calls which dont return object. 2018-11-16 13:30:16 -08:00
Shubham Padia
c1d1378125 auth: Add email_data option to github_oauth2_test.
Removes email_not_verified option. That option was used to assign
email_data a different set of emails for a test. Instead of that,
this refactor allows to specify the email_data itself in the function
which calls github_oauth2_test. Flags like email_not_verified are
generally used in one test. This is a preparatory refactor for
choose email screen which may have introduced multiple flags otherwise.
2018-11-16 12:18:23 -08:00
Shubham Padia
79e590f50f auth: Store realm id in return_data of social_associate_user_helper.
Realm object is not json-serializable; store the realm id instead
and retrieve the realm in social_auth_finish using
`Realm.objects.get(id=return_data["realm_id"])`.
2018-11-16 12:16:21 -08:00
Shubham Padia
d95364b94f auth: GitHubAuthBackend.get_verified_emails returns user's all emails.
The email_list returned has the primary email as the first element.
Testing: The order of the emails in the test was changed to put a
verified email before the primary one. The tests would fail without
this commit's change after the changes in the order of test emails.
2018-11-16 12:16:21 -08:00
Tim Abbott
2fa77d9d54 sessions: Stop using the cached_db sessions engine.
See https://github.com/zulip/zulip/issues/10856 for details on the bug
here; but basically, users who reset their password were unable to
login until the next time we flushed memcached.  The issue disappeared
after stopping using the Django cached_db session engine, so it's
pretty clear that some sort of bug with that session engine
interacting with our password reset logic is the root cause.

Further debugging is required to understand this fully, but for now,
it seems wise to just disable the backend.

The cost of doing so is a small performance decrease, which is likely
acceptable until we can resolve this (it's certainly a more minor
problem than the "Can't login" bug that disabling this removes).
2018-11-16 12:03:21 -08:00
Tim Abbott
ededdc512b nginx: Fix missing API authentication configuration.
This fixes a bug where our API routes for uploaded files (where we
need to use a consistent URL between session auth and API auth) were
not properly configured to pass through the API authentication headers
(and otherwise provide REST endpoint settings).

In particular, this prevented the Zulip mobile apps from being able to
access authenticated image files using these URLs.
2018-11-16 11:25:54 -08:00
Steve Howell
68d81cb25b subject -> topic: Fix respond_to_message(). 2018-11-16 11:11:40 -08:00
Steve Howell
82b9f2a3db subject -> topic: Fix create_message_object(). 2018-11-16 11:11:40 -08:00
Steve Howell
3e860fbc39 subject -> topic: Fix group.subject references. 2018-11-16 11:05:43 -08:00
Steve Howell
55362263dd Isolate/eliminate uses of "match_subject". 2018-11-16 11:05:43 -08:00
Steve Howell
89c278d1e5 Isolate/eliminate use of "subject_links".
For message groups, I just changed the internal name
to "topic_links".

For uses of "subject_links" that are tied to how the
server names fields, I introduced these wrappers:

    * util.set_topic_links(obj, topic_links)
    * util.get_topic_links(obj)

These can be used for either messages or events.
2018-11-16 11:05:43 -08:00
Yashashvi Dave
5759d5a762 statis/js/bot_data.js: Add get_bot_owner_email function. 2018-11-16 09:52:05 -08:00
Yashashvi Dave
a394778cde statis/js/popover.js: Remove unused arg from show_user_profile func.
Remove unused argument `element` from function `show_user_profile`.
2018-11-16 09:52:05 -08:00
Vishnu Ks
9d398ee335 activity: Move the total row from last to first. 2018-11-16 09:22:32 -08:00
Nolan Darilek
5d291eb52c accessibility: Model messages as a list with items, each representing a single message.
Previously, messages were a string of disconnected regions. Modeling them as a list brings several benefits:
 * Quickly jump to the message list by using a screen reader's list navigation hotkey.
 * Quickly jump between messages by using a screen reader's list item navigation hotkey.
 * Quickly jump to the beginning or end of message lists in screen readers that support it.
2018-11-16 08:54:01 -08:00
Tim Abbott
209dd5db67 actions: Add a function for changing realm subdomains.
This is initial work, which will help us establish habits of using a
well-tested approach for renaming a Zulip organization (since as part
of https://github.com/zulip/zulip-mobile/issues/3142, we'll likely
need to make this function do more).
2018-11-15 14:39:14 -08:00
Tim Abbott
9e4058efd3 test_realm: Use update_fields when saving realm objects.
This is a slight cache performance optimization, and more importantly
matches our standard style for modifying objects.
2018-11-15 14:39:14 -08:00
Vishnu Ks
74ee41912a auth: Always force Google to show account chooser.
Fixes #10515
2018-11-15 11:12:45 -08:00
Tim Abbott
86801d350a compose: Store raw_content after fetching it for quoting.
This is a nice performance optimization for the rare case where the
user does quote-and-reply on a message, aborts the compose, and then
re-does the quote-and-reply.
2018-11-14 23:55:26 -08:00
Marco Burstein
f37e4df471 compose: Check if raw_content is present when quoting.
If `raw_content` is already present for the selected message, there is
no need to make a request to the server.
2018-11-14 23:52:08 -08:00
Steve Howell
6546fb3f1d subject -> topic: Fix local subject vars. 2018-11-14 23:24:06 -08:00
Steve Howell
51f8ac91ec subject -> topic: Rename current_subject. 2018-11-14 23:24:06 -08:00
Steve Howell
a172ac264d subject -> topic: Rename by_stream_subject_uri. 2018-11-14 23:24:06 -08:00
Steve Howell
b615f0df4d subject -> topic: Fix stream/subject in comments. 2018-11-14 23:24:06 -08:00
Steve Howell
c6ad12d058 subject -> topic: Fix local vars in stream_list. 2018-11-14 23:24:06 -08:00
Steve Howell
3a9c81ed8c subject -> topic: Rename add_subject_links. 2018-11-14 23:24:06 -08:00
Steve Howell
91e4784b92 subject -> topic: Rename narrow.by_subject. 2018-11-14 23:24:06 -08:00
Steve Howell
6c1a96174e subject -> topic: Rename narrow_by_subject. 2018-11-14 23:24:06 -08:00
Steve Howell
7ae8907b3f subject -> topic: Rename narrows_by_subject. 2018-11-14 23:24:06 -08:00
Rohitt Vashishtha
d7a0bd4a6c subject-to-topic: Add topics to compose_state.js. 2018-11-14 23:24:06 -08:00
Steve Howell
f69a4f11e3 subject -> topic: Fix narrow tests.
This fixes the last remaining "subject" references except
for uses of it in expected SQL statements.
2018-11-14 23:24:06 -08:00
Steve Howell
c0fd8660d2 subject -> topic: Fix analytics test (minor). 2018-11-14 23:24:06 -08:00
Steve Howell
f3e529c694 minor: Use topic_name() in travis test. 2018-11-14 23:24:06 -08:00
Steve Howell
eb4d279bbc Extract get_turtle_message().
This seems like kind of a silly function to extract
to topic.py, but it will theoretically help us sweep
"subject" if we change the DB.

It had test coverage.
2018-11-14 23:24:06 -08:00
Steve Howell
cc33e4cd0c digest: Eliminate unneeded queries for hot convos.
We can easily keep track of messages by bucket from the
original loop through messages.
2018-11-14 23:24:06 -08:00
Steve Howell
3091412806 refactor: Use messages in gather_hot_conversations().
We rename stream_messages -> stream_ums, and then we get
messages at the top for the loop that only cares about
messages.
2018-11-14 23:24:06 -08:00
Steve Howell
f961408782 digest: Reduce queries using select_related().
We use the message a lot for the query modified
here, so I think it's worth taking the up-front
hit of getting bulkier objects to avoid O(N)
hops back to the database.
2018-11-14 23:24:06 -08:00
Steve Howell
51aa313833 test coverage: Add test_multiple_stream_senders().
This exercises a loop in digest.gather_hot_conversations().
2018-11-14 23:24:06 -08:00
Steve Howell
5a539d44b0 subject -> topic: Fix notification tests.
The URLs changed here are artificial, so we can convert
subject -> topic without breaking anything.
2018-11-14 23:24:06 -08:00
Steve Howell
8cf93a25c5 Use email_subject as var in test_notifications.
We change subject -> email_subject for all local vars
here, so it's easier to skip past this code if you
are sweeping subject -> topic.
2018-11-14 23:24:06 -08:00
Steve Howell
27d79352da topic -> subject: Extract get_topic_from_message_info().
This changes files where it's safe to just assume caller
may use either "topic" or "subject", and we prefer "topic"
but support "subject".
2018-11-14 23:24:06 -08:00
Steve Howell
aa4e9cec2d minor: Add a code comment and move two constants. 2018-11-14 23:24:06 -08:00
Steve Howell
b666a6bd6c subject -> topic: Fix most of api_test_helpers.
We don't want to change anything that can end
up in docs yet, but for test setup, we can switch
to topic_name.
2018-11-14 23:24:06 -08:00
Steve Howell
44cbcdf00c minor: Remove txt file from lint exception.
It's already ignored because it's not a .py file.
2018-11-14 23:24:06 -08:00
Steve Howell
2505a2f3cc lint: Build exceptions for subject. 2018-11-14 23:24:06 -08:00
Steve Howell
a3460d1ef6 lint: Remove obsolete exemptions.
These two files have been cleaned up since the original
lint rule exemption.
2018-11-14 23:24:06 -08:00
Steve Howell
c69c40a55a lint: Extract check_file_for_pattern(). 2018-11-14 23:24:06 -08:00
Steve Howell
fd0b249a29 lint: Calculate strip_rule outside the loop.
This adds up over a million lines. :)
2018-11-14 23:24:06 -08:00
Steve Howell
f386c64759 lint: Speed up by doing fewer regex compiles.
Even though you'd think these regexes would be
cached, compiling the regex outside of looping
through lines makes a difference.

My timings are 8.4s -> 6.0s.  (You need to hack
on the linter to isolate the custom checks.)
2018-11-14 23:24:06 -08:00
Steve Howell
08e44aac0d lint: Extract get_rules_applying_to_fn(). 2018-11-14 23:24:06 -08:00
Steve Howell
eda138343b lint: Extract get_line_info_from_file(). 2018-11-14 23:24:06 -08:00
Steve Howell
6d88210110 lint: Extract check_file_for_long_lines().
In passing this removes some unnecessary string
decoding that's a relic of python2.
2018-11-14 23:24:06 -08:00
Steve Howell
ea26372083 hipchat: Make conversion work with UUID ids from Stride.
Normal hipchat exports use integer ids for their
users and "rooms," which we just borrowed during
conversion.

Atlassian Stride uses stride UUIDs for these instead, but otherwise
has the same export format.

We now introduce IdMapper to handle external ids
that aren't integer.  The IdMapper will map UUID
ids to ints and remember them.  For ints it just
leaves them alone.

Fixes #10805.
2018-11-14 23:22:40 -08:00
Steve Howell
aff84cd1e9 hipchat: Skip attachments without paths.
This is a short term workaround.  Some variants
of HipChat exports are missing `path`, and we just
punt for now.
2018-11-14 23:14:13 -08:00
Vishnu Ks
546fd5d60e email log: Inline email CSS when generating emails.
This saves a step in the development cycle for iterating on the email
HTML and CSS.
2018-11-14 23:05:44 -08:00
Steve Howell
47e464528c refactor: Split up add_display_time().
We split out two new functions and call them
everywhere that we used to call add_display_time():

    - `update_group_time_display`
    - `update_timestr`

We also make some of the local vars more consistent,
as well as doing more explicit clearing of vars than
`delete`.

Splitting these functions will allow us to muck with date
dividers without affecting the `update_str` functionality.
2018-11-14 22:47:29 -08:00
Eeshan Garg
ab7d0de782 webhooks/github: Enable PM notifications for non-JSON payloads. 2018-11-14 22:35:57 -08:00
Eeshan Garg
d9958610a4 webhook_decorator: Support notifying bot owner on invalid JSON.
Our webhook-errors.log file is riddled with exceptions that are
logged when a webhook is incorrectly configured to send data in
a non-JSON format. To avoid this, api_key_only_webhook_view
now supports an additional argument, notify_bot_owner_on_invalid_json.
This argument, when True, will send a PM notification to the bot's
owner notifying them of the configuration issue.
2018-11-14 22:35:56 -08:00
Tim Abbott
71174d53cb docs: Add a document with notes on the Django upgrade process. 2018-11-14 17:53:27 -08:00
Tim Abbott
f1c65975ad docs: Clarify preparatory process for data import.
You need a Zulip server running the a matching version, and no longer
need to do an upgrade from master before using established import tools.
2018-11-14 17:02:33 -08:00
Tim Abbott
67c3593b39 sessions: Add coverage exception for now. 2018-11-14 15:28:35 -08:00
Tim Abbott
ae6fc0a471 sessions: Resync session middleware from Django upstream.
Until we resolve https://github.com/zulip/zulip/issues/10832, we will
need to maintain our own forked copy of Django's SessionMiddleware.
We apparently let this get out of date.

This fixes a few subtle bugs involving the user logout experience that
were throwing occasional exceptions (e.g. the UpdateError fix you can
see).
2018-11-14 15:16:12 -08:00
Steve Howell
75ead3379d node: Fix typo in tests (diffrent -> different). 2018-11-14 13:21:34 -08:00
Tim Abbott
a2371a96b7 docs: Clarify push registration for running manage.py correctly.
We've had several users get errors running this because they ran it as
a bash script; fix this my making the command super explicit.
2018-11-14 13:07:04 -08:00
Tim Abbott
8ab26df9f0 docs: Link to setup-certbot multiple hostname support. 2018-11-13 12:55:24 -08:00
Rohitt Vashishtha
95ba947f13 setup-cerbot: Allow issuing certificates for multiple domains.
This commit allows specifying Subject Alternative Names to issue certs
for multiple domains using certbot. The first name passed to certbot-auto
becomes the common name for the certificate; common name and the other
names are then added to the SAN field. All of these arguments are now
positional. Also read the following for the certbot syntax reference:

https://community.letsencrypt.org/t/how-to-specify-subject-name-on-san/

Fixes #10674.
2018-11-13 12:47:31 -08:00
Tim Abbott
11ffd6b370 requirements: Revert updates to thumbor virtualenv.
Apparently, this set of upgrades fails on the Travis production test
suite.  Not yet clear why, but reverting for now in any case.
2018-11-13 12:41:09 -08:00
Tim Abbott
6aee656f6b requirements: Update recursive dependencies.
This was generated by:
* `rm -f requirements/*.txt`
* `./tools/update-locked-requirements`

and passes tests.  The effect is to unpin ourselves from old versions
of a bunch of recursive dependencies of our third-party dependencies.
2018-11-13 12:31:35 -08:00
Hemanth V. Alluri
f8882db8a0 docs: Replace "MagickMock" with "MagicMock". 2018-11-13 12:20:08 -08:00
Vishnu Ks
d3138d486e requirements: Upgrade setuptools to 40.6.1. 2018-11-13 12:15:07 -08:00
Vishnu Ks
5f69452d48 requirements: Upgrade coverage to 4.5.2. 2018-11-13 12:15:07 -08:00
Vishnu Ks
7fafcd438e requirements: Upgrade SQLAlchemy to 1.2.14. 2018-11-13 12:15:07 -08:00
Vishnu Ks
2d140bae3e billing: Cast return value of _mock_stripe to CallableT.
Without the cast mypy raises the following error:

Incompatible return value type (got "Callable[..., Any]",
expected "CallableT")

This is a known issue: https://github.com/python/mypy/issues/1927
2018-11-12 23:42:59 -08:00
Vishnu Ks
20c41f3d3e billing: Replace IDs and other values before writing fixtures.
This makes a few other changes to the fixtures as well. Most are from API
updates, though I'm not sure why "Zulip Cloud Standard" got changed to
"Zulip Cloud Premium".

[Substantial edits by Rishi Gupta]
2018-11-12 23:24:33 -08:00
Tim Abbott
33c6390c14 billing: Fix missing target=blank for new navbar menu items. 2018-11-12 17:14:14 -08:00
Yashashvi Dave
766bdbfe89 stream settings: Rephrase info to state guest user can't join public stream.
Change wording of public stream description to
"Any member of the organization" from "Anybody"
to indicate that guest users can't subscribe even
public stream of organization.
2018-11-12 17:00:38 -08:00
Eeshan Garg
41c0e9ba47 webhooks: Add ReviewBoard integration. 2018-11-12 16:11:32 -08:00
Steve Howell
a942732d83 lint: Get rid of unused skip_rules.
We also go to the modern annotation style for mypy.
2018-11-12 16:00:52 -08:00
Steve Howell
3eb2b2be5f lint: Change lastLine logic slightly. 2018-11-12 15:47:11 -08:00
Steve Howell
a86e7fbd9f subject -> topic: Fix message tests. 2018-11-12 15:47:11 -08:00
Steve Howell
c90085b28e lint: Extend "subject" prohibition to zerver/tests.
There are several exemptions here, so I triaged
them into various buckets.
2018-11-12 15:47:11 -08:00
Steve Howell
394cd4c6b6 subject -> topic: Fix user group tests. 2018-11-12 15:47:11 -08:00
Steve Howell
ee9d321d9f subject -> topic: Fix tornado tests. 2018-11-12 15:47:11 -08:00
Steve Howell
2fe78ffe21 subject -> topic: Fix widget tests. 2018-11-12 15:47:11 -08:00
Steve Howell
d86dd165da gitter/slack/hipchat: Remove "subject" from conversions.
We (lexically) remove "subject" from the conversion code.  The
`build_message` helper calls `set_topic_name` under the hood,
so things still have "subject" in the JSON.

There was good code coverage on `build_message`.
2018-11-12 15:47:11 -08:00
Steve Howell
710095920f subject -> topic: Fix push notification tests.
We also make the topic name more clear.
2018-11-12 15:47:11 -08:00
Steve Howell
8e639543fb subject -> topic: Fix webhook system tests. 2018-11-12 15:47:11 -08:00
Steve Howell
8f8ceab062 subject -> topic: Fix external tests. 2018-11-12 15:47:11 -08:00
Steve Howell
cd76d4c308 subject -> topic: Fix events tests. 2018-11-12 15:47:11 -08:00
Steve Howell
4b38260a27 tests: Fix message.subject references. 2018-11-12 15:47:11 -08:00
Steve Howell
630dd8ac1b subject -> topic: Fix bugdown tests. 2018-11-12 15:47:11 -08:00
Steve Howell
1854ddbcd0 taiga tests: Use self.TOPIC instead of "subject". 2018-11-12 15:47:11 -08:00
Steve Howell
31e328c544 webhook tests: Replace SUBJECT with TOPIC. 2018-11-12 15:47:11 -08:00
Steve Howell
1fff890b71 webhooks: Change *_SUBJECT_TEMPLATE to *_TOPIC_TEMPLATE. 2018-11-12 15:47:11 -08:00
Steve Howell
ea98a44db3 webhooks: Replace SUBJECT_WITH_* with TOPIC_WITH_*. 2018-11-12 15:47:11 -08:00
Steve Howell
ced4d81856 Sweep tests for expected_subject -> expected_topic.
This is all in the webhooks tests, including some
docs for how to write those tests.
2018-11-12 15:47:11 -08:00
Steve Howell
3133998af9 test_messages: Fix a lot of subject -> topic_name. 2018-11-12 15:47:11 -08:00
Steve Howell
e55fc144b9 Add alias support to REQ helpers for subject/topic.
The alias support is generic here, and we use it for
migrating subject -> topic in REQ_topic().
2018-11-12 15:47:11 -08:00
Steve Howell
97062c4017 lint: Prevent use of "subject" in zerver/views. 2018-11-12 15:47:11 -08:00
Steve Howell
de6c08a842 Extract messages_for_topic(). 2018-11-12 15:47:11 -08:00
Steve Howell
b667dff4bc minor: Change wording in comment to avoid "subject".
We're trying to sweep "subject" out of the codebase,
even when it has nothing to do our legacy "subject"
field.  The rewording here will prevent some linter
noise.
2018-11-12 15:47:11 -08:00
Steve Howell
c7515a853c Use REQ_topic in update_message_backend().
Note that we now strip the topic in the converter.
We also strip it in the view handler, which is now
redundant, but I left it in as defensive code.
2018-11-12 15:47:11 -08:00
Steve Howell
3de1289d3e Rename subject -> topic_name in update_message_backend(). 2018-11-12 15:47:11 -08:00
Steve Howell
754795c0b7 Extract REQ_topic() helper.
For now we use it only in the send path, not the update
path.
2018-11-12 15:47:11 -08:00
Steve Howell
0a171bf9bf Fix "prev_subject" with LEGACY_PREV_TOPIC.
I added `LEGACY_` prefix to the var, because
otherwise you'd have really confusing code
where you change the key from `PREV_TOPIC`
to "prev_topic".
2018-11-12 15:47:11 -08:00
Steve Howell
a49ba8c577 Extract user_message_exists_for_topic(). 2018-11-12 15:47:11 -08:00
Steve Howell
39e5c61d4a Extact MATCH_TOPIC constant. 2018-11-12 15:47:11 -08:00
Steve Howell
500fcbb5e3 messages: Update subject -> topic_name.
This fixes several local vars named "subject".
2018-11-12 15:47:11 -08:00
Steve Howell
f7f071b52f minor: Fix subject -> topic in a comment. 2018-11-12 15:47:11 -08:00
Steve Howell
8981b65bbc Extract topic_column_sa(). 2018-11-12 15:47:11 -08:00
Steve Howell
b46fb5eaad Rename subject_matches -> topic_matches.
This is always either a var or a SQL label,
so it's safe to change.
2018-11-12 15:47:11 -08:00
Tim Abbott
fe8d400e3a node: Fix test failure due to 'narrowed' removal.
This was broken in 67fa755158.
2018-11-12 15:39:35 -08:00
Vishnu Ks
fba5b329ab version: Bump PROVISION_VERSION for py packages upgrade. 2018-11-12 15:27:26 -08:00
Vishnu Ks
11c595a33e requirements: Upgrade disposable-email-domains to 0.0.38. 2018-11-12 15:27:26 -08:00
Vishnu Ks
c4b197cd4f requirements: Upgrade Sphinx to 1.8.2. 2018-11-12 15:27:26 -08:00
Vishnu Ks
96bd1328a5 requirements: Upgrade pylibmc to 1.6.0. 2018-11-12 15:27:26 -08:00
Vishnu Ks
1657f0d161 requirements: Upgrade psycopg2 to 2.7.6.1. 2018-11-12 15:27:26 -08:00
Vishnu Ks
7121903fc5 requirements: Upgrade cryptography to 2.4.1. 2018-11-12 15:27:26 -08:00
Vishnu Ks
77473c2a6a requirements: Upgrade django-auth-ldap to 1.7.0. 2018-11-12 15:27:26 -08:00
Vishnu Ks
b46aeaf00b requirements: Upgrade setuptools to 40.5.0. 2018-11-12 15:27:26 -08:00
Vishnu Ks
c1aed13afe requirements: Upgrade wheel to 0.32.2. 2018-11-12 15:27:26 -08:00
Vishnu Ks
4f91a564ef requirements: Upgrade virtualenv-clone to 0.4.0. 2018-11-12 15:27:26 -08:00
Vishnu Ks
8f5cbb5c8c requirements: Upgrade typing to 3.6.6. 2018-11-12 15:27:26 -08:00
Vishnu Ks
3ae8e79c5a requirements: Upgrade Twisted to 18.9.0. 2018-11-12 15:27:26 -08:00
Vishnu Ks
1444fb8870 requirements: Upgrade sphinx-rtd-theme to 0.4.2. 2018-11-12 15:27:26 -08:00
Yashashvi Dave
89eebad14f user profile: Add user type/role in user profile popover.
Add user type/role in user's detail profile popover.

Fixes part of #10754
2018-11-12 15:13:44 -08:00
Yashashvi Dave
54dd7f0a43 user info popover: Add user type/role in user information popover.
Add user role-- "Administrator", "Member", "Bot" or "Guest"
under 'Local time' in user information popover.

Fixes part of #10754
2018-11-12 15:13:44 -08:00
Yashashvi Dave
614624d232 static/js/popover.js: Extract render_user_info_popover. 2018-11-12 15:13:43 -08:00
Tim Abbott
67fa755158 popovers: Remove now-unused narrowed argument to user info popover.
This stopped being used in bbfd33185c.
2018-11-12 15:10:19 -08:00
Tim Abbott
5a9f00dae4 popovers: Sort arguments for user info popover.
This makes it easier to see how the two duplicate implementations differ.
2018-11-12 15:09:09 -08:00
Tim Abbott
4c8f439ece popovers: Standardize calculation of show_user_profile. 2018-11-12 14:59:39 -08:00
Tim Abbott
96284bd336 popovers: Use attributes of user object more consistently.
This is a preparatory refactoring to make it easy to see what's
different as we deduplicate this logic.
2018-11-12 14:59:38 -08:00
Tim Abbott
08529507c8 popovers: Sort arguments to user info popover rendering.
This is a first step towards deduplicating this logic.
2018-11-12 14:59:23 -08:00
Yashashvi Dave
53201c5411 statis/js/people.js: Add function get_user_type.
Add function `get_user_type`, which returns user
type-"Administrator", "Guest", "Bot" or "Member"
depending on what they are.
2018-11-12 14:57:32 -08:00
Steve Howell
bb959acbaf Use modern huddle URLs in digest emails. 2018-11-12 12:01:09 -08:00
Steve Howell
e79e0018f7 Use modern PM URLs in digest emails. 2018-11-12 12:01:09 -08:00
Steve Howell
6a89446e80 tests: Add test for huddle digest urls. 2018-11-12 12:01:09 -08:00
Steve Howell
c08a3833e2 tests: Start to check urls in digest emails. 2018-11-12 12:01:09 -08:00
Tim Abbott
453c35d0f7 install: Provide a suggestive error message when missing Universe.
By far the dominant cause of errors when installing apt packages is
not having the Universe repository enabled in Ubuntu bionic (this
seems to have started happening a lot recently; I wonder if Ubuntu
changed the defaults for new server installs or something?).

In any case, providing that suggestion in the error output should help
reduce these a lot.
2018-11-12 10:56:39 -08:00
Tim Abbott
e7bb833a37 install: Improve some error output for common errors.
This uses `set +x` to hide the `echo` output, and then sets the font
color to red.
2018-11-12 10:55:06 -08:00
Pranjal Vyas
f729840040 docs: Fix typo in writing-views.md. 2018-11-11 16:56:56 -08:00
Vishnu Ks
f812b76c3b billing: Allow mock_stripe to take multiple function_name arguments. 2018-11-10 00:38:32 -05:00
Nolan Darilek
c0a8f0a66e accessibility: Add button role and tabindex to sender names.
This facilitates interacting with them via keyboard.
2018-11-09 17:33:42 -08:00
Nolan Darilek
fb54ea82b2 accessibility: Make the recipient row more accessible.
This primarily just exposes hidden icons.
2018-11-09 17:33:32 -08:00
Nolan Darilek
ef8ea330fa accessibility: Make individual messages more accessible.
We do this by setting a region and exposing hidden icons.
2018-11-09 17:33:21 -08:00
Nolan Darilek
253c034d90 accessibility: Label messages region, and add aria-live.
This tells assistive technologies to automatically speak new messages
when they arrive.
2018-11-09 17:32:59 -08:00
Tim Abbott
2c06615909 streams: Fix stream color synchronization.
Previously, when a new stream was created on a client other than the
current one, the browser would first receive the "stream_created"
event, and make up a client-side display color at that time to use in
the "stream settings" view (it doesn't yet know the color that was
selected when the user was actually subscribed, because it doesn't
even know yet that the user is being subscribed to this stream), and
then moments after it'll receive a "susbcribe" event letting the
client know that the user is subscribed (and specifying the color to
use).

However, due to an argument not being passed through properly and a
missing rerender, we were not properly updating either the data
structures or doing a stream colors rerender in order to show the new
color.

This fixes the issue reported in
https://chat.zulip.org/#narrow/stream/48-mobile/subject/stream.20colors/near/660170
2018-11-09 17:04:47 -08:00
Vishnu Ks
fe931d9b66 requirements: Upgrade sockjs-tornado to 1.0.6. 2018-11-09 10:17:55 -08:00
Vishnu Ks
349a9fe75a requirements: Upgrade social-auth-app-django to 3.1.0. 2018-11-09 10:17:55 -08:00
Vishnu Ks
6c0dee5471 requirements: Upgrade snakeviz to 1.0.0. 2018-11-09 10:17:55 -08:00
Vishnu Ks
2de33e413f requirements: Upgrade rsa to 4.0. 2018-11-09 10:17:55 -08:00
Vishnu Ks
ce4088c9ed requirements: Upgrade python-twitter to 3.5. 2018-11-09 10:17:55 -08:00
Vishnu Ks
502243bb75 requirements: Upgrade python-digital-ocean to 1.14.0. 2018-11-09 10:17:55 -08:00
Vishnu Ks
19db3088df requirements: Upgrade pip to 18.1. 2018-11-09 10:17:55 -08:00
Vishnu Ks
f4a81b743e requirements: Upgrade Pillow to 5.3.0. 2018-11-09 10:17:55 -08:00
Vishnu Ks
ff253fb1c7 requirements: Upgrade oauth2client to 4.1.3. 2018-11-09 10:17:55 -08:00
Vishnu Ks
6e15d4efc7 requirements: Upgrade Markupsafe to 1.1.0. 2018-11-09 10:17:55 -08:00
Vishnu Ks
90491692b7 requirements: Upgrade imagesize to 1.1.0. 2018-11-09 10:17:55 -08:00
Vishnu Ks
c73eb25c83 requirements: Upgrade httpretty to 0.9.6. 2018-11-09 10:17:55 -08:00
Vishnu Ks
ed973ebc71 requirements: Upgrade django-two-factor-auth to 1.8.0. 2018-11-09 10:17:55 -08:00
Vishnu Ks
d039ef871b requirements: Upgrade disposable-email-domains to 0.0.37. 2018-11-09 10:17:55 -08:00
Vishnu Ks
5ec9eb819b requirements: Upgrade certifi to 2018.10.15. 2018-11-09 10:17:55 -08:00
Vishnu Ks
1789cbea30 requirements: Upgrade beautifulsoup4 to 4.6.3. 2018-11-09 10:17:55 -08:00
Vishnu Ks
70a426c7ce requirements: Upgrade argon2-cffi to 18.3.0. 2018-11-09 10:17:55 -08:00
Vishnu Ks
1d11fc578e requirements: Upgrade albaster to 0.7.12. 2018-11-09 10:17:55 -08:00
Shubham Dhama
d5e1e8e5e3 settings: Move deactivate account button under "User settings".
This moves the deactivate account which was previously placed under
"SETTINGS / YOUR ACCOUNT" -> "Deactivate account" to "SETTINGS / YOUR
ACCOUNT" -> "User settings" for making it more visible.
2018-11-08 22:27:22 -08:00
Roman Godov
aa3682f9fc api: Add GET /user_groups documentation.
This documents our GET endpoint for interacting with Zulip's user
groups feature.

Fixes #10298.
2018-11-08 22:19:30 -08:00
Tim Abbott
8c8cb725bf api: Clarify slack-format outgoing webhook docs.
The previous discussion was confused about the fact that Slack sends
the outgoing webhook requests, not receives them.
2018-11-08 22:13:15 -08:00
Eeshan Garg
5c8b774628 outgoing-webhooks.md: Document example endpoint responses. 2018-11-08 22:07:56 -08:00
Eeshan Garg
10570d508f tools/lint: Fix JSON lint pattern for spaces after ':'.
Previously, a string ending in "... 😄" was reported as an
error and the linter complained that there should be a space
after the last ':'. This commit changes the pattern so that the
linter only checks for colons that are preceded by an opening
double-quote (").
2018-11-08 22:07:56 -08:00
Tim Abbott
106e5c3ed9 docs: Further document tokenized noreply email addresses.
We should still extend email.html to explain the security issue a bit
more clearly, since the article we link to is super long.
2018-11-08 15:26:21 -08:00
Tim Abbott
e88998e6d4 import: Fix buggy handling of avatars in Slack conversion.
This was a pretty nasty error, where we were accidentally accessing
the parent list in this inner loop function.

This appears to have been introduced as a refactoring bug in
7822ef38c2.
2018-11-08 15:03:39 -08:00
Roger Souza
6179bba2bd emails: Add one-click unsubscribe link to new login emails.
Fixes: #10547.
2018-11-08 14:39:33 -08:00
Tim Abbott
17be6e9165 confirmation: Move one_click_unsubscribe_link out of notifications.py.
This helps prevent a problematic import sequence when we start using
it from signals.py.
2018-11-08 14:39:33 -08:00
Nolan Darilek
33c2bbf0f1 accessibility: Make another reactions button semi-accessible. 2018-11-08 14:10:48 -08:00
Nolan Darilek
95781c913d accessibility: Hide non-actionable profile image from screen readers. 2018-11-08 14:10:11 -08:00
Nolan Darilek
bec0336092 accessibility: Add navigation roles for sidebars. 2018-11-08 14:04:51 -08:00
Steve Howell
cd4d447d90 Minor: change message.subject -> message.topic_name().
This also allows us to lock down
push_notifications.py from using "subject"
in the future.
2018-11-08 16:34:30 +00:00
Steve Howell
ff9a6c5ced minor: Rename subject -> topic_name in bugdown. 2018-11-08 16:21:14 +00:00
Steve Howell
70c16ddbcc lint: Prevent "subject" more aggressively.
We now prevent adding "subject" to any code in
zerver/lib, unless you specifically exempt it.

The new set called `FILES_WITH_LEGACY_SUJECT`
is also has comments that give a roadmap of what
to fix.
2018-11-08 15:33:36 +00:00
Steve Howell
e802be0fde Remove "subject" in notifications.py.
These last few are all pretty safe.
2018-11-08 15:12:10 +00:00
Steve Howell
39dc5f2691 Rename recipient_subject to bucket.
The various vars here that had recipient_subject
in the name now have either bucket or bucket_tup
there.

The shorter names are a bit easier to read, and the
original names were misleading for the PM case.

This was basically two search/replaces, and we have
good test coverage here, so it's pretty low risk
despite the messy diff.
2018-11-08 14:59:09 +00:00
Steve Howell
226a2826b5 Remove "subject" from zerver/lib/message.py.
We also lock this down file in the linter, so
that you can no longer introduce "subject"
to `message.py`.
2018-11-08 14:45:16 +00:00
Steve Howell
592dd290b2 Avoid "subject" in MessageDict. 2018-11-08 14:33:44 +00:00
Steve Howell
881e046c37 minor: Use TOPIC_NAME constant for "subject" event. 2018-11-08 14:01:45 +00:00
Rishi Gupta
2e89ffb0e2 billing: Make it easier to access /billing in tests. 2018-11-07 22:18:54 -05:00
Rishi Gupta
9b6b842f00 billing: Merge test_billing_home into test_initial_upgrade. 2018-11-07 22:18:54 -05:00
Tim Abbott
0e2f360177 security: Remove discussion of how other SaaS providers work.
While from my anecdotal experience, it is accurate that at many SaaS
providers, dozens or even hundreds of engineers have access to
production infrastructure, the "essentially all" statement isn't true
(not sure how that got added), and in any case, there aren't great
public sources we can cite to educate folks who might think Silicon
Valley startup practices are better than they actually are.
2018-11-07 16:14:29 -08:00
Steve Howell
d05f731c1c Eliminate the use of arguments.db_data.
We now attach zulip_db_data to the markdown engines
for classes that need it.  This was the last remaining
global we had, so we remove `arguments.py` here.
2018-11-07 10:44:49 -08:00
Steve Howell
b66304e167 refactor: Pass db_data down to helpers.
This mostly preps for the next commit.
2018-11-07 10:44:49 -08:00
Steve Howell
fa6f642c9c refactor: Remove global argument.current_realm. 2018-11-07 10:44:48 -08:00
Steve Howell
e1113c7011 refactor: Remove the global arguments.current_message.
The Markdown processor makes it fairly simple for
the helper classes to access the `md` engine.  We
now write `_md_engine.zulip_message` to avoid having
the current message in the global namespace.

Note that we do reuse engines for multiple messages,
but each engine is specific to a realm.  And we therefore
avoid even the theoretical possibility of leaking message
data between realms.
2018-11-07 10:44:48 -08:00
Steve Howell
ab24cc2535 minor: Pass in arguments.current_message to helpers. 2018-11-07 10:44:48 -08:00
Steve Howell
c26768ea63 bugdown: Import nl2br and tables extensions "normally".
This makes us consistent with how we import codehilite.

Using Python's normal import mechanism avoids some overhead
with Markdown having to parse dotted notation.

These modules are tiny, so they shouldn't impact startup
too much.  Also, by explicitly importing them, we avoid
the pitfall of having a sucessful startup and a broken
renderer.
2018-11-07 10:44:48 -08:00
Steve Howell
c8a2081526 bugdown: Break out helper functions for extending bugdown.
These will make profiling a lot easier, and you
can also quickly disable features.  The overhead
of these function calls is dwarfed by other concerns.
2018-11-07 10:44:47 -08:00
Steve Howell
ffa4daf936 bugdown: Reduce overhead of building link regexes.
We were building the same link regex every time
we build a Markdown engine, which happens twice
per realm.  It's an expensive operation due to
the complexity of the regex and us reading a file.
2018-11-07 10:33:11 -08:00
Steve Howell
18a76c54de bugdown: Extract build_engine.
This separates out the main job of building
an instance of Markdown from the fairly orthogonal
task of maintaining a list of engines.
2018-11-07 10:33:11 -08:00
Steve Howell
eb2269c614 fenced_code: Refactor to avoid nested classes.
Nested classes are kind of expensive in Python,
particularly when you throw in mypy annotations.

Also, flatter is arguably better, although it is
kind of a pain here not to have closures.
2018-11-07 10:33:11 -08:00
Steve Howell
dfadbcd3bc bugdown: Avoid ORM when there are no group names.
This change avoids hitting the Django ORM when
we don't find any possible group mentions in
the message content.

Django doesn't necessarily actually hit the database,
but it's still slow and shows up in profiles.
2018-11-07 10:33:11 -08:00
Steve Howell
88f50b97fd import: Render content before inserting messages.
By rendering content before bulk importing messages,
we avoid O(N) database hops.
2018-11-07 10:33:11 -08:00
Steve Howell
bf3f7d93d0 Simplify params for fix_message_rendered_content. 2018-11-07 10:33:11 -08:00
Steve Howell
0878d86706 import: Avoid unnecessary Message lookups.
We now no longer go the DB to get a Message object
during render.
2018-11-07 10:33:11 -08:00
Steve Howell
1e12b13a56 import: Avoid unnecessary sender lookups.
This commit speeds up the import by avoiding
sender lookups and instead using the data
for users that we already have in memory.

This avoids a few DB hops, many hops to memcached,
plus some object construction.

We now call do_render_markdown() directly.  This
also makes it more explicit that the import has
never rendered alert words.
2018-11-07 10:33:10 -08:00
Steve Howell
06f8d0af7e refactor: Extract do_render_markdown().
For the import-data codepath, we will call
the extracted function directly in a
subsequent commit.

The do_render_markdown() function has more
required parameters, which allows for more
explicit code and also allows us to flatten
out some logic related to alert words.  (We
just pass in empty sets/dicts as needed).
2018-11-07 10:20:14 -08:00
Steve Howell
35e9e5928f render: Upstream calculation of translate_emoticons. 2018-11-07 10:20:14 -08:00
Tim Abbott
b4f2e09b3a node: Fix a compose_actions test.
This was apparently wrong in 207d7a8ee6.
2018-11-07 10:17:43 -08:00
Steve Howell
82b808e620 bugdown: Avoid zephyr-related queries in rendering.
We can rely on `message_realm` being the same
as `message.sender.realm`, which allows us to
skip two queries to the database for the rare
Zephyr mirroring case.
2018-11-07 10:11:06 -08:00
Steve Howell
659c9dde00 bugdown: Avoid unnecessary realm queries.
We now keep realm in the arguments variable,
which avoids some lookups.

We also test settings before even trying to
get realms.
2018-11-07 10:08:46 -08:00
Steve Howell
f9a7451167 import: Pass in realm to render codepath.
We avoid querying the same realm multiple times.
2018-11-07 10:08:46 -08:00
Steve Howell
92a7f04149 import: Inline save_message_rendered_content().
This function requires a message object, whereas
we want to work with JSON data to avoid necessary
queries when we import data.  Inlining the function
sets us up for a subsequent refactoring.

We change the way we deal with theoretical return
values of `None` to use an assertion; otherwise,
we would have to loosen up a bunch of mypy types
from `str` to `Optional[str]`.  It's not clear `None`
is even possible--we've moved toward throwing exceptions
there instead of silently failing.
2018-11-07 10:08:45 -08:00
Steve Howell
6b6001c46c Remove "subject" from test_classes.py.
We now use "topic" lingo.
2018-11-07 10:03:53 -08:00
Steve Howell
ff60055fa4 Use topic_match_sa() for topic searches.
Note this introduce literal(), which makes the way
we handle topic mutes more consistent with general
topic searches.
2018-11-07 10:03:53 -08:00
Steve Howell
79d5e36ca3 Extract topic_match_sa() helper.
We'll also use this in zerver/views/messages.py, but
that's a bigger change.
2018-11-07 10:03:53 -08:00
Steve Howell
df743e8948 lint: Start to deprecate "subject" references. 2018-11-07 10:03:53 -08:00
Steve Howell
af1acf9239 Rename constant to MAX_TOPIC_NAME_LENGTH. 2018-11-07 10:03:53 -08:00
Steve Howell
2cf46f0122 Extract save_message_for_edit_use_case().
This is mostly extracted to help clean out
all "subject" references from actions.py.
2018-11-07 10:03:53 -08:00
Steve Howell
0cf4cddc5b Extract update_messages_for_topic_edit().
This is somewhat hairy logic, so it's nice
to extract it and not worry about variable leaks.

Also, this moves some legacy "subject" references out
of actions.py.
2018-11-07 10:03:53 -08:00
Steve Howell
32232377f7 Rename bugdown.subject_links -> topic_links. 2018-11-07 10:03:53 -08:00
Steve Howell
0e854288ee Add some string constants to topic.py.
The goal here is to make it easy to
forbid "subject" in actions.py.
2018-11-07 10:03:53 -08:00
Steve Howell
7252861785 Extract filter_by_topic_name_via_message. 2018-11-07 10:03:53 -08:00
Steve Howell
2fd0cfe708 Use topic_name() helper in more places. 2018-11-07 10:03:53 -08:00
Steve Howell
55afadc286 Introduce Message.set_topic_name(). 2018-11-07 10:03:53 -08:00
Steve Howell
dc8f893494 Extract filter_by_exact_message_topic(). 2018-11-07 10:03:53 -08:00
Steve Howell
56ecd227ff Add topic-related helpers for ScheduledMessage. 2018-11-07 10:03:53 -08:00
Steve Howell
50e3f85557 Extract topic.py library.
We start by including functions that do custom
queries for topic history.

The goal of this library is partly to quarantine
the legacy "subject" column on Message.
2018-11-07 10:03:53 -08:00
Rohitt Vashishtha
652477daea bugdown: Refactor name to mention_text in mention.py.
This commit renames some variables to make it clear that a mention's
text is not only the name of the user in all cases.
2018-11-07 10:02:53 -08:00
Marco Burstein
207d7a8ee6 compose: Use a placeholder when quoting and replying.
Use the placeholder `[Quoting…]` when quoting and replying before the
quote has been added to the message. Also, add tests to the
`compose_actions` Node tests for the new behavior.

Fix #10705.
2018-11-07 09:56:38 -08:00
Eeshan Garg
f9d867e138 webhooks/jira: Test double-escaped stream names with spaces.
A recent change to check_send_webhook_message allows webhooks to
unescape stream names before sending a message. This commit adds
a test for the edge case where the webhook URL is escaped twice by
a third-party.
2018-11-07 09:55:48 -08:00
Tim Abbott
e14a35b490 import: Don't assume a last_modified key is present.
This fixes an exception when importing uploaded file data from
Slack/HipChat.
2018-11-07 09:52:35 -08:00
Tim Abbott
bf77158dbc docs: Remove links to long-obsolete /plans.html.
We were previously sending users to a redirect, and that redirect
recently broke.
2018-11-07 08:11:07 -08:00
Tim Abbott
db51d40f4e release: Update version strings following 1.9.0 release. 2018-11-07 07:53:12 -08:00
Tim Abbott
06d39f87b7 Release Zulip Server 1.9.0. 2018-11-07 07:24:30 -08:00
Tim Abbott
aba25a5ef6 i18n: Update translation data from transifex. 2018-11-07 07:22:47 -08:00
Tim Abbott
f62050212b tornado: Fix supervisord configuration for multiple processes.
Apparently, we can use the process group naming style of having dashes
in the names without using the explicit nun_procs feature of
supervisord configuration.

The new configuration is perfectly satisfactory, so there's no real
reason to prefer the old approach.
2018-11-06 17:56:06 -08:00
Tim Abbott
60ed41081b scripts: Write to upgrade.log in upgrade-zulip-from-git.
This should simplify debugging when doing Git-based upgrades; this log
has long been useful for the main upgrade-zulip tool.
2018-11-06 17:56:01 -08:00
Tim Abbott
3f03dcdf5e nagios: Support multiple tornado processes.
This allows our Tornado monitoring to correctly report whether
multiple configured Tornado processes are running.

This setup isn't ideal, in that it can't detect cases where the wrong
set of Tornado processes are running, but it's nice and simple and
should catch most actual problems.
2018-11-06 16:50:03 -08:00
Tim Abbott
5abf4dee92 nagios: Add new host groups for Tornado processes.
We also move all the existing Tornado monitoring rules to the
singletornado_frontends rule.
2018-11-06 16:33:18 -08:00
Tim Abbott
5f3b79c9e7 nagios: Fix tab-based whitespace. 2018-11-06 16:30:29 -08:00
Tim Abbott
15519ee0bc requirements: Upgrade a few dependencies. 2018-11-06 16:28:02 -08:00
Eeshan Garg
006e47198c webhooks/jira: Decode stream name on our end.
Recently, one of our users reported that a JIRA webhook was not
able to send messages to a stream with a space character in its
name. Turns out that JIRA does something weird with webhook URLs,
such that escaped space characters (%20) are escaped again, so
that when the request gets to Zulip, the double escaped %20 is
evaluated as the literal characters `%20`, and not as a space.

We fix this by unescaping the stream name on our end before
sending the message forward!
2018-11-06 15:57:04 -08:00
Tim Abbott
6ef64fc752 narrow: Throw a clear error for invalid id: narrows.
This fixes an issue where searching for `id:` (with no operand) would
cause the server to 500, rather than returning a user-facing error.
2018-11-06 15:53:02 -08:00
Tim Abbott
e8290ccd6d add_new_user: Fix mention of running "python manage.py".
This won't work on Python 3.
2018-11-06 13:28:18 -08:00
Tim Abbott
8b661f2f03 slack import: Correctly detect the commenting user.
Fixes #10772.
2018-11-06 13:14:23 -08:00
Tim Abbott
86b38b1de7 tornado: Ensure TORNADO_PROCESSES is an integer.
When reading something from get_config, the default return type is a
string, which mean that various comparisons didn't work correctly.
2018-11-06 13:08:28 -08:00
Tim Abbott
1bf385e35f import: Avoid sending a content-type of None to S3.
The previous logic was incorrect, in that if `content_type` was set to
None (which happens with Slack/HipChat export, among other things),
then we wouldn't run the `guess_type` logic to auto-detect the
Content-Type to send to S3.
2018-11-06 13:03:14 -08:00
Tim Abbott
81a4c846f4 hipchat: Set s3_path for exported emoji.
This fixes an issue where the import process would fail when importing
to a server using the S3 backend.
2018-11-06 13:02:04 -08:00
Yashashvi Dave
8c72adc106 subscribers: Hide subscribers of non-subscribed stream for guest user in UI.
Guest users can't access subscribers of any(public or private)
non-subscribed streams. Therefore, hide subscribers list
of all non-subscribed streams from guest users in UI.

Fixes #10749 (the previous parts were fixed already).
2018-11-06 12:57:19 -08:00
Eeshan Garg
c6dd801525 docs: Fix a couple of broken links.
For the PHP link, I just found an equivalent link that detailed
some well-known PHP security vulnerabilities.

As for the now defunct RequestBin, another instance is hosted
by another domain, so we can recommend using that for now.
2018-11-06 12:54:36 -08:00
Tim Abbott
539e84e9a1 hipchat import: Stop setting last_modified=None.
The last_modified field is intended to support setting the
orig-last-modified field in the S3 backend when importing, basically
to keep track of this bit of pre-export data for debugging.  In the
event that it isn't available, the correct thing to do is not write
out an invalid `last_modified` field; we should just not write it out
at all.
2018-11-06 12:50:36 -08:00
Tim Abbott
a4f5d825b7 Revert "upgrade-zulip-from-git: Support specifying tag or commit ID for refname."
This reverts commit 5ea7feee7e.

We had to revert this because it didn't work with non-master branch names.
2018-11-06 12:40:45 -08:00
sameerchoubey
996caddb11 webhooks/taiga: Stop using emojis in notifications.
This fixes the fact that these emoji were sometimes not displaying
properly (because of changes in the emoji names used in the codebase),
while also making this integration more standard (since it was the
only one with such an aggressive use of emoji).
2018-11-06 12:06:49 -08:00
Roger Souza
f445a71272 hello: Fix responsiveness bug when page is at 800px. 2018-11-05 10:20:34 -08:00
Steve Howell
a092bee6b3 import: Reduce memory usage for UserMessage ids.
The UserMessage table can be huge, so creating a
bunch of entries in `ID_MAP` can overflow memory.

We don't have any tables that depend on `UserMessage`,
and we don't send the 'id' fields from `zerver_usermessage`
to the database, so re-mapping them was just busy-work.
2018-11-05 10:18:01 -08:00
Tim Abbott
2636db64e4 Update translation data from transifex. 2018-11-02 17:35:21 -07:00
Tim Abbott
e55a3b6cd1 version: Bump after 1.9.0-rc3 release. 2018-11-02 17:30:13 -07:00
1866 changed files with 94159 additions and 59425 deletions

View File

@@ -1,7 +1,86 @@
# See https://zulip.readthedocs.io/en/latest/testing/continuous-integration.html for
# high-level documentation on our CircleCI setup.
# See CircleCI upstream's docs on this config format:
# https://circleci.com/docs/2.0/language-python/
#
version: 2
aliases:
- &create_cache_directories
run:
name: create cache directories
command: |
dirs=(/srv/zulip-{npm,venv}-cache)
sudo mkdir -p "${dirs[@]}"
sudo chown -R circleci "${dirs[@]}"
- &restore_cache_package_json
restore_cache:
keys:
- v1-npm-base.{{ .Environment.CIRCLE_JOB }}-{{ checksum "package.json" }}-{{ checksum "yarn.lock" }}
- &restore_cache_requirements
restore_cache:
keys:
- v1-venv-base.{{ .Environment.CIRCLE_JOB }}-{{ checksum "requirements/thumbor.txt" }}-{{ checksum "requirements/dev.txt" }}
- &install_dependencies
run:
name: install dependencies
command: |
sudo apt-get update
# Install moreutils so we can use `ts` and `mispipe` in the following.
sudo apt-get install -y moreutils
# CircleCI sets the following in Git config at clone time:
# url.ssh://git@github.com.insteadOf https://github.com
# This breaks the Git clones in the NVM `install.sh` we run
# in `install-node`.
# TODO: figure out why that breaks, and whether we want it.
# (Is it an optimization?)
rm -f /home/circleci/.gitconfig
# This is the main setup job for the test suite
mispipe "tools/ci/setup-backend" ts
# Cleaning caches is mostly unnecessary in Circle, because
# most builds don't get to write to the cache.
# mispipe "scripts/lib/clean-unused-caches --verbose --threshold 0" ts
- &save_cache_package_json
save_cache:
paths:
- /srv/zulip-npm-cache
key: v1-npm-base.{{ .Environment.CIRCLE_JOB }}-{{ checksum "package.json" }}-{{ checksum "yarn.lock" }}
- &save_cache_requirements
save_cache:
paths:
- /srv/zulip-venv-cache
key: v1-venv-base.{{ .Environment.CIRCLE_JOB }}-{{ checksum "requirements/thumbor.txt" }}-{{ checksum "requirements/dev.txt" }}
# TODO: in Travis we also cache ~/zulip-emoji-cache, ~/node, ~/misc
- &run_backend_tests
run:
name: run backend tests
command: |
. /srv/zulip-py3-venv/bin/activate
mispipe ./tools/ci/backend ts
- &run_frontend_tests
run:
name: run frontend tests
command: |
. /srv/zulip-py3-venv/bin/activate
mispipe ./tools/ci/frontend ts
- &upload_coverage_report
run:
name: upload coverage report
command: |
. /srv/zulip-py3-venv/bin/activate
pip install codecov && codecov \
|| echo "Error in uploading coverage reports to codecov.io."
jobs:
"trusty-python-3.4":
docker:
@@ -13,71 +92,15 @@ jobs:
steps:
- checkout
- run:
name: create cache directories
command: |
dirs=(/srv/zulip-{npm,venv}-cache)
sudo mkdir -p "${dirs[@]}"
sudo chown -R circleci "${dirs[@]}"
- restore_cache:
keys:
- v1-npm-base.trusty-{{ checksum "package.json" }}-{{ checksum "yarn.lock" }}
- restore_cache:
keys:
- v1-venv-base.trusty-{{ checksum "requirements/thumbor.txt" }}-{{ checksum "requirements/dev.txt" }}
- run:
name: install dependencies
command: |
# Install moreutils so we can use `ts` and `mispipe` in the following.
sudo apt-get install -y moreutils
# CircleCI sets the following in Git config at clone time:
# url.ssh://git@github.com.insteadOf https://github.com
# This breaks the Git clones in the NVM `install.sh` we run
# in `install-node`.
# TODO: figure out why that breaks, and whether we want it.
# (Is it an optimization?)
rm -f /home/circleci/.gitconfig
# This is the main setup job for the test suite
mispipe "tools/travis/setup-backend" ts
# Cleaning caches is mostly unnecessary in Circle, because
# most builds don't get to write to the cache.
# mispipe "scripts/lib/clean-unused-caches --verbose --threshold 0" ts
- save_cache:
paths:
- /srv/zulip-npm-cache
key: v1-npm-base.trusty-{{ checksum "package.json" }}-{{ checksum "yarn.lock" }}
- save_cache:
paths:
- /srv/zulip-venv-cache
key: v1-venv-base.trusty-{{ checksum "requirements/thumbor.txt" }}-{{ checksum "requirements/dev.txt" }}
# TODO: in Travis we also cache ~/zulip-emoji-cache, ~/node, ~/misc
# The moment of truth! Run the tests.
- run:
name: run backend tests
command: |
. /srv/zulip-py3-venv/bin/activate
mispipe ./tools/travis/backend ts
- run:
name: run frontend tests
command: |
. /srv/zulip-py3-venv/bin/activate
mispipe ./tools/travis/frontend ts
- run:
name: upload coverage report
command: |
. /srv/zulip-py3-venv/bin/activate
pip install codecov && codecov \
|| echo "Error in uploading coverage reports to codecov.io."
- *create_cache_directories
- *restore_cache_package_json
- *restore_cache_requirements
- *install_dependencies
- *save_cache_package_json
- *save_cache_requirements
- *run_backend_tests
- *run_frontend_tests
- *upload_coverage_report
# - store_artifacts: # TODO
# path: var/casper/
@@ -93,50 +116,14 @@ jobs:
steps:
- checkout
- run:
name: create cache directories
command: |
dirs=(/srv/zulip-{npm,venv}-cache)
sudo mkdir -p "${dirs[@]}"
sudo chown -R circleci "${dirs[@]}"
- restore_cache:
keys:
- v1-npm-base.xenial-{{ checksum "package.json" }}-{{ checksum "yarn.lock" }}
- restore_cache:
keys:
- v1-venv-base.xenial-{{ checksum "requirements/thumbor.txt" }}-{{ checksum "requirements/dev.txt" }}
- run:
name: install dependencies
command: |
sudo apt-get update
sudo apt-get install -y moreutils
rm -f /home/circleci/.gitconfig
mispipe "tools/travis/setup-backend" ts
- save_cache:
paths:
- /srv/zulip-npm-cache
key: v1-npm-base.xenial-{{ checksum "package.json" }}-{{ checksum "yarn.lock" }}
- save_cache:
paths:
- /srv/zulip-venv-cache
key: v1-venv-base.xenial-{{ checksum "requirements/thumbor.txt" }}-{{ checksum "requirements/dev.txt" }}
- run:
name: run backend tests
command: |
. /srv/zulip-py3-venv/bin/activate
mispipe ./tools/travis/backend ts
- run:
name: upload coverage report
command: |
. /srv/zulip-py3-venv/bin/activate
pip install codecov && codecov \
|| echo "Error in uploading coverage reports to codecov.io."
- *create_cache_directories
- *restore_cache_package_json
- *restore_cache_requirements
- *install_dependencies
- *save_cache_package_json
- *save_cache_requirements
- *run_backend_tests
- *upload_coverage_report
"bionic-python-3.6":
docker:
@@ -148,53 +135,22 @@ jobs:
steps:
- checkout
- *create_cache_directories
- run:
name: create cache directories
name: do Bionic hack
command: |
dirs=(/srv/zulip-{npm,venv}-cache)
sudo mkdir -p "${dirs[@]}"
sudo chown -R circleci "${dirs[@]}"
# Temporary hack till `sudo service redis-server start` gets fixes in Bionic. See
# https://chat.zulip.org/#narrow/stream/3-backend/topic/Ubuntu.20bionic.20CircleCI
redis-server --daemonize yes
- restore_cache:
keys:
- v1-npm-base.bionic-{{ checksum "package.json" }}-{{ checksum "yarn.lock" }}
- restore_cache:
keys:
- v1-venv-base.bionic-{{ checksum "requirements/thumbor.txt" }}-{{ checksum "requirements/dev.txt" }}
- run:
name: install dependencies
command: |
sudo apt-get update
sudo apt-get install -y moreutils
rm -f /home/circleci/.gitconfig
mispipe "tools/travis/setup-backend" ts
- save_cache:
paths:
- /srv/zulip-npm-cache
key: v1-npm-base.bionic-{{ checksum "package.json" }}-{{ checksum "yarn.lock" }}
- save_cache:
paths:
- /srv/zulip-venv-cache
key: v1-venv-base.bionic-{{ checksum "requirements/thumbor.txt" }}-{{ checksum "requirements/dev.txt" }}
- run:
name: run backend tests
command: |
. /srv/zulip-py3-venv/bin/activate
mispipe ./tools/travis/backend ts
- run:
name: upload coverage report
command: |
. /srv/zulip-py3-venv/bin/activate
pip install codecov && codecov \
|| echo "Error in uploading coverage reports to codecov.io."
- *restore_cache_package_json
- *restore_cache_requirements
- *install_dependencies
- *save_cache_package_json
- *save_cache_requirements
- *run_backend_tests
- *upload_coverage_report
workflows:
version: 2

View File

@@ -26,11 +26,11 @@
"_": false,
"activity": false,
"admin": false,
"admin_sections": false,
"alert_words": false,
"alert_words_ui": false,
"attachments_ui": false,
"avatar": false,
"billing": false,
"blueslip": false,
"bot_data": false,
"bridge": false,
@@ -38,6 +38,7 @@
"buddy_list": false,
"channel": false,
"click_handlers": false,
"color_data": false,
"colorspace": false,
"common": false,
"components": false,
@@ -60,12 +61,14 @@
"emoji_picker": false,
"favicon": false,
"feature_flags": false,
"feedback_widget": false,
"fenced_code": false,
"flatpickr": false,
"floating_recipient_bar": false,
"gear_menu": false,
"hash_util": false,
"hashchange": false,
"helpers": false,
"home_msg_list": false,
"hotspots": false,
"i18n": false,
@@ -117,6 +120,8 @@
"pygments_data": false,
"reactions": false,
"realm_icon": false,
"realm_logo": false,
"realm_night_logo": false,
"recent_senders": false,
"reload": false,
"reload_state": false,
@@ -141,7 +146,7 @@
"settings_bots": false,
"settings_display": false,
"settings_emoji": false,
"settings_filters": false,
"settings_linkifiers": false,
"settings_invites": false,
"settings_muting": false,
"settings_notifications": false,
@@ -164,6 +169,7 @@
"stream_muting": false,
"stream_popover": false,
"stream_sort": false,
"StripeCheckout": false,
"submessage": false,
"subs": false,
"tab_bar": false,
@@ -185,19 +191,23 @@
"typing_events": false,
"typing_status": false,
"ui": false,
"ui_init": false,
"ui_report": false,
"ui_util": false,
"unread": false,
"unread_ops": false,
"unread_ui": false,
"upgrade": false,
"upload": false,
"upload_widget": false,
"user_events": false,
"user_groups": false,
"user_pill": false,
"user_search": false,
"user_status": false,
"user_status_ui": false,
"util": false,
"voting_widget": false,
"poll_widget": false,
"widgetize": false,
"zcommand": false,
"zform": false,
@@ -222,6 +232,12 @@
"functions": "never"
}
],
"comma-spacing": [ "error",
{
"before": false,
"after": true
}
],
"complexity": [ 0, 4 ],
"curly": 2,
"dot-notation": [ "error", { "allowKeywords": true } ],
@@ -239,6 +255,12 @@
"FunctionExpression": {"parameters": "first"},
"FunctionDeclaration": {"parameters": "first"}
}],
"key-spacing": [ "error",
{
"beforeColon": false,
"afterColon": true
}
],
"keyword-spacing": [ "error",
{
"before": true,
@@ -365,6 +387,7 @@
"quotes": [ 0, "single" ],
"radix": 2,
"semi": 2,
"semi-spacing": [2, {"before": false, "after": true}],
"space-before-blocks": 2,
"space-before-function-paren": [ "error",
{

View File

@@ -62,5 +62,6 @@
# Limit language features
"color-no-hex": true,
"color-named": "never",
}
}

View File

@@ -1,4 +1,4 @@
# See https://zulip.readthedocs.io/en/latest/testing/travis.html for
# See https://zulip.readthedocs.io/en/latest/testing/continuous-integration.html for
# high-level documentation on our Travis CI setup.
dist: trusty
group: deprecated-2017Q4
@@ -15,7 +15,7 @@ install:
- mispipe "pip install codecov" ts || mispipe "pip install codecov" ts
# This is the main setup job for the test suite
- mispipe "tools/travis/setup-$TEST_SUITE" ts
- mispipe "tools/ci/setup-$TEST_SUITE" ts
# Clean any caches that are not in use to avoid our cache
# becoming huge.
@@ -26,7 +26,7 @@ script:
# broken running their system puppet with Ruby. See
# https://travis-ci.org/zulip/zulip/jobs/240120991 for an example traceback.
- unset GEM_PATH
- mispipe "./tools/travis/$TEST_SUITE" ts
- mispipe "./tools/ci/$TEST_SUITE" ts
cache:
yarn: true
apt: false
@@ -38,7 +38,7 @@ cache:
- $HOME/misc
env:
global:
- BOTO_CONFIG=/tmp/nowhere
- BOTO_CONFIG=/nonexistent
language: python
# Our test suites generally run on Python 3.4, the version in
# Ubuntu 14.04 trusty, which is the oldest OS release we support.

View File

@@ -69,10 +69,11 @@ to help.
if you run into any troubles.
* Read the
[Zulip guide to Git](https://zulip.readthedocs.io/en/latest/git/index.html)
and do the Git tutorial (coming soon) if you are unfamiliar with Git,
getting help in
[#git help](https://chat.zulip.org/#narrow/stream/44-git-help) if you run
into any troubles.
and do the Git tutorial (coming soon) if you are unfamiliar with
Git, getting help in
[#git help](https://chat.zulip.org/#narrow/stream/44-git-help) if
you run into any troubles. Be sure to check out the
[extremely useful Zulip-specific tools page](https://zulip.readthedocs.io/en/latest/git/zulip-tools.html).
* Sign the
[Dropbox Contributor License Agreement](https://opensource.dropbox.com/cla/).

View File

@@ -11,7 +11,7 @@ RUN useradd -d /home/zulip -m zulip && echo 'zulip ALL=(ALL) NOPASSWD:ALL' >> /e
USER zulip
RUN ln -nsf /srv/zulip ~/zulip
RUN echo 'export LC_ALL="en_US.UTF-8" LANG="en_US.UTF-8" LANGUAGE="en_US.UTF-8"' >> ~zulip/.bashrc
RUN echo 'export LC_ALL="en_US.UTF-8" LANG="en_US.UTF-8" LANGUAGE="en_US.UTF-8"' >> ~zulip/.bash_profile
WORKDIR /srv/zulip

View File

@@ -5,13 +5,14 @@ immediacy of real-time chat with the productivity benefits of threaded
conversations. Zulip is used by open source projects, Fortune 500 companies,
large standards bodies, and others who need a real-time chat system that
allows users to easily process hundreds or thousands of messages a day. With
over 300 contributors merging over 500 commits a month, Zulip is also the
over 500 contributors merging over 500 commits a month, Zulip is also the
largest and fastest growing open source group chat project.
[![CircleCI Build Status](https://circleci.com/gh/zulip/zulip.svg?style=svg)](https://circleci.com/gh/zulip/zulip)
[![CircleCI branch](https://img.shields.io/circleci/project/github/zulip/zulip/master.svg)](https://circleci.com/gh/zulip/zulip)
[![Travis Build Status](https://travis-ci.org/zulip/zulip.svg?branch=master)](https://travis-ci.org/zulip/zulip)
[![Coverage Status](https://img.shields.io/codecov/c/github/zulip/zulip.svg)](https://codecov.io/gh/zulip/zulip)
[![Mypy coverage](https://img.shields.io/badge/mypy-100%25-green.svg)][mypy-coverage]
[![GitHub release](https://img.shields.io/github/release/zulip/zulip.svg)](https://github.com/zulip/zulip/releases/latest)
[![docs](https://readthedocs.org/projects/zulip/badge/?version=latest)](https://zulip.readthedocs.io/en/latest/)
[![Zulip chat](https://img.shields.io/badge/zulip-join_chat-brightgreen.svg)](https://chat.zulip.org)
[![Twitter](https://img.shields.io/badge/twitter-@zulip-blue.svg?style=flat)](https://twitter.com/zulip)
@@ -58,7 +59,7 @@ You might be interested in:
* **Running a Zulip server**. Setting up a server takes just a couple
of minutes. Zulip runs on Ubuntu 18.04 Bionic, Ubuntu 16.04 Xenial,
Ubuntu 14.04 Trusty, and Debian 9 Stretch. The installation process is
[documented here](https://zulip.readthedocs.io/en/stable/prod.html).
[documented here](https://zulip.readthedocs.io/en/stable/production/install.html).
Commercial support is available; see <https://zulipchat.com/plans>
for details.

View File

@@ -2,14 +2,14 @@ import time
from collections import OrderedDict, defaultdict
from datetime import datetime, timedelta
import logging
from typing import Any, Callable, Dict, List, \
from typing import Callable, Dict, List, \
Optional, Tuple, Type, Union
from django.conf import settings
from django.db import connection, models
from django.db import connection
from django.db.models import F
from analytics.models import Anomaly, BaseCount, \
from analytics.models import BaseCount, \
FillState, InstallationCount, RealmCount, StreamCount, \
UserCount, installation_epoch, last_successful_fill
from zerver.lib.logging_util import log_to_file
@@ -226,7 +226,6 @@ def do_drop_all_analytics_tables() -> None:
RealmCount.objects.all().delete()
InstallationCount.objects.all().delete()
FillState.objects.all().delete()
Anomaly.objects.all().delete()
def do_drop_single_stat(property: str) -> None:
UserCount.objects.filter(property=property).delete()

View File

@@ -1,10 +1,9 @@
from argparse import ArgumentParser
from datetime import timedelta
from django.core.management.base import BaseCommand
from django.utils.timezone import now as timezone_now
from analytics.models import InstallationCount, installation_epoch, \
from analytics.models import installation_epoch, \
last_successful_fill
from analytics.lib.counts import COUNT_STATS, CountStat
from zerver.lib.timestamp import floor_to_hour, floor_to_day, verify_UTC, \
@@ -12,7 +11,6 @@ from zerver.lib.timestamp import floor_to_hour, floor_to_day, verify_UTC, \
from zerver.models import Realm
import os
import sys
import time
from typing import Any, Dict

View File

@@ -1,6 +1,6 @@
from datetime import datetime, timedelta
from typing import Any, Dict, List, Mapping, Optional, Type, Union
from typing import Any, Dict, List, Mapping, Optional, Type
from django.core.management.base import BaseCommand
from django.utils.timezone import now as timezone_now
@@ -11,10 +11,10 @@ from analytics.lib.fixtures import generate_time_series_data
from analytics.lib.time_utils import time_range
from analytics.models import BaseCount, FillState, RealmCount, UserCount, \
StreamCount, InstallationCount
from zerver.lib.actions import do_change_is_admin
from zerver.lib.actions import do_change_is_admin, STREAM_ASSIGNMENT_COLORS
from zerver.lib.timestamp import floor_to_day
from zerver.models import Realm, UserProfile, Stream, Message, Client, \
RealmAuditLog, Recipient
from zerver.models import Realm, UserProfile, Stream, Client, \
RealmAuditLog, Recipient, Subscription
class Command(BaseCommand):
help = """Populates analytics tables with randomly generated data."""
@@ -72,7 +72,16 @@ class Command(BaseCommand):
do_change_is_admin(shylock, True)
stream = Stream.objects.create(
name='all', realm=realm, date_created=installation_time)
Recipient.objects.create(type_id=stream.id, type=Recipient.STREAM)
recipient = Recipient.objects.create(type_id=stream.id, type=Recipient.STREAM)
# Subscribe shylock to the stream to avoid invariant failures.
# TODO: This should use subscribe_users_to_streams from populate_db.
subs = [
Subscription(recipient=recipient,
user_profile=shylock,
color=STREAM_ASSIGNMENT_COLORS[0]),
]
Subscription.objects.bulk_create(subs)
def insert_fixture_data(stat: CountStat,
fixture_data: Mapping[Optional[str], List[int]],

View File

@@ -2,7 +2,6 @@ import datetime
from argparse import ArgumentParser
from typing import Any, List
import pytz
from django.core.management.base import BaseCommand
from django.db.models import Count
from django.utils.timezone import now as timezone_now

View File

@@ -25,20 +25,33 @@ class Command(BaseCommand):
realms = Realm.objects.all()
for realm in realms:
print(realm.string_id)
print("------------")
print("%25s %15s %10s" % ("stream", "subscribers", "messages"))
streams = Stream.objects.filter(realm=realm).exclude(Q(name__istartswith="tutorial-"))
invite_only_count = 0
# private stream count
private_count = 0
# public stream count
public_count = 0
for stream in streams:
if stream.invite_only:
invite_only_count += 1
continue
private_count += 1
else:
public_count += 1
print("------------")
print(realm.string_id, end=' ')
print("%10s %d public streams and" % ("(", public_count), end=' ')
print("%d private streams )" % (private_count,))
print("------------")
print("%25s %15s %10s %12s" % ("stream", "subscribers", "messages", "type"))
for stream in streams:
if stream.invite_only:
stream_type = 'private'
else:
stream_type = 'public'
print("%25s" % (stream.name,), end=' ')
recipient = Recipient.objects.filter(type=Recipient.STREAM, type_id=stream.id)
print("%10d" % (len(Subscription.objects.filter(recipient=recipient,
active=True)),), end=' ')
num_messages = len(Message.objects.filter(recipient=recipient))
print("%12d" % (num_messages,))
print("%d private streams" % (invite_only_count,))
print("%12d" % (num_messages,), end=' ')
print("%15s" % (stream_type,))
print("")

View File

@@ -11,6 +11,7 @@ from django.utils.timezone import utc as timezone_utc
from analytics.lib.counts import COUNT_STATS, logger, process_count_stat
from scripts.lib.zulip_tools import ENDC, WARNING
from zerver.lib.remote_server import send_analytics_to_remote_server
from zerver.lib.timestamp import floor_to_hour
from zerver.models import Realm
@@ -84,3 +85,6 @@ class Command(BaseCommand):
print("Finished updating analytics counts through %s in %.3fs" %
(fill_to_time, time.time() - start))
logger.info("Finished updating analytics counts through %s" % (fill_to_time,))
if settings.PUSH_NOTIFICATION_BOUNCER_URL and settings.SUBMIT_USAGE_STATISTICS:
send_analytics_to_remote_server()

View File

@@ -3,8 +3,6 @@ import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import zerver.lib.str_utils
class Migration(migrations.Migration):
dependencies = [

View File

@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from django.db import migrations, models
from django.db import migrations
class Migration(migrations.Migration):

View File

@@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
from django.db import migrations, models
import zerver.lib.str_utils
class Migration(migrations.Migration):
dependencies = [

View File

@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from django.db import migrations, models
from django.db import migrations
class Migration(migrations.Migration):

View File

@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.4 on 2017-01-16 20:50
from django.conf import settings
from django.db import migrations
class Migration(migrations.Migration):

View File

@@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.18 on 2019-02-02 02:47
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('analytics', '0012_add_on_delete'),
]
operations = [
migrations.RemoveField(
model_name='installationcount',
name='anomaly',
),
migrations.RemoveField(
model_name='realmcount',
name='anomaly',
),
migrations.RemoveField(
model_name='streamcount',
name='anomaly',
),
migrations.RemoveField(
model_name='usercount',
name='anomaly',
),
migrations.DeleteModel(
name='Anomaly',
),
]

View File

@@ -1,10 +1,10 @@
import datetime
from typing import Any, Dict, Optional, Tuple, Union
from typing import Optional
from django.db import models
from zerver.lib.timestamp import floor_to_day
from zerver.models import Realm, Recipient, Stream, UserProfile
from zerver.models import Realm, Stream, UserProfile
class FillState(models.Model):
property = models.CharField(max_length=40, unique=True) # type: str
@@ -34,13 +34,6 @@ def last_successful_fill(property: str) -> Optional[datetime.datetime]:
return fillstate.end_time
return fillstate.end_time - datetime.timedelta(hours=1)
# would only ever make entries here by hand
class Anomaly(models.Model):
info = models.CharField(max_length=1000) # type: str
def __str__(self) -> str:
return "<Anomaly: %s... %s>" % (self.info, self.id)
class BaseCount(models.Model):
# Note: When inheriting from BaseCount, you may want to rearrange
# the order of the columns in the migration to make sure they
@@ -49,7 +42,6 @@ class BaseCount(models.Model):
subgroup = models.CharField(max_length=16, null=True) # type: Optional[str]
end_time = models.DateTimeField() # type: datetime.datetime
value = models.BigIntegerField() # type: int
anomaly = models.ForeignKey(Anomaly, on_delete=models.SET_NULL, null=True) # type: Optional[Anomaly]
class Meta:
abstract = True

View File

@@ -1,6 +1,6 @@
from datetime import datetime, timedelta
from typing import Any, Dict, List, Optional, Tuple, Type, Union
from typing import Any, Dict, List, Optional, Tuple, Type
import ujson
from django.apps import apps
@@ -10,19 +10,20 @@ from django.test import TestCase
from django.utils.timezone import now as timezone_now
from django.utils.timezone import utc as timezone_utc
from analytics.lib.counts import COUNT_STATS, CountStat, DataCollector, \
from analytics.lib.counts import COUNT_STATS, CountStat, \
DependentCountStat, LoggingCountStat, do_aggregate_to_summary_table, \
do_drop_all_analytics_tables, do_drop_single_stat, \
do_fill_count_stat_at_hour, do_increment_logging_stat, \
process_count_stat, sql_data_collector
from analytics.models import Anomaly, BaseCount, \
from analytics.models import BaseCount, \
FillState, InstallationCount, RealmCount, StreamCount, \
UserCount, installation_epoch, last_successful_fill
UserCount, installation_epoch
from zerver.lib.actions import do_activate_user, do_create_user, \
do_deactivate_user, do_reactivate_user, update_user_activity_interval, \
do_invite_users, do_revoke_user_invite, do_resend_user_invite_email, \
InvitationError
from zerver.lib.timestamp import TimezoneNotUTCException, floor_to_day
from zerver.lib.topic import DB_TOPIC_NAME
from zerver.models import Client, Huddle, Message, Realm, \
RealmAuditLog, Recipient, Stream, UserActivityInterval, \
UserProfile, get_client, get_user, PreregistrationUser
@@ -56,7 +57,10 @@ class AnalyticsTestCase(TestCase):
'api_key': '42'}
for key, value in defaults.items():
kwargs[key] = kwargs.get(key, value)
return UserProfile.objects.create(**kwargs)
kwargs['delivery_email'] = kwargs['email']
user_profile = UserProfile.objects.create(**kwargs)
# TODO: Make this pass user_profile.full_clean()
return user_profile
def create_stream_with_recipient(self, **kwargs: Any) -> Tuple[Stream, Recipient]:
self.name_counter += 1
@@ -82,7 +86,7 @@ class AnalyticsTestCase(TestCase):
defaults = {
'sender': sender,
'recipient': recipient,
'subject': 'subject',
DB_TOPIC_NAME: 'subject',
'content': 'hi',
'pub_date': self.TIME_LAST_HOUR,
'sending_client': get_client("website")}
@@ -842,7 +846,6 @@ class TestDeleteStats(AnalyticsTestCase):
RealmCount.objects.create(realm=user.realm, **count_args)
InstallationCount.objects.create(**count_args)
FillState.objects.create(property='test', end_time=self.TIME_ZERO, state=FillState.DONE)
Anomaly.objects.create(info='test anomaly')
analytics = apps.get_app_config('analytics')
for table in list(analytics.models.values()):
@@ -865,7 +868,6 @@ class TestDeleteStats(AnalyticsTestCase):
InstallationCount.objects.create(**count_args)
FillState.objects.create(property='to_delete', end_time=self.TIME_ZERO, state=FillState.DONE)
FillState.objects.create(property='to_save', end_time=self.TIME_ZERO, state=FillState.DONE)
Anomaly.objects.create(info='test anomaly')
analytics = apps.get_app_config('analytics')
for table in list(analytics.models.values()):
@@ -873,11 +875,8 @@ class TestDeleteStats(AnalyticsTestCase):
do_drop_single_stat('to_delete')
for table in list(analytics.models.values()):
if table._meta.db_table == 'analytics_anomaly':
self.assertTrue(table.objects.exists())
else:
self.assertFalse(table.objects.filter(property='to_delete').exists())
self.assertTrue(table.objects.filter(property='to_save').exists())
self.assertFalse(table.objects.filter(property='to_delete').exists())
self.assertTrue(table.objects.filter(property='to_save').exists())
class TestActiveUsersAudit(AnalyticsTestCase):
def setUp(self) -> None:
@@ -1025,7 +1024,7 @@ class TestActiveUsersAudit(AnalyticsTestCase):
self.assertTrue(UserCount.objects.filter(
user=user, property=self.current_property, subgroup='false',
end_time=end_time, value=1).exists())
self.assertFalse(UserCount.objects.filter(user=user2).exists())
self.assertFalse(UserCount.objects.filter(user=user2, end_time=end_time).exists())
class TestRealmActiveHumans(AnalyticsTestCase):
def setUp(self) -> None:

View File

@@ -1,5 +1,5 @@
from datetime import datetime, timedelta
from typing import Dict, List, Optional
from typing import List, Optional
import mock
from django.utils.timezone import utc
@@ -8,8 +8,8 @@ from analytics.lib.counts import COUNT_STATS, CountStat
from analytics.lib.time_utils import time_range
from analytics.models import FillState, \
RealmCount, UserCount, last_successful_fill
from analytics.views import get_chart_data, rewrite_client_arrays, \
sort_by_totals, sort_client_labels, stats
from analytics.views import rewrite_client_arrays, \
sort_by_totals, sort_client_labels
from zerver.lib.test_classes import ZulipTestCase
from zerver.lib.timestamp import ceiling_to_day, \
ceiling_to_hour, datetime_to_timestamp

View File

@@ -16,6 +16,12 @@ i18n_urlpatterns = [
name='analytics.views.stats_for_realm'),
url(r'^stats/installation$', analytics.views.stats_for_installation,
name='analytics.views.stats_for_installation'),
url(r'^stats/remote/(?P<remote_server_id>[\S]+)/installation$',
analytics.views.stats_for_remote_installation,
name='analytics.views.stats_for_remote_installation'),
url(r'^stats/remote/(?P<remote_server_id>[\S]+)/realm/(?P<remote_realm_id>[\S]+)/$',
analytics.views.stats_for_remote_realm,
name='analytics.views.stats_for_remote_realm'),
# User-visible stats page
url(r'^stats$', analytics.views.stats,
@@ -38,6 +44,11 @@ v1_api_and_json_patterns = [
{'GET': 'analytics.views.get_chart_data_for_realm'}),
url(r'^analytics/chart_data/installation$', rest_dispatch,
{'GET': 'analytics.views.get_chart_data_for_installation'}),
url(r'^analytics/chart_data/remote/(?P<remote_server_id>[\S]+)/installation$', rest_dispatch,
{'GET': 'analytics.views.get_chart_data_for_remote_installation'}),
url(r'^analytics/chart_data/remote/(?P<remote_server_id>[\S]+)/realm/(?P<remote_realm_id>[\S]+)$',
rest_dispatch,
{'GET': 'analytics.views.get_chart_data_for_remote_realm'}),
]
i18n_urlpatterns += [

View File

@@ -1,28 +1,26 @@
import itertools
import json
import logging
import re
import time
from collections import defaultdict
from datetime import datetime, timedelta
from typing import Any, Callable, Dict, List, \
Optional, Set, Tuple, Type, Union
Optional, Set, Tuple, Type, Union, cast
import pytz
from django.conf import settings
from django.urls import reverse
from django.db import connection
from django.db.models import Sum
from django.db.models.query import QuerySet
from django.http import HttpRequest, HttpResponse, HttpResponseNotFound
from django.shortcuts import render
from django.template import RequestContext, loader
from django.template import loader
from django.utils.timezone import now as timezone_now, utc as timezone_utc
from django.utils.translation import ugettext as _
from jinja2 import Markup as mark_safe
from analytics.lib.counts import COUNT_STATS, CountStat, process_count_stat
from analytics.lib.counts import COUNT_STATS, CountStat
from analytics.lib.time_utils import time_range
from analytics.models import BaseCount, InstallationCount, \
RealmCount, StreamCount, UserCount, last_successful_fill, installation_epoch
@@ -32,16 +30,25 @@ from zerver.lib.exceptions import JsonableError
from zerver.lib.json_encoder_for_html import JSONEncoderForHTML
from zerver.lib.request import REQ, has_request_variables
from zerver.lib.response import json_success
from zerver.lib.timestamp import ceiling_to_day, \
ceiling_to_hour, convert_to_UTC, timestamp_to_datetime
from zerver.lib.timestamp import convert_to_UTC, timestamp_to_datetime
from zerver.models import Client, get_realm, Realm, \
UserActivity, UserActivityInterval, UserProfile
if settings.ZILENCER_ENABLED:
from zilencer.models import RemoteInstallationCount, RemoteRealmCount, \
RemoteZulipServer
else:
from mock import Mock
RemoteInstallationCount = Mock() # type: ignore # https://github.com/JukkaL/mypy/issues/1188
RemoteZulipServer = Mock() # type: ignore # https://github.com/JukkaL/mypy/issues/1188
RemoteRealmCount = Mock() # type: ignore # https://github.com/JukkaL/mypy/issues/1188
def render_stats(request: HttpRequest, data_url_suffix: str, target_name: str,
for_installation: bool=False) -> HttpRequest:
for_installation: bool=False, remote: bool=False) -> HttpRequest:
page_params = dict(
data_url_suffix=data_url_suffix,
for_installation=for_installation,
remote=remote,
debug_mode=False,
)
return render(request,
@@ -67,6 +74,14 @@ def stats_for_realm(request: HttpRequest, realm_str: str) -> HttpResponse:
return render_stats(request, '/realm/%s' % (realm_str,), realm.name or realm.string_id)
@require_server_admin
@has_request_variables
def stats_for_remote_realm(request: HttpRequest, remote_server_id: str,
remote_realm_id: str) -> HttpResponse:
server = RemoteZulipServer.objects.get(id=remote_server_id)
return render_stats(request, '/remote/%s/realm/%s' % (server.id, remote_realm_id),
"Realm %s on server %s" % (remote_realm_id, server.hostname))
@require_server_admin_api
@has_request_variables
def get_chart_data_for_realm(request: HttpRequest, user_profile: UserProfile,
@@ -77,26 +92,65 @@ def get_chart_data_for_realm(request: HttpRequest, user_profile: UserProfile,
return get_chart_data(request=request, user_profile=user_profile, realm=realm, **kwargs)
@require_server_admin_api
@has_request_variables
def get_chart_data_for_remote_realm(
request: HttpRequest, user_profile: UserProfile, remote_server_id: str,
remote_realm_id: str, **kwargs: Any) -> HttpResponse:
server = RemoteZulipServer.objects.get(id=remote_server_id)
return get_chart_data(request=request, user_profile=user_profile, server=server,
remote=True, remote_realm_id=int(remote_realm_id), **kwargs)
@require_server_admin
def stats_for_installation(request: HttpRequest) -> HttpResponse:
return render_stats(request, '/installation', 'Installation', True)
@require_server_admin
def stats_for_remote_installation(request: HttpRequest, remote_server_id: str) -> HttpResponse:
server = RemoteZulipServer.objects.get(id=remote_server_id)
return render_stats(request, '/remote/%s/installation' % (server.id,),
'remote Installation %s' % (server.hostname), True, True)
@require_server_admin_api
@has_request_variables
def get_chart_data_for_installation(request: HttpRequest, user_profile: UserProfile,
chart_name: str=REQ(), **kwargs: Any) -> HttpResponse:
return get_chart_data(request=request, user_profile=user_profile, for_installation=True, **kwargs)
@require_server_admin_api
@has_request_variables
def get_chart_data_for_remote_installation(
request: HttpRequest,
user_profile: UserProfile,
remote_server_id: str,
chart_name: str=REQ(),
**kwargs: Any) -> HttpResponse:
server = RemoteZulipServer.objects.get(id=remote_server_id)
return get_chart_data(request=request, user_profile=user_profile, for_installation=True,
remote=True, server=server, **kwargs)
@require_non_guest_user
@has_request_variables
def get_chart_data(request: HttpRequest, user_profile: UserProfile, chart_name: str=REQ(),
min_length: Optional[int]=REQ(converter=to_non_negative_int, default=None),
start: Optional[datetime]=REQ(converter=to_utc_datetime, default=None),
end: Optional[datetime]=REQ(converter=to_utc_datetime, default=None),
realm: Optional[Realm]=None, for_installation: bool=False) -> HttpResponse:
aggregate_table = RealmCount
realm: Optional[Realm]=None, for_installation: bool=False,
remote: bool=False, remote_realm_id: Optional[int]=None,
server: Optional[RemoteZulipServer]=None) -> HttpResponse:
if for_installation:
aggregate_table = InstallationCount
if remote:
aggregate_table = RemoteInstallationCount
assert server is not None
else:
aggregate_table = InstallationCount
else:
if remote:
aggregate_table = RemoteRealmCount
assert server is not None
assert remote_realm_id is not None
else:
aggregate_table = RealmCount
if chart_name == 'number_of_humans':
stats = [
@@ -147,29 +201,60 @@ def get_chart_data(request: HttpRequest, user_profile: UserProfile, chart_name:
{'start': start, 'end': end})
if realm is None:
# Note that this value is invalid for Remote tables; be
# careful not to access it in those code paths.
realm = user_profile.realm
if start is None:
if for_installation:
start = installation_epoch()
else:
start = realm.date_created
if end is None:
end = max(last_successful_fill(stat.property) or
datetime.min.replace(tzinfo=timezone_utc) for stat in stats)
if end is None or start > end:
logging.warning("User from realm %s attempted to access /stats, but the computed "
"start time: %s (creation of realm or installation) is later than the computed "
"end time: %s (last successful analytics update). Is the "
"analytics cron job running?" % (realm.string_id, start, end))
raise JsonableError(_("No analytics data available. Please contact your server administrator."))
if remote:
# For remote servers, we don't have fillstate data, and thus
# should simply use the first and last data points for the
# table.
assert server is not None
if not aggregate_table.objects.filter(server=server).exists():
raise JsonableError(_("No analytics data available. Please contact your server administrator."))
if start is None:
start = aggregate_table.objects.filter(server=server).first().end_time
if end is None:
end = aggregate_table.objects.filter(server=server).last().end_time
else:
# Otherwise, we can use tables on the current server to
# determine a nice range, and some additional validation.
if start is None:
if for_installation:
start = installation_epoch()
else:
start = realm.date_created
if end is None:
end = max(last_successful_fill(stat.property) or
datetime.min.replace(tzinfo=timezone_utc) for stat in stats)
if end is None or start > end:
logging.warning("User from realm %s attempted to access /stats, but the computed "
"start time: %s (creation of realm or installation) is later than the computed "
"end time: %s (last successful analytics update). Is the "
"analytics cron job running?" % (realm.string_id, start, end))
raise JsonableError(_("No analytics data available. Please contact your server administrator."))
assert len(set([stat.frequency for stat in stats])) == 1
end_times = time_range(start, end, stats[0].frequency, min_length)
data = {'end_times': end_times, 'frequency': stats[0].frequency} # type: Dict[str, Any]
aggregation_level = {InstallationCount: 'everyone', RealmCount: 'everyone', UserCount: 'user'}
aggregation_level = {
InstallationCount: 'everyone',
RealmCount: 'everyone',
RemoteInstallationCount: 'everyone',
RemoteRealmCount: 'everyone',
UserCount: 'user',
}
# -1 is a placeholder value, since there is no relevant filtering on InstallationCount
id_value = {InstallationCount: -1, RealmCount: realm.id, UserCount: user_profile.id}
id_value = {
InstallationCount: -1,
RealmCount: realm.id,
RemoteInstallationCount: cast(RemoteZulipServer, server).id if server is not None else None,
# TODO: RemoteRealmCount logic doesn't correctly handle
# filtering by server_id as well.
RemoteRealmCount: remote_realm_id,
UserCount: user_profile.id,
}
for table in tables:
data[aggregation_level[table]] = {}
for stat in stats:
@@ -213,6 +298,10 @@ def table_filtered_to_id(table: Type[BaseCount], key_id: int) -> QuerySet:
return StreamCount.objects.filter(stream_id=key_id)
elif table == InstallationCount:
return InstallationCount.objects.all()
elif table == RemoteInstallationCount:
return RemoteInstallationCount.objects.filter(server_id=key_id)
elif table == RemoteRealmCount:
return RemoteRealmCount.objects.filter(realm_id=key_id)
else:
raise AssertionError("Unknown table: %s" % (table,))
@@ -476,7 +565,7 @@ def realm_summary_table(realm_minutes: Dict[str, float]) -> str:
for row in rows:
row['date_created_day'] = row['date_created'].strftime('%Y-%m-%d')
row['plan_type_string'] = [
'', 'self hosted', 'limited', 'standard', 'standard free'][row['plan_type']]
'', 'self hosted', 'limited', 'standard', 'open source'][row['plan_type']]
row['age_days'] = int((now - row['date_created']).total_seconds()
/ 86400)
row['is_new'] = row['age_days'] < 12 * 7
@@ -490,6 +579,16 @@ def realm_summary_table(realm_minutes: Dict[str, float]) -> str:
except Exception:
row['history'] = ''
# estimate annual subscription revenue
total_amount = 0
if settings.BILLING_ENABLED:
from corporate.lib.stripe import estimate_annual_recurring_revenue_by_realm
estimated_arrs = estimate_annual_recurring_revenue_by_realm()
for row in rows:
if row['string_id'] in estimated_arrs:
row['amount'] = estimated_arrs[row['string_id']]
total_amount += sum(estimated_arrs.values())
# augment data with realm_minutes
total_hours = 0.0
for row in rows:
@@ -525,9 +624,10 @@ def realm_summary_table(realm_minutes: Dict[str, float]) -> str:
total_bot_count += int(row['bot_count'])
total_wau_count += int(row['wau_count'])
rows.append(dict(
total_row = dict(
string_id='Total',
plan_type_string="",
amount=total_amount,
stats_link = '',
date_created_day='',
realm_admin_email='',
@@ -536,7 +636,9 @@ def realm_summary_table(realm_minutes: Dict[str, float]) -> str:
bot_count=total_bot_count,
hours=int(total_hours),
wau_count=total_wau_count,
))
)
rows.insert(0, total_row)
content = loader.render_to_string(
'analytics/realm_summary_table.html',
@@ -562,15 +664,15 @@ def user_activity_intervals() -> Tuple[mark_safe, Dict[str, float]]:
).only(
'start',
'end',
'user_profile__email',
'user_profile__delivery_email',
'user_profile__realm__string_id'
).order_by(
'user_profile__realm__string_id',
'user_profile__email'
'user_profile__delivery_email'
)
by_string_id = lambda row: row.user_profile.realm.string_id
by_email = lambda row: row.user_profile.email
by_email = lambda row: row.user_profile.delivery_email
realm_minutes = {}
@@ -664,7 +766,8 @@ def sent_messages_report(realm: str) -> str:
return make_table(title, cols, rows)
def ad_hoc_queries() -> List[Dict[str, str]]:
def get_page(query: str, cols: List[str], title: str) -> Dict[str, str]:
def get_page(query: str, cols: List[str], title: str,
totals_columns: List[int]=[]) -> Dict[str, str]:
cursor = connection.cursor()
cursor.execute(query)
rows = cursor.fetchall()
@@ -676,11 +779,24 @@ def ad_hoc_queries() -> List[Dict[str, str]]:
for row in rows:
row[i] = fixup_func(row[i])
total_row = []
for i, col in enumerate(cols):
if col == 'Realm':
fix_rows(i, realm_activity_link)
elif col in ['Last time', 'Last visit']:
fix_rows(i, format_date_for_activity_reports)
elif col == 'Hostname':
for row in rows:
row[i] = remote_installation_stats_link(row[0], row[i])
if len(totals_columns) > 0:
if i == 0:
total_row.append("Total")
elif i in totals_columns:
total_row.append(str(sum(row[i] for row in rows if row[i] is not None)))
else:
total_row.append('')
if len(totals_columns) > 0:
rows.insert(0, total_row)
content = make_table(title, cols, rows)
@@ -830,6 +946,49 @@ def ad_hoc_queries() -> List[Dict[str, str]]:
pages.append(get_page(query, cols, title))
title = 'Remote Zulip servers'
query = '''
with icount as (
select
server_id,
max(value) as max_value,
max(end_time) as max_end_time
from zilencer_remoteinstallationcount
where
property='active_users:is_bot:day'
and subgroup='false'
group by server_id
),
remote_push_devices as (
select server_id, count(distinct(user_id)) as push_user_count from zilencer_remotepushdevicetoken
group by server_id
)
select
rserver.id,
rserver.hostname,
rserver.contact_email,
max_value,
push_user_count,
max_end_time
from zilencer_remotezulipserver rserver
left join icount on icount.server_id = rserver.id
left join remote_push_devices on remote_push_devices.server_id = rserver.id
order by max_value DESC NULLS LAST, push_user_count DESC NULLS LAST
'''
cols = [
'ID',
'Hostname',
'Contact email',
'Analytics users',
'Mobile users',
'Last update time',
]
pages.append(get_page(query, cols, title,
totals_columns=[3, 4]))
return pages
@require_server_admin
@@ -855,7 +1014,7 @@ def get_activity(request: HttpRequest) -> HttpResponse:
def get_user_activity_records_for_realm(realm: str, is_bot: bool) -> QuerySet:
fields = [
'user_profile__full_name',
'user_profile__email',
'user_profile__delivery_email',
'query',
'client__name',
'count',
@@ -867,7 +1026,7 @@ def get_user_activity_records_for_realm(realm: str, is_bot: bool) -> QuerySet:
user_profile__is_active=True,
user_profile__is_bot=is_bot
)
records = records.order_by("user_profile__email", "-last_visit")
records = records.order_by("user_profile__delivery_email", "-last_visit")
records = records.select_related('user_profile', 'client').only(*fields)
return records
@@ -881,7 +1040,7 @@ def get_user_activity_records_for_email(email: str) -> List[QuerySet]:
]
records = UserActivity.objects.filter(
user_profile__email=email
user_profile__delivery_email=email
)
records = records.order_by("-last_visit")
records = records.select_related('user_profile', 'client').only(*fields)
@@ -980,6 +1139,12 @@ def realm_stats_link(realm_str: str) -> mark_safe:
stats_link = '<a href="{}"><i class="fa fa-pie-chart"></i></a>'.format(url, realm_str)
return mark_safe(stats_link)
def remote_installation_stats_link(server_id: int, hostname: str) -> mark_safe:
url_name = 'analytics.views.stats_for_remote_installation'
url = reverse(url_name, kwargs=dict(remote_server_id=server_id))
stats_link = '<a href="{}"><i class="fa fa-pie-chart"></i>{}</a>'.format(url, hostname)
return mark_safe(stats_link)
def realm_client_table(user_summaries: Dict[str, Dict[str, Dict[str, Any]]]) -> str:
exclude_keys = [
'internal',
@@ -1055,7 +1220,7 @@ def realm_user_summary_table(all_records: List[QuerySet],
user_records = {}
def by_email(record: QuerySet) -> str:
return record.user_profile.email
return record.user_profile.delivery_email
for email, records in itertools.groupby(all_records, by_email):
user_records[email] = get_user_activity_summary(list(records))
@@ -1126,7 +1291,7 @@ def get_realm_activity(request: HttpRequest, realm_str: str) -> HttpResponse:
except Realm.DoesNotExist:
return HttpResponseNotFound("Realm %s does not exist" % (realm_str,))
admin_emails = {admin.email for admin in admins}
admin_emails = {admin.delivery_email for admin in admins}
for is_bot, page_title in [(False, 'Humans'), (True, 'Bots')]:
all_records = list(get_user_activity_records_for_realm(realm_str, is_bot))

View File

@@ -16,12 +16,11 @@ from django.http import HttpRequest, HttpResponse
from django.shortcuts import render
from django.utils.timezone import now as timezone_now
from zerver.lib.utils import generate_random_token
from zerver.models import PreregistrationUser, EmailChangeStatus, MultiuseInvite, \
UserProfile, Realm
from random import SystemRandom
import string
from typing import Any, Dict, Optional, Union
from typing import Dict, Optional, Union
class ConfirmationKeyException(Exception):
WRONG_LENGTH = 1
@@ -70,8 +69,11 @@ def create_confirmation_link(obj: ContentType, host: str,
confirmation_type: int,
url_args: Optional[Dict[str, str]]=None) -> str:
key = generate_key()
realm = None
if hasattr(obj, 'realm'):
realm = obj.realm
Confirmation.objects.create(content_object=obj, date_sent=timezone_now(), confirmation_key=key,
realm=obj.realm, type=confirmation_type)
realm=realm, type=confirmation_type)
return confirmation_url(key, host, confirmation_type, url_args)
def confirmation_url(confirmation_key: str, host: str,
@@ -99,6 +101,7 @@ class Confirmation(models.Model):
SERVER_REGISTRATION = 5
MULTIUSE_INVITE = 6
REALM_CREATION = 7
REALM_REACTIVATION = 8
type = models.PositiveSmallIntegerField() # type: int
def __str__(self) -> str:
@@ -121,8 +124,18 @@ _properties = {
'zerver.views.registration.accounts_home_from_multiuse_invite',
validity_in_days=settings.INVITATION_LINK_VALIDITY_DAYS),
Confirmation.REALM_CREATION: ConfirmationType('check_prereg_key_and_redirect'),
Confirmation.REALM_REACTIVATION: ConfirmationType('zerver.views.realm.realm_reactivation'),
}
def one_click_unsubscribe_link(user_profile: UserProfile, email_type: str) -> str:
"""
Generate a unique link that a logged-out user can visit to unsubscribe from
Zulip e-mails without having to first log in.
"""
return create_confirmation_link(user_profile, user_profile.realm.host,
Confirmation.UNSUBSCRIBE,
url_args = {'email_type': email_type})
# Functions related to links generated by the generate_realm_creation_link.py
# management command.
# Note that being validated here will just allow the user to access the create_realm

View File

@@ -2,8 +2,6 @@
# Copyright: (c) 2008, Jarek Zgoda <jarek.zgoda@gmail.com>
from typing import Any, Dict
__revision__ = '$Id: settings.py 12 2008-11-23 19:38:52Z jarek.zgoda $'
STATUS_ACTIVE = 1

View File

@@ -1,8 +1,10 @@
import datetime
from datetime import datetime
from decimal import Decimal
from functools import wraps
import logging
import math
import os
from typing import Any, Callable, Dict, Optional, TypeVar, Tuple
from typing import Any, Callable, Dict, Optional, TypeVar, Tuple, cast
import ujson
from django.conf import settings
@@ -12,13 +14,12 @@ from django.utils.timezone import now as timezone_now
from django.core.signing import Signer
import stripe
from zerver.lib.exceptions import JsonableError
from zerver.lib.logging_util import log_to_file
from zerver.lib.timestamp import datetime_to_timestamp, timestamp_to_datetime
from zerver.lib.utils import generate_random_token
from zerver.lib.actions import do_change_plan_type
from zerver.models import Realm, UserProfile, RealmAuditLog
from corporate.models import Customer, Plan, Coupon, BillingProcessor
from corporate.models import Customer, CustomerPlan, LicenseLedger, \
get_active_plan
from zproject.settings import get_secret
STRIPE_PUBLISHABLE_KEY = get_secret('stripe_publishable_key')
@@ -32,30 +33,17 @@ billing_logger = logging.getLogger('corporate.stripe')
log_to_file(billing_logger, BILLING_LOG_PATH)
log_to_file(logging.getLogger('stripe'), BILLING_LOG_PATH)
## Note: this is no longer accurate, as of when we added coupons
# To generate the fixture data in stripe_fixtures.json:
# * Set PRINT_STRIPE_FIXTURE_DATA to True
# * ./manage.py setup_stripe
# * Customer.objects.all().delete()
# * Log in as a user, and go to http://localhost:9991/upgrade/
# * Click Add card. Enter the following billing details:
# Name: Ada Starr, Street: Under the sea, City: Pacific,
# Zip: 33333, Country: United States
# Card number: 4242424242424242, Expiry: 03/33, CVV: 333
# * Click Make payment.
# * Copy out the 4 blobs of json from the dev console into stripe_fixtures.json.
# The contents of that file are '{\n' + concatenate the 4 json blobs + '\n}'.
# Then you can run e.g. `M-x mark-whole-buffer` and `M-x indent-region` in emacs
# to prettify the file (and make 4 space indents).
# * Copy out the customer id, plan id, and quantity values into
# corporate.tests.test_stripe.StripeTest.setUp.
# * Set PRINT_STRIPE_FIXTURE_DATA to False
PRINT_STRIPE_FIXTURE_DATA = False
CallableT = TypeVar('CallableT', bound=Callable[..., Any])
MIN_INVOICED_LICENSES = 30
DEFAULT_INVOICE_DAYS_UNTIL_DUE = 30
def get_seat_count(realm: Realm) -> int:
return UserProfile.objects.filter(realm=realm, is_active=True, is_bot=False).count()
non_guests = UserProfile.objects.filter(
realm=realm, is_active=True, is_bot=False, is_guest=False).count()
guests = UserProfile.objects.filter(
realm=realm, is_active=True, is_bot=False, is_guest=True).count()
return max(non_guests, math.ceil(guests / 5))
def sign_string(string: str) -> Tuple[str, str]:
salt = generate_random_token(64)
@@ -66,13 +54,78 @@ def unsign_string(signed_string: str, salt: str) -> str:
signer = Signer(salt=salt)
return signer.unsign(signed_string)
# Be extremely careful changing this function. Historical billing periods
# are not stored anywhere, and are just computed on the fly using this
# function. Any change you make here should return the same value (or be
# within a few seconds) for basically any value from when the billing system
# went online to within a year from now.
def add_months(dt: datetime, months: int) -> datetime:
assert(months >= 0)
# It's fine that the max day in Feb is 28 for leap years.
MAX_DAY_FOR_MONTH = {1: 31, 2: 28, 3: 31, 4: 30, 5: 31, 6: 30,
7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31}
year = dt.year
month = dt.month + months
while month > 12:
year += 1
month -= 12
day = min(dt.day, MAX_DAY_FOR_MONTH[month])
# datetimes don't support leap seconds, so don't need to worry about those
return dt.replace(year=year, month=month, day=day)
def next_month(billing_cycle_anchor: datetime, dt: datetime) -> datetime:
estimated_months = round((dt - billing_cycle_anchor).days * 12. / 365)
for months in range(max(estimated_months - 1, 0), estimated_months + 2):
proposed_next_month = add_months(billing_cycle_anchor, months)
if 20 < (proposed_next_month - dt).days < 40:
return proposed_next_month
raise AssertionError('Something wrong in next_month calculation with '
'billing_cycle_anchor: %s, dt: %s' % (billing_cycle_anchor, dt))
# TODO take downgrade into account
def next_renewal_date(plan: CustomerPlan, event_time: datetime) -> datetime:
months_per_period = {
CustomerPlan.ANNUAL: 12,
CustomerPlan.MONTHLY: 1,
}[plan.billing_schedule]
periods = 1
dt = plan.billing_cycle_anchor
while dt <= event_time:
dt = add_months(plan.billing_cycle_anchor, months_per_period * periods)
periods += 1
return dt
# TODO take downgrade into account
def next_invoice_date(plan: CustomerPlan) -> datetime:
months_per_period = {
CustomerPlan.ANNUAL: 12,
CustomerPlan.MONTHLY: 1,
}[plan.billing_schedule]
if plan.automanage_licenses:
months_per_period = 1
periods = 1
dt = plan.billing_cycle_anchor
while dt <= plan.next_invoice_date:
dt = add_months(plan.billing_cycle_anchor, months_per_period * periods)
periods += 1
return dt
def renewal_amount(plan: CustomerPlan, event_time: datetime) -> Optional[int]: # nocoverage: TODO
if plan.fixed_price is not None:
return plan.fixed_price
last_ledger_entry = add_plan_renewal_to_license_ledger_if_needed(plan, event_time)
if last_ledger_entry.licenses_at_next_renewal is None:
return None
assert(plan.price_per_license is not None) # for mypy
return plan.price_per_license * last_ledger_entry.licenses_at_next_renewal
class BillingError(Exception):
# error messages
CONTACT_SUPPORT = _("Something went wrong. Please contact %s." % (settings.ZULIP_ADMINISTRATOR,))
TRY_RELOADING = _("Something went wrong. Please reload the page.")
# description is used only for tests
def __init__(self, description: str, message: str) -> None:
def __init__(self, description: str, message: str=CONTACT_SUPPORT) -> None:
self.description = description
self.message = message
@@ -89,9 +142,6 @@ def catch_stripe_errors(func: CallableT) -> CallableT:
if STRIPE_PUBLISHABLE_KEY is None:
raise BillingError('missing stripe config', "Missing Stripe config. "
"See https://zulip.readthedocs.io/en/latest/subsystems/billing.html.")
if not Plan.objects.exists():
raise BillingError('missing plans',
"Plan objects not created. Please run ./manage.py setup_stripe")
try:
return func(*args, **kwargs)
# See https://stripe.com/docs/api/python#error_handling, though
@@ -114,58 +164,11 @@ def catch_stripe_errors(func: CallableT) -> CallableT:
@catch_stripe_errors
def stripe_get_customer(stripe_customer_id: str) -> stripe.Customer:
stripe_customer = stripe.Customer.retrieve(stripe_customer_id, expand=["default_source"])
if PRINT_STRIPE_FIXTURE_DATA:
print(''.join(['"customer_with_subscription": ', str(stripe_customer), ','])) # nocoverage
return stripe_customer
return stripe.Customer.retrieve(stripe_customer_id, expand=["default_source"])
@catch_stripe_errors
def stripe_get_upcoming_invoice(stripe_customer_id: str) -> stripe.Invoice:
stripe_invoice = stripe.Invoice.upcoming(customer=stripe_customer_id)
if PRINT_STRIPE_FIXTURE_DATA:
print(''.join(['"upcoming_invoice": ', str(stripe_invoice), ','])) # nocoverage
return stripe_invoice
@catch_stripe_errors
def stripe_get_invoice_preview_for_downgrade(
stripe_customer_id: str, stripe_subscription_id: str,
stripe_subscriptionitem_id: str) -> stripe.Invoice:
return stripe.Invoice.upcoming(
customer=stripe_customer_id, subscription=stripe_subscription_id,
subscription_items=[{'id': stripe_subscriptionitem_id, 'quantity': 0}])
def preview_invoice_total_for_downgrade(stripe_customer: stripe.Customer) -> int:
stripe_subscription = extract_current_subscription(stripe_customer)
if stripe_subscription is None:
# Most likely situation is: user A goes to billing page, user B
# cancels subscription, user A clicks on "downgrade" or something
# else that calls this function.
billing_logger.error("Trying to extract subscription item that doesn't exist, for Stripe customer %s"
% (stripe_customer.id,))
raise BillingError('downgrade without subscription', BillingError.TRY_RELOADING)
for item in stripe_subscription['items']:
# There should only be one item, but we can't index into stripe_subscription['items']
stripe_subscriptionitem_id = item.id
return stripe_get_invoice_preview_for_downgrade(
stripe_customer.id, stripe_subscription.id, stripe_subscriptionitem_id).total
# Return type should be Optional[stripe.Subscription], which throws a mypy error.
# Will fix once we add type stubs for the Stripe API.
def extract_current_subscription(stripe_customer: stripe.Customer) -> Any:
if not stripe_customer.subscriptions:
return None
for stripe_subscription in stripe_customer.subscriptions:
if stripe_subscription.status != "canceled":
return stripe_subscription
return None
@catch_stripe_errors
def do_create_customer(user: UserProfile, stripe_token: Optional[str]=None,
coupon: Optional[Coupon]=None) -> stripe.Customer:
def do_create_stripe_customer(user: UserProfile, stripe_token: Optional[str]=None) -> Customer:
realm = user.realm
stripe_coupon_id = None
if coupon is not None:
stripe_coupon_id = coupon.stripe_coupon_id
# We could do a better job of handling race conditions here, but if two
# people from a realm try to upgrade at exactly the same time, the main
# bad thing that will happen is that we will create an extra stripe
@@ -174,10 +177,7 @@ def do_create_customer(user: UserProfile, stripe_token: Optional[str]=None,
description="%s (%s)" % (realm.string_id, realm.name),
email=user.email,
metadata={'realm_id': realm.id, 'realm_str': realm.string_id},
source=stripe_token,
coupon=stripe_coupon_id)
if PRINT_STRIPE_FIXTURE_DATA:
print(''.join(['"create_customer": ', str(stripe_customer), ','])) # nocoverage
source=stripe_token)
event_time = timestamp_to_datetime(stripe_customer.created)
with transaction.atomic():
RealmAuditLog.objects.create(
@@ -187,10 +187,11 @@ def do_create_customer(user: UserProfile, stripe_token: Optional[str]=None,
RealmAuditLog.objects.create(
realm=user.realm, acting_user=user, event_type=RealmAuditLog.STRIPE_CARD_CHANGED,
event_time=event_time)
Customer.objects.create(realm=realm, stripe_customer_id=stripe_customer.id)
customer, created = Customer.objects.update_or_create(realm=realm, defaults={
'stripe_customer_id': stripe_customer.id})
user.is_billing_admin = True
user.save(update_fields=["is_billing_admin"])
return stripe_customer
return customer
@catch_stripe_errors
def do_replace_payment_source(user: UserProfile, stripe_token: str) -> stripe.Customer:
@@ -205,213 +206,262 @@ def do_replace_payment_source(user: UserProfile, stripe_token: str) -> stripe.Cu
event_time=timezone_now())
return updated_stripe_customer
@catch_stripe_errors
def do_replace_coupon(user: UserProfile, coupon: Coupon) -> stripe.Customer:
stripe_customer = stripe_get_customer(Customer.objects.get(realm=user.realm).stripe_customer_id)
stripe_customer.coupon = coupon.stripe_coupon_id
return stripe.Customer.save(stripe_customer)
# event_time should roughly be timezone_now(). Not designed to handle
# event_times in the past or future
# TODO handle downgrade
def add_plan_renewal_to_license_ledger_if_needed(plan: CustomerPlan, event_time: datetime) -> LicenseLedger:
last_ledger_entry = LicenseLedger.objects.filter(plan=plan).order_by('-id').first()
last_renewal = LicenseLedger.objects.filter(plan=plan, is_renewal=True) \
.order_by('-id').first().event_time
plan_renewal_date = next_renewal_date(plan, last_renewal)
if plan_renewal_date <= event_time:
return LicenseLedger.objects.create(
plan=plan, is_renewal=True, event_time=plan_renewal_date,
licenses=last_ledger_entry.licenses_at_next_renewal,
licenses_at_next_renewal=last_ledger_entry.licenses_at_next_renewal)
return last_ledger_entry
# Returns Customer instead of stripe_customer so that we don't make a Stripe
# API call if there's nothing to update
def update_or_create_stripe_customer(user: UserProfile, stripe_token: Optional[str]=None) -> Customer:
realm = user.realm
customer = Customer.objects.filter(realm=realm).first()
if customer is None or customer.stripe_customer_id is None:
return do_create_stripe_customer(user, stripe_token=stripe_token)
if stripe_token is not None:
do_replace_payment_source(user, stripe_token)
return customer
def compute_plan_parameters(
automanage_licenses: bool, billing_schedule: int,
discount: Optional[Decimal]) -> Tuple[datetime, datetime, datetime, int]:
# Everything in Stripe is stored as timestamps with 1 second resolution,
# so standardize on 1 second resolution.
# TODO talk about leapseconds?
billing_cycle_anchor = timezone_now().replace(microsecond=0)
if billing_schedule == CustomerPlan.ANNUAL:
# TODO use variables to account for Zulip Plus
price_per_license = 8000
period_end = add_months(billing_cycle_anchor, 12)
elif billing_schedule == CustomerPlan.MONTHLY:
price_per_license = 800
period_end = add_months(billing_cycle_anchor, 1)
else:
raise AssertionError('Unknown billing_schedule: {}'.format(billing_schedule))
if discount is not None:
# There are no fractional cents in Stripe, so round down to nearest integer.
price_per_license = int(float(price_per_license * (1 - discount / 100)) + .00001)
next_invoice_date = period_end
if automanage_licenses:
next_invoice_date = add_months(billing_cycle_anchor, 1)
return billing_cycle_anchor, next_invoice_date, period_end, price_per_license
# Only used for cloud signups
@catch_stripe_errors
def do_subscribe_customer_to_plan(user: UserProfile, stripe_customer: stripe.Customer, stripe_plan_id: str,
seat_count: int, tax_percent: float) -> None:
if extract_current_subscription(stripe_customer) is not None:
# Most likely due to two people in the org going to the billing page,
# and then both upgrading their plan. We don't send clients
# real-time event updates for the billing pages, so this is more
# likely than it would be in other parts of the app.
billing_logger.error("Stripe customer %s trying to subscribe to %s, "
"but has an active subscription" % (stripe_customer.id, stripe_plan_id))
def process_initial_upgrade(user: UserProfile, licenses: int, automanage_licenses: bool,
billing_schedule: int, stripe_token: Optional[str]) -> None:
realm = user.realm
customer = update_or_create_stripe_customer(user, stripe_token=stripe_token)
if CustomerPlan.objects.filter(customer=customer, status=CustomerPlan.ACTIVE).exists():
# Unlikely race condition from two people upgrading (clicking "Make payment")
# at exactly the same time. Doesn't fully resolve the race condition, but having
# a check here reduces the likelihood.
billing_logger.warning(
"Customer {} trying to upgrade, but has an active subscription".format(customer))
raise BillingError('subscribing with existing subscription', BillingError.TRY_RELOADING)
customer = Customer.objects.get(stripe_customer_id=stripe_customer.id)
# Note that there is a race condition here, where if two users upgrade at exactly the
# same time, they will have two subscriptions, and get charged twice. We could try to
# reduce the chance of it with a well-designed idempotency_key, but it's not easy since
# we also need to be careful not to block the customer from retrying if their
# subscription attempt fails (e.g. due to insufficient funds).
# Success here implies the stripe_customer was charged: https://stripe.com/docs/billing/lifecycle#active
# Otherwise we should expect it to throw a stripe.error.
stripe_subscription = stripe.Subscription.create(
customer=stripe_customer.id,
billing='charge_automatically',
items=[{
'plan': stripe_plan_id,
'quantity': seat_count,
}],
prorate=True,
tax_percent=tax_percent)
if PRINT_STRIPE_FIXTURE_DATA:
print(''.join(['"create_subscription": ', str(stripe_subscription), ','])) # nocoverage
billing_cycle_anchor, next_invoice_date, period_end, price_per_license = compute_plan_parameters(
automanage_licenses, billing_schedule, customer.default_discount)
# The main design constraint in this function is that if you upgrade with a credit card, and the
# charge fails, everything should be rolled back as if nothing had happened. This is because we
# expect frequent card failures on initial signup.
# Hence, if we're going to charge a card, do it at the beginning, even if we later may have to
# adjust the number of licenses.
charge_automatically = stripe_token is not None
if charge_automatically:
stripe_charge = stripe.Charge.create(
amount=price_per_license * licenses,
currency='usd',
customer=customer.stripe_customer_id,
description="Upgrade to Zulip Standard, ${} x {}".format(price_per_license/100, licenses),
receipt_email=user.email,
statement_descriptor='Zulip Standard')
# Not setting a period start and end, but maybe we should? Unclear what will make things
# most similar to the renewal case from an accounting perspective.
stripe.InvoiceItem.create(
amount=price_per_license * licenses * -1,
currency='usd',
customer=customer.stripe_customer_id,
description="Payment (Card ending in {})".format(cast(stripe.Card, stripe_charge.source).last4),
discountable=False)
# TODO: The correctness of this relies on user creation, deactivation, etc being
# in a transaction.atomic() with the relevant RealmAuditLog entries
with transaction.atomic():
customer.has_billing_relationship = True
customer.save(update_fields=['has_billing_relationship'])
customer.realm.has_seat_based_plan = True
customer.realm.save(update_fields=['has_seat_based_plan'])
# billed_licenses can greater than licenses if users are added between the start of
# this function (process_initial_upgrade) and now
billed_licenses = max(get_seat_count(realm), licenses)
plan_params = {
'automanage_licenses': automanage_licenses,
'charge_automatically': charge_automatically,
'price_per_license': price_per_license,
'discount': customer.default_discount,
'billing_cycle_anchor': billing_cycle_anchor,
'billing_schedule': billing_schedule,
'tier': CustomerPlan.STANDARD}
plan = CustomerPlan.objects.create(
customer=customer,
next_invoice_date=next_invoice_date,
**plan_params)
ledger_entry = LicenseLedger.objects.create(
plan=plan,
is_renewal=True,
event_time=billing_cycle_anchor,
licenses=billed_licenses,
licenses_at_next_renewal=billed_licenses)
plan.invoiced_through = ledger_entry
plan.save(update_fields=['invoiced_through'])
RealmAuditLog.objects.create(
realm=customer.realm,
acting_user=user,
event_type=RealmAuditLog.STRIPE_PLAN_CHANGED,
event_time=timestamp_to_datetime(stripe_subscription.created),
extra_data=ujson.dumps({'plan': stripe_plan_id, 'quantity': seat_count}))
realm=realm, acting_user=user, event_time=billing_cycle_anchor,
event_type=RealmAuditLog.CUSTOMER_PLAN_CREATED,
extra_data=ujson.dumps(plan_params))
stripe.InvoiceItem.create(
currency='usd',
customer=customer.stripe_customer_id,
description='Zulip Standard',
discountable=False,
period = {'start': datetime_to_timestamp(billing_cycle_anchor),
'end': datetime_to_timestamp(period_end)},
quantity=billed_licenses,
unit_amount=price_per_license)
current_seat_count = get_seat_count(customer.realm)
if seat_count != current_seat_count:
RealmAuditLog.objects.create(
realm=customer.realm,
event_type=RealmAuditLog.STRIPE_PLAN_QUANTITY_RESET,
event_time=timestamp_to_datetime(stripe_subscription.created),
requires_billing_update=True,
extra_data=ujson.dumps({'quantity': current_seat_count}))
if charge_automatically:
billing_method = 'charge_automatically'
days_until_due = None
else:
billing_method = 'send_invoice'
days_until_due = DEFAULT_INVOICE_DAYS_UNTIL_DUE
stripe_invoice = stripe.Invoice.create(
auto_advance=True,
billing=billing_method,
customer=customer.stripe_customer_id,
days_until_due=days_until_due,
statement_descriptor='Zulip Standard')
stripe.Invoice.finalize_invoice(stripe_invoice)
def process_initial_upgrade(user: UserProfile, plan: Plan, seat_count: int, stripe_token: str) -> None:
customer = Customer.objects.filter(realm=user.realm).first()
from zerver.lib.actions import do_change_plan_type
do_change_plan_type(realm, Realm.STANDARD)
def update_license_ledger_for_automanaged_plan(realm: Realm, plan: CustomerPlan,
event_time: datetime) -> None:
last_ledger_entry = add_plan_renewal_to_license_ledger_if_needed(plan, event_time)
# todo: handle downgrade, where licenses_at_next_renewal should be 0
licenses_at_next_renewal = get_seat_count(realm)
licenses = max(licenses_at_next_renewal, last_ledger_entry.licenses)
LicenseLedger.objects.create(
plan=plan, event_time=event_time, licenses=licenses,
licenses_at_next_renewal=licenses_at_next_renewal)
def update_license_ledger_if_needed(realm: Realm, event_time: datetime) -> None:
customer = Customer.objects.filter(realm=realm).first()
if customer is None:
stripe_customer = do_create_customer(user, stripe_token=stripe_token)
else:
stripe_customer = do_replace_payment_source(user, stripe_token)
do_subscribe_customer_to_plan(
user=user,
stripe_customer=stripe_customer,
stripe_plan_id=plan.stripe_plan_id,
seat_count=seat_count,
# TODO: billing address details are passed to us in the request;
# use that to calculate taxes.
tax_percent=0)
do_change_plan_type(user, Realm.STANDARD)
return
plan = get_active_plan(customer)
if plan is None:
return
if not plan.automanage_licenses:
return
update_license_ledger_for_automanaged_plan(realm, plan, event_time)
def attach_discount_to_realm(user: UserProfile, percent_off: int) -> None:
coupon = Coupon.objects.get(percent_off=percent_off)
customer = Customer.objects.filter(realm=user.realm).first()
if customer is None:
do_create_customer(user, coupon=coupon)
else:
do_replace_coupon(user, coupon)
@catch_stripe_errors
def process_downgrade(user: UserProfile) -> None:
stripe_customer = stripe_get_customer(
Customer.objects.filter(realm=user.realm).first().stripe_customer_id)
subscription_balance = preview_invoice_total_for_downgrade(stripe_customer)
# If subscription_balance > 0, they owe us money. This is likely due to
# people they added in the last day, so we can just forgive it.
# Stripe automatically forgives it when we delete the subscription, so nothing we need to do there.
if subscription_balance < 0:
stripe_customer.account_balance = stripe_customer.account_balance + subscription_balance
stripe_subscription = extract_current_subscription(stripe_customer)
# Wish these two could be transaction.atomic
stripe_subscription = stripe_subscription.delete()
stripe.Customer.save(stripe_customer)
with transaction.atomic():
user.realm.has_seat_based_plan = False
user.realm.save(update_fields=['has_seat_based_plan'])
RealmAuditLog.objects.create(
realm=user.realm,
acting_user=user,
event_type=RealmAuditLog.STRIPE_PLAN_CHANGED,
event_time=timestamp_to_datetime(stripe_subscription.canceled_at),
extra_data=ujson.dumps({'plan': None, 'quantity': stripe_subscription.quantity}))
# Doing this last, since it results in user-visible confirmation (via
# product changes) that the downgrade succeeded.
# Keeping it out of the transaction.atomic block because it will
# eventually have a lot of stuff going on.
do_change_plan_type(user, Realm.LIMITED)
## Process RealmAuditLog
def do_set_subscription_quantity(
customer: Customer, timestamp: int, idempotency_key: str, quantity: int) -> None:
stripe_customer = stripe_get_customer(customer.stripe_customer_id)
stripe_subscription = extract_current_subscription(stripe_customer)
stripe_subscription.quantity = quantity
stripe_subscription.proration_date = timestamp
stripe_subscription.save(idempotency_key=idempotency_key)
def do_adjust_subscription_quantity(
customer: Customer, timestamp: int, idempotency_key: str, delta: int) -> None:
stripe_customer = stripe_get_customer(customer.stripe_customer_id)
stripe_subscription = extract_current_subscription(stripe_customer)
stripe_subscription.quantity = stripe_subscription.quantity + delta
stripe_subscription.proration_date = timestamp
stripe_subscription.save(idempotency_key=idempotency_key)
def increment_subscription_quantity(
customer: Customer, timestamp: int, idempotency_key: str) -> None:
return do_adjust_subscription_quantity(customer, timestamp, idempotency_key, 1)
def decrement_subscription_quantity(
customer: Customer, timestamp: int, idempotency_key: str) -> None:
return do_adjust_subscription_quantity(customer, timestamp, idempotency_key, -1)
@catch_stripe_errors
def process_billing_log_entry(processor: BillingProcessor, log_row: RealmAuditLog) -> None:
processor.state = BillingProcessor.STARTED
processor.log_row = log_row
processor.save()
customer = Customer.objects.get(realm=log_row.realm)
timestamp = datetime_to_timestamp(log_row.event_time)
idempotency_key = 'process_billing_log_entry:%s' % (log_row.id,)
extra_args = {} # type: Dict[str, Any]
if log_row.extra_data is not None:
extra_args = ujson.loads(log_row.extra_data)
processing_functions = {
RealmAuditLog.STRIPE_PLAN_QUANTITY_RESET: do_set_subscription_quantity,
RealmAuditLog.USER_CREATED: increment_subscription_quantity,
RealmAuditLog.USER_ACTIVATED: increment_subscription_quantity,
RealmAuditLog.USER_DEACTIVATED: decrement_subscription_quantity,
RealmAuditLog.USER_REACTIVATED: increment_subscription_quantity,
} # type: Dict[str, Callable[..., None]]
processing_functions[log_row.event_type](customer, timestamp, idempotency_key, **extra_args)
processor.state = BillingProcessor.DONE
processor.save()
def get_next_billing_log_entry(processor: BillingProcessor) -> Optional[RealmAuditLog]:
if processor.state == BillingProcessor.STARTED:
return processor.log_row
assert processor.state != BillingProcessor.STALLED
if processor.state not in [BillingProcessor.DONE, BillingProcessor.SKIPPED]:
raise BillingError(
'unknown processor state',
"Check for typos, since this value is sometimes set by hand: %s" % (processor.state,))
if processor.realm is None:
realms_with_processors = BillingProcessor.objects.exclude(
realm=None).values_list('realm', flat=True)
query = RealmAuditLog.objects.exclude(realm__in=realms_with_processors)
else:
global_processor = BillingProcessor.objects.get(realm=None)
query = RealmAuditLog.objects.filter(
realm=processor.realm, id__lt=global_processor.log_row.id)
return query.filter(id__gt=processor.log_row.id,
requires_billing_update=True).order_by('id').first()
def run_billing_processor_one_step(processor: BillingProcessor) -> bool:
# Returns True if a row was processed, or if processing was attempted
log_row = get_next_billing_log_entry(processor)
if log_row is None:
if processor.realm is not None:
processor.delete()
return False
try:
process_billing_log_entry(processor, log_row)
return True
except Exception as e:
# Possible errors include processing subscription quantity entries
# after downgrade, since the downgrade code doesn't check that
# billing processor is up to date
billing_logger.error("Error on log_row.realm=%s, event_type=%s, log_row.id=%s, "
"processor.id=%s, processor.realm=%s" % (
processor.log_row.realm.string_id, processor.log_row.event_type,
processor.log_row.id, processor.id, processor.realm))
if isinstance(e, StripeCardError):
if processor.realm is None:
BillingProcessor.objects.create(log_row=processor.log_row,
realm=processor.log_row.realm,
state=BillingProcessor.STALLED)
processor.state = BillingProcessor.SKIPPED
def invoice_plan(plan: CustomerPlan, event_time: datetime) -> None:
if plan.invoicing_status == CustomerPlan.STARTED:
raise NotImplementedError('Plan with invoicing_status==STARTED needs manual resolution.')
add_plan_renewal_to_license_ledger_if_needed(plan, event_time)
assert(plan.invoiced_through is not None)
licenses_base = plan.invoiced_through.licenses
invoice_item_created = False
for ledger_entry in LicenseLedger.objects.filter(plan=plan, id__gt=plan.invoiced_through.id,
event_time__lte=event_time).order_by('id'):
price_args = {} # type: Dict[str, int]
if ledger_entry.is_renewal:
if plan.fixed_price is not None:
price_args = {'amount': plan.fixed_price}
else:
processor.state = BillingProcessor.STALLED
processor.save()
return True
raise
assert(plan.price_per_license is not None) # needed for mypy
price_args = {'unit_amount': plan.price_per_license,
'quantity': ledger_entry.licenses}
description = "Zulip Standard - renewal"
elif ledger_entry.licenses != licenses_base:
assert(plan.price_per_license)
last_renewal = LicenseLedger.objects.filter(
plan=plan, is_renewal=True, event_time__lte=ledger_entry.event_time) \
.order_by('-id').first().event_time
period_end = next_renewal_date(plan, ledger_entry.event_time)
proration_fraction = (period_end - ledger_entry.event_time) / (period_end - last_renewal)
price_args = {'unit_amount': int(plan.price_per_license * proration_fraction + .5),
'quantity': ledger_entry.licenses - licenses_base}
description = "Additional license ({} - {})".format(
ledger_entry.event_time.strftime('%b %-d, %Y'), period_end.strftime('%b %-d, %Y'))
if price_args:
plan.invoiced_through = ledger_entry
plan.invoicing_status = CustomerPlan.STARTED
plan.save(update_fields=['invoicing_status', 'invoiced_through'])
idempotency_key = 'ledger_entry:{}'.format(ledger_entry.id) # type: Optional[str]
if settings.TEST_SUITE:
idempotency_key = None
stripe.InvoiceItem.create(
currency='usd',
customer=plan.customer.stripe_customer_id,
description=description,
discountable=False,
period = {'start': datetime_to_timestamp(ledger_entry.event_time),
'end': datetime_to_timestamp(next_renewal_date(plan, ledger_entry.event_time))},
idempotency_key=idempotency_key,
**price_args)
invoice_item_created = True
plan.invoiced_through = ledger_entry
plan.invoicing_status = CustomerPlan.DONE
plan.save(update_fields=['invoicing_status', 'invoiced_through'])
licenses_base = ledger_entry.licenses
if invoice_item_created:
if plan.charge_automatically:
billing_method = 'charge_automatically'
days_until_due = None
else:
billing_method = 'send_invoice'
days_until_due = DEFAULT_INVOICE_DAYS_UNTIL_DUE
stripe_invoice = stripe.Invoice.create(
auto_advance=True,
billing=billing_method,
customer=plan.customer.stripe_customer_id,
days_until_due=days_until_due,
statement_descriptor='Zulip Standard')
stripe.Invoice.finalize_invoice(stripe_invoice)
plan.next_invoice_date = next_invoice_date(plan)
plan.save(update_fields=['next_invoice_date'])
def invoice_plans_as_needed(event_time: datetime) -> None:
for plan in CustomerPlan.objects.filter(next_invoice_date__lte=event_time):
invoice_plan(plan, event_time)
def attach_discount_to_realm(realm: Realm, discount: Decimal) -> None:
Customer.objects.update_or_create(realm=realm, defaults={'default_discount': discount})
def process_downgrade(user: UserProfile) -> None: # nocoverage
pass
def estimate_annual_recurring_revenue_by_realm() -> Dict[str, int]: # nocoverage
annual_revenue = {}
for plan in CustomerPlan.objects.filter(
status=CustomerPlan.ACTIVE).select_related('customer__realm'):
# TODO: figure out what to do for plans that don't automatically
# renew, but which probably will renew
renewal_cents = renewal_amount(plan, timezone_now()) or 0
if plan.billing_schedule == CustomerPlan.MONTHLY:
renewal_cents *= 12
# TODO: Decimal stuff
annual_revenue[plan.customer.realm.string_id] = int(renewal_cents / 100)
return annual_revenue

View File

@@ -1,47 +0,0 @@
"""\
Run BillingProcessors.
This management command is run via supervisor. Do not run on multiple
machines, as the code has not been made robust to race conditions from doing
so. (Alternatively, you can set `BILLING_PROCESSOR_ENABLED=False` on all but
one machine to make the command have no effect.)
"""
import time
from typing import Any
from django.conf import settings
from django.core.management.base import BaseCommand
from zerver.lib.context_managers import lockfile
from zerver.lib.management import sleep_forever
from corporate.lib.stripe import StripeConnectionError, \
run_billing_processor_one_step
from corporate.models import BillingProcessor
class Command(BaseCommand):
help = """Run BillingProcessors, to sync billing-relevant updates into Stripe.
Run this command under supervisor.
Usage: ./manage.py process_billing_updates
"""
def handle(self, *args: Any, **options: Any) -> None:
if not settings.BILLING_PROCESSOR_ENABLED:
sleep_forever()
with lockfile("/tmp/zulip_billing_processor.lockfile"):
while True:
for processor in BillingProcessor.objects.exclude(
state=BillingProcessor.STALLED):
try:
entry_processed = run_billing_processor_one_step(processor)
except StripeConnectionError:
time.sleep(5*60)
# Less load on the db during times of activity
# and more responsiveness when the load is low
if entry_processed:
time.sleep(10)
else:
time.sleep(2)

View File

@@ -1,55 +0,0 @@
from zerver.lib.management import ZulipBaseCommand
from corporate.models import Plan, Coupon, Customer
from zproject.settings import get_secret
from typing import Any
import stripe
stripe.api_key = get_secret('stripe_secret_key')
class Command(ZulipBaseCommand):
help = """Script to add the appropriate products and plans to Stripe."""
def handle(self, *args: Any, **options: Any) -> None:
Customer.objects.all().delete()
Plan.objects.all().delete()
Coupon.objects.all().delete()
# Zulip Cloud offerings
product = stripe.Product.create(
name="Zulip Cloud Standard",
type='service',
statement_descriptor="Zulip Cloud Standard",
unit_label="user")
plan = stripe.Plan.create(
currency='usd',
interval='month',
product=product.id,
amount=800,
billing_scheme='per_unit',
nickname=Plan.CLOUD_MONTHLY,
usage_type='licensed')
Plan.objects.create(nickname=Plan.CLOUD_MONTHLY, stripe_plan_id=plan.id)
plan = stripe.Plan.create(
currency='usd',
interval='year',
product=product.id,
amount=8000,
billing_scheme='per_unit',
nickname=Plan.CLOUD_ANNUAL,
usage_type='licensed')
Plan.objects.create(nickname=Plan.CLOUD_ANNUAL, stripe_plan_id=plan.id)
coupon = stripe.Coupon.create(
duration='forever',
name='25% discount',
percent_off=25)
Coupon.objects.create(percent_off=25, stripe_coupon_id=coupon.id)
coupon = stripe.Coupon.create(
duration='forever',
name='85% discount',
percent_off=85)
Coupon.objects.create(percent_off=85, stripe_coupon_id=coupon.id)

View File

@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.16 on 2018-12-12 20:19
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('corporate', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='customer',
name='default_discount',
field=models.DecimalField(decimal_places=4, max_digits=7, null=True),
),
]

View File

@@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.16 on 2018-12-22 21:05
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('corporate', '0002_customer_default_discount'),
]
operations = [
migrations.CreateModel(
name='CustomerPlan',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('licenses', models.IntegerField()),
('automanage_licenses', models.BooleanField(default=False)),
('charge_automatically', models.BooleanField(default=False)),
('price_per_license', models.IntegerField(null=True)),
('fixed_price', models.IntegerField(null=True)),
('discount', models.DecimalField(decimal_places=4, max_digits=6, null=True)),
('billing_cycle_anchor', models.DateTimeField()),
('billing_schedule', models.SmallIntegerField()),
('billed_through', models.DateTimeField()),
('next_billing_date', models.DateTimeField(db_index=True)),
('tier', models.SmallIntegerField()),
('status', models.SmallIntegerField(default=1)),
('customer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='corporate.Customer')),
],
),
]

View File

@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.18 on 2019-01-19 05:01
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('corporate', '0003_customerplan'),
]
operations = [
migrations.CreateModel(
name='LicenseLedger',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('is_renewal', models.BooleanField(default=False)),
('event_time', models.DateTimeField()),
('licenses', models.IntegerField()),
('licenses_at_next_renewal', models.IntegerField(null=True)),
('plan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='corporate.CustomerPlan')),
],
),
]

View File

@@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.18 on 2019-01-28 13:04
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('corporate', '0004_licenseledger'),
]
operations = [
migrations.RenameField(
model_name='customerplan',
old_name='next_billing_date',
new_name='next_invoice_date',
),
migrations.RemoveField(
model_name='customerplan',
name='billed_through',
),
migrations.AddField(
model_name='customerplan',
name='invoiced_through',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='corporate.LicenseLedger'),
),
migrations.AddField(
model_name='customerplan',
name='invoicing_status',
field=models.SmallIntegerField(default=1),
),
]

View File

@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.18 on 2019-01-29 01:46
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('corporate', '0005_customerplan_invoicing'),
]
operations = [
migrations.AlterField(
model_name='customer',
name='stripe_customer_id',
field=models.CharField(max_length=255, null=True, unique=True),
),
]

View File

@@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.18 on 2019-01-31 22:16
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('corporate', '0006_nullable_stripe_customer_id'),
]
operations = [
migrations.RemoveField(
model_name='billingprocessor',
name='log_row',
),
migrations.RemoveField(
model_name='billingprocessor',
name='realm',
),
migrations.DeleteModel(
name='Coupon',
),
migrations.DeleteModel(
name='Plan',
),
migrations.RemoveField(
model_name='customer',
name='has_billing_relationship',
),
migrations.RemoveField(
model_name='customerplan',
name='licenses',
),
migrations.DeleteModel(
name='BillingProcessor',
),
]

View File

@@ -1,46 +1,70 @@
import datetime
from decimal import Decimal
from typing import Optional
from django.db import models
from django.db.models import CASCADE
from zerver.models import Realm, RealmAuditLog
from zerver.models import Realm
class Customer(models.Model):
realm = models.OneToOneField(Realm, on_delete=models.CASCADE) # type: Realm
stripe_customer_id = models.CharField(max_length=255, unique=True) # type: str
# Becomes True the first time a payment successfully goes through, and never
# goes back to being False
has_billing_relationship = models.BooleanField(default=False) # type: bool
realm = models.OneToOneField(Realm, on_delete=CASCADE) # type: Realm
stripe_customer_id = models.CharField(max_length=255, null=True, unique=True) # type: str
# A percentage, like 85.
default_discount = models.DecimalField(decimal_places=4, max_digits=7, null=True) # type: Optional[Decimal]
def __str__(self) -> str:
return "<Customer %s %s>" % (self.realm, self.stripe_customer_id)
class Plan(models.Model):
# The two possible values for nickname
CLOUD_MONTHLY = 'monthly'
CLOUD_ANNUAL = 'annual'
nickname = models.CharField(max_length=40, unique=True) # type: str
class CustomerPlan(models.Model):
customer = models.ForeignKey(Customer, on_delete=CASCADE) # type: Customer
automanage_licenses = models.BooleanField(default=False) # type: bool
charge_automatically = models.BooleanField(default=False) # type: bool
stripe_plan_id = models.CharField(max_length=255, unique=True) # type: str
# Both of these are in cents. Exactly one of price_per_license or
# fixed_price should be set. fixed_price is only for manual deals, and
# can't be set via the self-serve billing system.
price_per_license = models.IntegerField(null=True) # type: Optional[int]
fixed_price = models.IntegerField(null=True) # type: Optional[int]
class Coupon(models.Model):
percent_off = models.SmallIntegerField(unique=True) # type: int
stripe_coupon_id = models.CharField(max_length=255, unique=True) # type: str
# Discount that was applied. For display purposes only.
discount = models.DecimalField(decimal_places=4, max_digits=6, null=True) # type: Optional[Decimal]
def __str__(self) -> str:
return '<Coupon: %s %s %s>' % (self.percent_off, self.stripe_coupon_id, self.id)
billing_cycle_anchor = models.DateTimeField() # type: datetime.datetime
ANNUAL = 1
MONTHLY = 2
billing_schedule = models.SmallIntegerField() # type: int
class BillingProcessor(models.Model):
log_row = models.ForeignKey(RealmAuditLog, on_delete=models.CASCADE) # RealmAuditLog
# Exactly one processor, the global processor, has realm=None.
realm = models.OneToOneField(Realm, null=True, on_delete=models.CASCADE) # type: Realm
next_invoice_date = models.DateTimeField(db_index=True) # type: datetime.datetime
invoiced_through = models.ForeignKey(
'LicenseLedger', null=True, on_delete=CASCADE, related_name='+') # type: Optional[LicenseLedger]
DONE = 1
STARTED = 2
invoicing_status = models.SmallIntegerField(default=DONE) # type: int
DONE = 'done'
STARTED = 'started'
SKIPPED = 'skipped' # global processor only
STALLED = 'stalled' # realm processors only
state = models.CharField(max_length=20) # type: str
STANDARD = 1
PLUS = 2 # not available through self-serve signup
ENTERPRISE = 10
tier = models.SmallIntegerField() # type: int
last_modified = models.DateTimeField(auto_now=True) # type: datetime.datetime
ACTIVE = 1
ENDED = 2
NEVER_STARTED = 3
# You can only have 1 active subscription at a time
status = models.SmallIntegerField(default=ACTIVE) # type: int
def __str__(self) -> str:
return '<BillingProcessor: %s %s %s>' % (self.realm, self.log_row, self.id)
# TODO maybe override setattr to ensure billing_cycle_anchor, etc are immutable
def get_active_plan(customer: Customer) -> Optional[CustomerPlan]:
return CustomerPlan.objects.filter(customer=customer, status=CustomerPlan.ACTIVE).first()
class LicenseLedger(models.Model):
plan = models.ForeignKey(CustomerPlan, on_delete=CASCADE) # type: CustomerPlan
# Also True for the initial upgrade.
is_renewal = models.BooleanField(default=False) # type: bool
event_time = models.DateTimeField() # type: datetime.datetime
licenses = models.IntegerField() # type: int
# None means the plan does not automatically renew.
# 0 means the plan has been explicitly downgraded.
# This cannot be None if plan.automanage_licenses.
licenses_at_next_renewal = models.IntegerField(null=True) # type: Optional[int]

View File

@@ -1,411 +0,0 @@
{
"create_customer": {
"account_balance": 0,
"created": 1529990750,
"currency": null,
"default_source": "card_1Ch9gVGh0CmXqmnwv94RombT",
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": {
"coupon": {
"amount_off": null,
"created": 1535002820,
"currency": null,
"duration": "forever",
"duration_in_months": null,
"id": "rncBblSZ",
"livemode": false,
"max_redemptions": null,
"metadata": {},
"name": "85% discount",
"object": "coupon",
"percent_off": 85.0,
"redeem_by": null,
"times_redeemed": 1,
"valid": true
},
"customer": "cus_DT7pd3yW0w8lF1",
"end": null,
"object": "discount",
"start": 1535004909,
"subscription": null
},
"email": "hamlet@zulip.com",
"id": "cus_D7OT2jf5YAtZQL",
"invoice_prefix": "23ABC45",
"livemode": false,
"metadata": {
"realm_id": "1",
"realm_str": "zulip"
},
"object": "customer",
"shipping": null,
"sources": {
"data": [
{
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea",
"address_line1_check": "pass",
"address_line2": null,
"address_state": "FL",
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_D7OT2jf5YAtZQL",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "6dAXT9VZvwro65EK",
"funding": "credit",
"id": "card_1Ch9gVGh0CmXqmnwv94RombT",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/customers/cus_D7OT2jf5YAtZQL/sources"
},
"subscriptions": {}
},
"create_subscription": {
"application_fee_percent": null,
"billing": "charge_automatically",
"billing_cycle_anchor": 1529990751,
"cancel_at_period_end": false,
"canceled_at": null,
"created": 1529990751,
"current_period_end": 1561526751,
"current_period_start": 1529990751,
"customer": "cus_D7OT2jf5YAtZQL",
"days_until_due": null,
"discount": null,
"ended_at": null,
"id": "sub_D7OTT8FZbOPxah",
"items": {
"data": [
{
"created": 1529990751,
"id": "si_D7OTEItF5ZLN2R",
"metadata": {},
"object": "subscription_item",
"plan": {
"active": true,
"aggregate_usage": null,
"amount": 8000,
"billing_scheme": "per_unit",
"created": 1529987890,
"currency": "usd",
"id": "plan_Do3xCvbzO89OsR",
"interval": "year",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": "annual",
"object": "plan",
"product": "prod_D7NhmicJvX2edE",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"quantity": 8,
"subscription": "sub_D7OTT8FZbOPxah"
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/subscription_items?subscription=sub_D7OTT8FZbOPxah"
},
"livemode": false,
"metadata": {},
"object": "subscription",
"plan": {
"active": true,
"aggregate_usage": null,
"amount": 8000,
"billing_scheme": "per_unit",
"created": 1529987890,
"currency": "usd",
"id": "plan_Do3xCvbzO89OsR",
"interval": "year",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": "annual",
"object": "plan",
"product": "prod_D7NhmicJvX2edE",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"quantity": 8,
"start": 1529990751,
"status": "active",
"tax_percent": 0.0,
"trial_end": null,
"trial_start": null
},
"customer_with_subscription": {
"account_balance": 0,
"created": 1529990750,
"currency": "usd",
"default_source": {
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea",
"address_line1_check": "pass",
"address_line2": null,
"address_state": "FL",
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_D7OT2jf5YAtZQL",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "6dAXT9VZvwro65EK",
"funding": "credit",
"id": "card_1Ch9gVGh0CmXqmnwv94RombT",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
},
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_D7OT2jf5YAtZQL",
"invoice_prefix": "23ABC45",
"livemode": false,
"metadata": {
"realm_id": "1",
"realm_str": "zulip"
},
"object": "customer",
"shipping": null,
"sources": {
"data": [
{
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea",
"address_line1_check": "pass",
"address_line2": null,
"address_state": "FL",
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_D7OT2jf5YAtZQL",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "6dAXT9VZvwro65EK",
"funding": "credit",
"id": "card_1Ch9gVGh0CmXqmnwv94RombT",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/customers/cus_D7OT2jf5YAtZQL/sources"
},
"subscriptions": {
"data": [
{
"application_fee_percent": null,
"billing": "charge_automatically",
"billing_cycle_anchor": 1529990751,
"cancel_at_period_end": false,
"canceled_at": null,
"created": 1529990751,
"current_period_end": 1561526751,
"current_period_start": 1529990751,
"customer": "cus_D7OT2jf5YAtZQL",
"days_until_due": null,
"discount": null,
"ended_at": null,
"id": "sub_D7OTT8FZbOPxah",
"items": {
"data": [
{
"created": 1529990751,
"id": "si_D7OTEItF5ZLN2R",
"metadata": {},
"object": "subscription_item",
"plan": {
"active": true,
"aggregate_usage": null,
"amount": 8000,
"billing_scheme": "per_unit",
"created": 1529987890,
"currency": "usd",
"id": "plan_Do3xCvbzO89OsR",
"interval": "year",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": "annual",
"object": "plan",
"product": "prod_D7NhmicJvX2edE",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"quantity": 8,
"subscription": "sub_D7OTT8FZbOPxah"
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/subscription_items?subscription=sub_D7OTT8FZbOPxah"
},
"livemode": false,
"metadata": {},
"object": "subscription",
"plan": {
"active": true,
"aggregate_usage": null,
"amount": 8000,
"billing_scheme": "per_unit",
"created": 1529987890,
"currency": "usd",
"id": "plan_Do3xCvbzO89OsR",
"interval": "year",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": "annual",
"object": "plan",
"product": "prod_D7NhmicJvX2edE",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"quantity": 8,
"start": 1529990751,
"status": "active",
"tax_percent": 0.0,
"trial_end": null,
"trial_start": null
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/customers/cus_D7OT2jf5YAtZQL/subscriptions"
}
},
"upcoming_invoice": {
"amount_due": 64000,
"amount_paid": 0,
"amount_remaining": 64000,
"application_fee": null,
"attempt_count": 0,
"attempted": false,
"billing": "charge_automatically",
"billing_reason": "upcoming",
"charge": null,
"closed": false,
"currency": "usd",
"customer": "cus_D7OT2jf5YAtZQL",
"date": 1561526751,
"description": "",
"discount": null,
"due_date": null,
"ending_balance": null,
"forgiven": false,
"lines": {
"data": [
{
"amount": 64000,
"currency": "usd",
"description": "8 user \u00d7 Zulip Cloud Standard (at $80.00 / year)",
"discountable": true,
"id": "sub_D7OTT8FZbOPxah",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1593149151,
"start": 1561526751
},
"plan": {
"active": true,
"aggregate_usage": null,
"amount": 8000,
"billing_scheme": "per_unit",
"created": 1529987890,
"currency": "usd",
"id": "plan_Do3xCvbzO89OsR",
"interval": "year",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": "annual",
"object": "plan",
"product": "prod_D7NhmicJvX2edE",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"proration": false,
"quantity": 8,
"subscription": null,
"subscription_item": "si_D7OTEItF5ZLN2R",
"type": "subscription"
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/invoices/upcoming/lines?customer=cus_D7OT2jf5YAtZQL"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": 1561530351,
"number": "23ABC45-0002",
"object": "invoice",
"paid": false,
"period_end": 1561526751,
"period_start": 1529990751,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": null,
"subscription": "sub_D7OTT8FZbOPxah",
"subtotal": 64000,
"tax": 0,
"tax_percent": 0.0,
"total": 64000,
"webhooks_delivered_at": null
},
}

View File

@@ -0,0 +1,78 @@
{
"amount": 7200,
"amount_refunded": 0,
"application": null,
"application_fee": null,
"application_fee_amount": null,
"balance_transaction": "txn_NORMALIZED00000000000001",
"captured": true,
"created": 1000000000,
"currency": "usd",
"customer": "cus_NORMALIZED0001",
"description": "Upgrade to Zulip Standard, $12.0 x 6",
"destination": null,
"dispute": null,
"failure_code": null,
"failure_message": null,
"fraud_details": {},
"id": "ch_NORMALIZED00000000000001",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "charge",
"on_behalf_of": null,
"order": null,
"outcome": {
"network_status": "approved_by_network",
"reason": null,
"risk_level": "normal",
"risk_score": 00,
"seller_message": "Payment complete.",
"type": "authorized"
},
"paid": true,
"payment_intent": null,
"receipt_email": "hamlet@zulip.com",
"receipt_number": null,
"receipt_url": "https://pay.stripe.com/receipts/acct_NORMALIZED000001/ch_NORMALIZED00000000000001/rcpt_NORMALIZED000000000000000000001",
"refunded": false,
"refunds": {
"data": [],
"has_more": false,
"object": "list",
"total_count": 0,
"url": "/v1/charges/ch_NORMALIZED00000000000001/refunds"
},
"review": null,
"shipping": null,
"source": {
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_NORMALIZED0001",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_NORMALIZED00000000000001",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
},
"source_transfer": null,
"statement_descriptor": "Zulip Standard",
"status": "succeeded",
"transfer_data": null,
"transfer_group": null
}

View File

@@ -0,0 +1,78 @@
{
"amount": 36000,
"amount_refunded": 0,
"application": null,
"application_fee": null,
"application_fee_amount": null,
"balance_transaction": "txn_NORMALIZED00000000000002",
"captured": true,
"created": 1000000000,
"currency": "usd",
"customer": "cus_NORMALIZED0001",
"description": "Upgrade to Zulip Standard, $60.0 x 6",
"destination": null,
"dispute": null,
"failure_code": null,
"failure_message": null,
"fraud_details": {},
"id": "ch_NORMALIZED00000000000002",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "charge",
"on_behalf_of": null,
"order": null,
"outcome": {
"network_status": "approved_by_network",
"reason": null,
"risk_level": "normal",
"risk_score": 00,
"seller_message": "Payment complete.",
"type": "authorized"
},
"paid": true,
"payment_intent": null,
"receipt_email": "hamlet@zulip.com",
"receipt_number": null,
"receipt_url": "https://pay.stripe.com/receipts/acct_NORMALIZED000001/ch_NORMALIZED00000000000002/rcpt_NORMALIZED000000000000000000002",
"refunded": false,
"refunds": {
"data": [],
"has_more": false,
"object": "list",
"total_count": 0,
"url": "/v1/charges/ch_NORMALIZED00000000000002/refunds"
},
"review": null,
"shipping": null,
"source": {
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_NORMALIZED0001",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_NORMALIZED00000000000002",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
},
"source_transfer": null,
"statement_descriptor": "Zulip Standard",
"status": "succeeded",
"transfer_data": null,
"transfer_group": null
}

View File

@@ -0,0 +1,79 @@
{
"data": [
{
"amount": 7200,
"amount_refunded": 0,
"application": null,
"application_fee": null,
"application_fee_amount": null,
"balance_transaction": "txn_NORMALIZED00000000000001",
"captured": true,
"created": 1000000000,
"currency": "usd",
"customer": "cus_NORMALIZED0001",
"description": "Upgrade to Zulip Standard, $12.0 x 6",
"destination": null,
"dispute": null,
"failure_code": null,
"failure_message": null,
"fraud_details": {},
"id": "ch_NORMALIZED00000000000001",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "charge",
"on_behalf_of": null,
"order": null,
"outcome": {
"network_status": "approved_by_network",
"reason": null,
"risk_level": "normal",
"risk_score": 00,
"seller_message": "Payment complete.",
"type": "authorized"
},
"paid": true,
"payment_intent": null,
"receipt_email": "hamlet@zulip.com",
"receipt_number": null,
"receipt_url": "https://pay.stripe.com/receipts/acct_NORMALIZED000001/ch_NORMALIZED00000000000001/rcpt_NORMALIZED000000000000000000001",
"refunded": false,
"refunds": {},
"review": null,
"shipping": null,
"source": {
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_NORMALIZED0001",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_NORMALIZED00000000000001",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
},
"source_transfer": null,
"statement_descriptor": "Zulip Standard",
"status": "succeeded",
"transfer_data": null,
"transfer_group": null
}
],
"has_more": false,
"object": "list",
"url": "/v1/charges"
}

View File

@@ -0,0 +1,151 @@
{
"data": [
{
"amount": 36000,
"amount_refunded": 0,
"application": null,
"application_fee": null,
"application_fee_amount": null,
"balance_transaction": "txn_NORMALIZED00000000000002",
"captured": true,
"created": 1000000000,
"currency": "usd",
"customer": "cus_NORMALIZED0001",
"description": "Upgrade to Zulip Standard, $60.0 x 6",
"destination": null,
"dispute": null,
"failure_code": null,
"failure_message": null,
"fraud_details": {},
"id": "ch_NORMALIZED00000000000002",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "charge",
"on_behalf_of": null,
"order": null,
"outcome": {
"network_status": "approved_by_network",
"reason": null,
"risk_level": "normal",
"risk_score": 00,
"seller_message": "Payment complete.",
"type": "authorized"
},
"paid": true,
"payment_intent": null,
"receipt_email": "hamlet@zulip.com",
"receipt_number": null,
"receipt_url": "https://pay.stripe.com/receipts/acct_NORMALIZED000001/ch_NORMALIZED00000000000002/rcpt_NORMALIZED000000000000000000002",
"refunded": false,
"refunds": {},
"review": null,
"shipping": null,
"source": {
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_NORMALIZED0001",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_NORMALIZED00000000000002",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
},
"source_transfer": null,
"statement_descriptor": "Zulip Standard",
"status": "succeeded",
"transfer_data": null,
"transfer_group": null
},
{
"amount": 7200,
"amount_refunded": 0,
"application": null,
"application_fee": null,
"application_fee_amount": null,
"balance_transaction": "txn_NORMALIZED00000000000001",
"captured": true,
"created": 1000000000,
"currency": "usd",
"customer": "cus_NORMALIZED0001",
"description": "Upgrade to Zulip Standard, $12.0 x 6",
"destination": null,
"dispute": null,
"failure_code": null,
"failure_message": null,
"fraud_details": {},
"id": "ch_NORMALIZED00000000000001",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "charge",
"on_behalf_of": null,
"order": null,
"outcome": {
"network_status": "approved_by_network",
"reason": null,
"risk_level": "normal",
"risk_score": 00,
"seller_message": "Payment complete.",
"type": "authorized"
},
"paid": true,
"payment_intent": null,
"receipt_email": "hamlet@zulip.com",
"receipt_number": null,
"receipt_url": "https://pay.stripe.com/receipts/acct_NORMALIZED000001/ch_NORMALIZED00000000000001/rcpt_NORMALIZED000000000000000000001",
"refunded": false,
"refunds": {},
"review": null,
"shipping": null,
"source": {
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_NORMALIZED0001",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_NORMALIZED00000000000001",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
},
"source_transfer": null,
"statement_descriptor": "Zulip Standard",
"status": "succeeded",
"transfer_data": null,
"transfer_group": null
}
],
"has_more": false,
"object": "list",
"url": "/v1/charges"
}

View File

@@ -1,14 +1,18 @@
{
"account_balance": 0,
"created": 1539882356,
"created": 1000000000,
"currency": null,
"default_source": "card_1DMewaGh0CmXqmnw659QMDX7",
"default_source": "card_NORMALIZED00000000000001",
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_DoHVyfEZQ0tNj4",
"invoice_prefix": "448916B",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"footer": null
},
"livemode": false,
"metadata": {
"realm_id": "1",
@@ -29,14 +33,14 @@
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_DoHVyfEZQ0tNj4",
"customer": "cus_NORMALIZED0001",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "6dAXT9VZvwro65EK",
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_1DMewaGh0CmXqmnw659QMDX7",
"id": "card_NORMALIZED00000000000001",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
@@ -47,14 +51,14 @@
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/customers/cus_DoHVyfEZQ0tNj4/sources"
"url": "/v1/customers/cus_NORMALIZED0001/sources"
},
"subscriptions": {
"data": [],
"has_more": false,
"object": "list",
"total_count": 0,
"url": "/v1/customers/cus_DoHVyfEZQ0tNj4/subscriptions"
"url": "/v1/customers/cus_NORMALIZED0001/subscriptions"
},
"tax_info": null,
"tax_info_verification": null

View File

@@ -0,0 +1,89 @@
{
"account_balance": 0,
"created": 1000000000,
"currency": "usd",
"default_source": {
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_NORMALIZED0001",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_NORMALIZED00000000000001",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
},
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"footer": null
},
"livemode": false,
"metadata": {
"realm_id": "1",
"realm_str": "zulip"
},
"object": "customer",
"shipping": null,
"sources": {
"data": [
{
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_NORMALIZED0001",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_NORMALIZED00000000000001",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/customers/cus_NORMALIZED0001/sources"
},
"subscriptions": {
"data": [],
"has_more": false,
"object": "list",
"total_count": 0,
"url": "/v1/customers/cus_NORMALIZED0001/subscriptions"
},
"tax_info": null,
"tax_info_verification": null
}

View File

@@ -0,0 +1,65 @@
{
"account_balance": 0,
"created": 1000000000,
"currency": "usd",
"default_source": "card_NORMALIZED00000000000002",
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"footer": null
},
"livemode": false,
"metadata": {
"realm_id": "1",
"realm_str": "zulip"
},
"object": "customer",
"shipping": null,
"sources": {
"data": [
{
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_NORMALIZED0001",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_NORMALIZED00000000000002",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/customers/cus_NORMALIZED0001/sources"
},
"subscriptions": {
"data": [],
"has_more": false,
"object": "list",
"total_count": 0,
"url": "/v1/customers/cus_NORMALIZED0001/subscriptions"
},
"tax_info": null,
"tax_info_verification": null
}

View File

@@ -0,0 +1,92 @@
{
"amount_due": 0,
"amount_paid": 0,
"amount_remaining": 0,
"application_fee": null,
"attempt_count": 0,
"attempted": false,
"auto_advance": true,
"billing": "charge_automatically",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": null,
"ending_balance": null,
"finalized_at": null,
"footer": null,
"hosted_invoice_url": null,
"id": "in_NORMALIZED00000000000001",
"invoice_pdf": null,
"lines": {
"data": [
{
"amount": 7200,
"currency": "usd",
"description": "Zulip Standard",
"discountable": false,
"id": "ii_NORMALIZED00000000000001",
"invoice_item": "ii_NORMALIZED00000000000001",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 6,
"subscription": null,
"type": "invoiceitem"
},
{
"amount": -7200,
"currency": "usd",
"description": "Payment (Card ending in 4242)",
"discountable": false,
"id": "ii_NORMALIZED00000000000002",
"invoice_item": "ii_NORMALIZED00000000000002",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 2,
"url": "/v1/invoices/in_NORMALIZED00000000000001/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": 1000000000,
"number": "NORMALI-0001",
"object": "invoice",
"paid": false,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "draft",
"subscription": null,
"subtotal": 0,
"tax": 0,
"tax_percent": null,
"total": 0,
"webhooks_delivered_at": null
}

View File

@@ -0,0 +1,92 @@
{
"amount_due": 0,
"amount_paid": 0,
"amount_remaining": 0,
"application_fee": null,
"attempt_count": 0,
"attempted": false,
"auto_advance": true,
"billing": "charge_automatically",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": null,
"ending_balance": null,
"finalized_at": null,
"footer": null,
"hosted_invoice_url": null,
"id": "in_NORMALIZED00000000000002",
"invoice_pdf": null,
"lines": {
"data": [
{
"amount": 36000,
"currency": "usd",
"description": "Zulip Standard",
"discountable": false,
"id": "ii_NORMALIZED00000000000003",
"invoice_item": "ii_NORMALIZED00000000000003",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 6,
"subscription": null,
"type": "invoiceitem"
},
{
"amount": -36000,
"currency": "usd",
"description": "Payment (Card ending in 4242)",
"discountable": false,
"id": "ii_NORMALIZED00000000000004",
"invoice_item": "ii_NORMALIZED00000000000004",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 2,
"url": "/v1/invoices/in_NORMALIZED00000000000002/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": 1000000000,
"number": "NORMALI-0002",
"object": "invoice",
"paid": false,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "draft",
"subscription": null,
"subtotal": 0,
"tax": 0,
"tax_percent": null,
"total": 0,
"webhooks_delivered_at": null
}

View File

@@ -0,0 +1,92 @@
{
"amount_due": 0,
"amount_paid": 0,
"amount_remaining": 0,
"application_fee": null,
"attempt_count": 0,
"attempted": true,
"auto_advance": false,
"billing": "charge_automatically",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": 1000000000,
"ending_balance": 0,
"finalized_at": 1000000000,
"footer": null,
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000001",
"id": "in_NORMALIZED00000000000001",
"invoice_pdf": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000001/pdf",
"lines": {
"data": [
{
"amount": 7200,
"currency": "usd",
"description": "Zulip Standard",
"discountable": false,
"id": "ii_NORMALIZED00000000000001",
"invoice_item": "ii_NORMALIZED00000000000001",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 6,
"subscription": null,
"type": "invoiceitem"
},
{
"amount": -7200,
"currency": "usd",
"description": "Payment (Card ending in 4242)",
"discountable": false,
"id": "ii_NORMALIZED00000000000002",
"invoice_item": "ii_NORMALIZED00000000000002",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 2,
"url": "/v1/invoices/in_NORMALIZED00000000000001/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": null,
"number": "NORMALI-0001",
"object": "invoice",
"paid": true,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "paid",
"subscription": null,
"subtotal": 0,
"tax": 0,
"tax_percent": null,
"total": 0,
"webhooks_delivered_at": 1000000000
}

View File

@@ -0,0 +1,92 @@
{
"amount_due": 0,
"amount_paid": 0,
"amount_remaining": 0,
"application_fee": null,
"attempt_count": 0,
"attempted": true,
"auto_advance": false,
"billing": "charge_automatically",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": 1000000000,
"ending_balance": 0,
"finalized_at": 1000000000,
"footer": null,
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000002",
"id": "in_NORMALIZED00000000000002",
"invoice_pdf": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000002/pdf",
"lines": {
"data": [
{
"amount": 36000,
"currency": "usd",
"description": "Zulip Standard",
"discountable": false,
"id": "ii_NORMALIZED00000000000003",
"invoice_item": "ii_NORMALIZED00000000000003",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 6,
"subscription": null,
"type": "invoiceitem"
},
{
"amount": -36000,
"currency": "usd",
"description": "Payment (Card ending in 4242)",
"discountable": false,
"id": "ii_NORMALIZED00000000000004",
"invoice_item": "ii_NORMALIZED00000000000004",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 2,
"url": "/v1/invoices/in_NORMALIZED00000000000002/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": null,
"number": "NORMALI-0002",
"object": "invoice",
"paid": true,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "paid",
"subscription": null,
"subtotal": 0,
"tax": 0,
"tax_percent": null,
"total": 0,
"webhooks_delivered_at": 1000000000
}

View File

@@ -0,0 +1,99 @@
{
"data": [
{
"amount_due": 0,
"amount_paid": 0,
"amount_remaining": 0,
"application_fee": null,
"attempt_count": 0,
"attempted": true,
"auto_advance": false,
"billing": "charge_automatically",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": 1000000000,
"ending_balance": 0,
"finalized_at": 1000000000,
"footer": null,
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000001",
"id": "in_NORMALIZED00000000000001",
"invoice_pdf": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000001/pdf",
"lines": {
"data": [
{
"amount": 7200,
"currency": "usd",
"description": "Zulip Standard",
"discountable": false,
"id": "ii_NORMALIZED00000000000001",
"invoice_item": "ii_NORMALIZED00000000000001",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 6,
"subscription": null,
"type": "invoiceitem"
},
{
"amount": -7200,
"currency": "usd",
"description": "Payment (Card ending in 4242)",
"discountable": false,
"id": "ii_NORMALIZED00000000000002",
"invoice_item": "ii_NORMALIZED00000000000002",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 2,
"url": "/v1/invoices/in_NORMALIZED00000000000001/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": null,
"number": "NORMALI-0001",
"object": "invoice",
"paid": true,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "paid",
"subscription": null,
"subtotal": 0,
"tax": 0,
"tax_percent": null,
"total": 0,
"webhooks_delivered_at": 1000000000
}
],
"has_more": false,
"object": "list",
"url": "/v1/invoices"
}

View File

@@ -0,0 +1,191 @@
{
"data": [
{
"amount_due": 0,
"amount_paid": 0,
"amount_remaining": 0,
"application_fee": null,
"attempt_count": 0,
"attempted": true,
"auto_advance": false,
"billing": "charge_automatically",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": 1000000000,
"ending_balance": 0,
"finalized_at": 1000000000,
"footer": null,
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000002",
"id": "in_NORMALIZED00000000000002",
"invoice_pdf": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000002/pdf",
"lines": {
"data": [
{
"amount": 36000,
"currency": "usd",
"description": "Zulip Standard",
"discountable": false,
"id": "ii_NORMALIZED00000000000003",
"invoice_item": "ii_NORMALIZED00000000000003",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 6,
"subscription": null,
"type": "invoiceitem"
},
{
"amount": -36000,
"currency": "usd",
"description": "Payment (Card ending in 4242)",
"discountable": false,
"id": "ii_NORMALIZED00000000000004",
"invoice_item": "ii_NORMALIZED00000000000004",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 2,
"url": "/v1/invoices/in_NORMALIZED00000000000002/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": null,
"number": "NORMALI-0002",
"object": "invoice",
"paid": true,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "paid",
"subscription": null,
"subtotal": 0,
"tax": 0,
"tax_percent": null,
"total": 0,
"webhooks_delivered_at": 1000000000
},
{
"amount_due": 0,
"amount_paid": 0,
"amount_remaining": 0,
"application_fee": null,
"attempt_count": 0,
"attempted": true,
"auto_advance": false,
"billing": "charge_automatically",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": 1000000000,
"ending_balance": 0,
"finalized_at": 1000000000,
"footer": null,
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000001",
"id": "in_NORMALIZED00000000000001",
"invoice_pdf": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000001/pdf",
"lines": {
"data": [
{
"amount": 7200,
"currency": "usd",
"description": "Zulip Standard",
"discountable": false,
"id": "ii_NORMALIZED00000000000001",
"invoice_item": "ii_NORMALIZED00000000000001",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 6,
"subscription": null,
"type": "invoiceitem"
},
{
"amount": -7200,
"currency": "usd",
"description": "Payment (Card ending in 4242)",
"discountable": false,
"id": "ii_NORMALIZED00000000000002",
"invoice_item": "ii_NORMALIZED00000000000002",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 2,
"url": "/v1/invoices/in_NORMALIZED00000000000001/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": null,
"number": "NORMALI-0001",
"object": "invoice",
"paid": true,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "paid",
"subscription": null,
"subtotal": 0,
"tax": 0,
"tax_percent": null,
"total": 0,
"webhooks_delivered_at": 1000000000
}
],
"has_more": false,
"object": "list",
"url": "/v1/invoices"
}

View File

@@ -0,0 +1,22 @@
{
"amount": -7200,
"currency": "usd",
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"description": "Payment (Card ending in 4242)",
"discountable": false,
"id": "ii_NORMALIZED00000000000002",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "invoiceitem",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"unit_amount": -7200
}

View File

@@ -0,0 +1,22 @@
{
"amount": 7200,
"currency": "usd",
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"description": "Zulip Standard",
"discountable": false,
"id": "ii_NORMALIZED00000000000001",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "invoiceitem",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 6,
"subscription": null,
"unit_amount": 1200
}

View File

@@ -0,0 +1,22 @@
{
"amount": -36000,
"currency": "usd",
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"description": "Payment (Card ending in 4242)",
"discountable": false,
"id": "ii_NORMALIZED00000000000004",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "invoiceitem",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"unit_amount": -36000
}

View File

@@ -0,0 +1,22 @@
{
"amount": 36000,
"currency": "usd",
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"description": "Zulip Standard",
"discountable": false,
"id": "ii_NORMALIZED00000000000003",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "invoiceitem",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 6,
"subscription": null,
"unit_amount": 6000
}

View File

@@ -14,18 +14,18 @@
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "6dAXT9VZvwro65EK",
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_1DMewaGh0CmXqmnw659QMDX7",
"id": "card_NORMALIZED00000000000001",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
},
"client_ip": "107.202.144.213",
"created": 1539882356,
"id": "tok_1DMewaGh0CmXqmnwguSDP9TQ",
"client_ip": "0.0.0.0",
"created": 1000000000,
"id": "tok_NORMALIZED00000000000001",
"livemode": false,
"object": "token",
"type": "card",

View File

@@ -14,18 +14,18 @@
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "6dAXT9VZvwro65EK",
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_1DMRsvGh0CmXqmnwRFN7yRRD",
"id": "card_NORMALIZED00000000000002",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
},
"client_ip": "107.202.144.213",
"created": 1539832157,
"id": "tok_1DMRsvGh0CmXqmnwO80yZKru",
"client_ip": "0.0.0.0",
"created": 1000000000,
"id": "tok_NORMALIZED00000000000002",
"livemode": false,
"object": "token",
"type": "card",

View File

@@ -0,0 +1,78 @@
{
"amount": 48000,
"amount_refunded": 0,
"application": null,
"application_fee": null,
"application_fee_amount": null,
"balance_transaction": "txn_NORMALIZED00000000000001",
"captured": true,
"created": 1000000000,
"currency": "usd",
"customer": "cus_NORMALIZED0001",
"description": "Upgrade to Zulip Standard, $80.0 x 6",
"destination": null,
"dispute": null,
"failure_code": null,
"failure_message": null,
"fraud_details": {},
"id": "ch_NORMALIZED00000000000001",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "charge",
"on_behalf_of": null,
"order": null,
"outcome": {
"network_status": "approved_by_network",
"reason": null,
"risk_level": "normal",
"risk_score": 00,
"seller_message": "Payment complete.",
"type": "authorized"
},
"paid": true,
"payment_intent": null,
"receipt_email": "hamlet@zulip.com",
"receipt_number": null,
"receipt_url": "https://pay.stripe.com/receipts/acct_NORMALIZED000001/ch_NORMALIZED00000000000001/rcpt_NORMALIZED000000000000000000001",
"refunded": false,
"refunds": {
"data": [],
"has_more": false,
"object": "list",
"total_count": 0,
"url": "/v1/charges/ch_NORMALIZED00000000000001/refunds"
},
"review": null,
"shipping": null,
"source": {
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_NORMALIZED0001",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_NORMALIZED00000000000001",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
},
"source_transfer": null,
"statement_descriptor": "Zulip Standard",
"status": "succeeded",
"transfer_data": null,
"transfer_group": null
}

View File

@@ -1,14 +1,18 @@
{
"account_balance": 0,
"created": 1540918391,
"created": 1000000000,
"currency": null,
"default_source": "card_1DR0SsGh0CmXqmnwLRYxxJTu",
"default_source": "card_NORMALIZED00000000000001",
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_Dsm0jbfb5Vxhmv",
"invoice_prefix": "705151A",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"footer": null
},
"livemode": false,
"metadata": {
"realm_id": "1",
@@ -29,14 +33,14 @@
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_Dsm0jbfb5Vxhmv",
"customer": "cus_NORMALIZED0001",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "6dAXT9VZvwro65EK",
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_1DR0SsGh0CmXqmnwLRYxxJTu",
"id": "card_NORMALIZED00000000000001",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
@@ -47,14 +51,14 @@
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/customers/cus_Dsm0jbfb5Vxhmv/sources"
"url": "/v1/customers/cus_NORMALIZED0001/sources"
},
"subscriptions": {
"data": [],
"has_more": false,
"object": "list",
"total_count": 0,
"url": "/v1/customers/cus_Dsm0jbfb5Vxhmv/subscriptions"
"url": "/v1/customers/cus_NORMALIZED0001/subscriptions"
},
"tax_info": null,
"tax_info_verification": null

View File

@@ -0,0 +1,89 @@
{
"account_balance": 0,
"created": 1000000000,
"currency": "usd",
"default_source": {
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_NORMALIZED0001",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_NORMALIZED00000000000001",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
},
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"footer": null
},
"livemode": false,
"metadata": {
"realm_id": "1",
"realm_str": "zulip"
},
"object": "customer",
"shipping": null,
"sources": {
"data": [
{
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_NORMALIZED0001",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_NORMALIZED00000000000001",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/customers/cus_NORMALIZED0001/sources"
},
"subscriptions": {
"data": [],
"has_more": false,
"object": "list",
"total_count": 0,
"url": "/v1/customers/cus_NORMALIZED0001/subscriptions"
},
"tax_info": null,
"tax_info_verification": null
}

View File

@@ -0,0 +1,89 @@
{
"account_balance": 0,
"created": 1000000000,
"currency": "usd",
"default_source": {
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_NORMALIZED0001",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_NORMALIZED00000000000001",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
},
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"footer": null
},
"livemode": false,
"metadata": {
"realm_id": "1",
"realm_str": "zulip"
},
"object": "customer",
"shipping": null,
"sources": {
"data": [
{
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_NORMALIZED0001",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_NORMALIZED00000000000001",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/customers/cus_NORMALIZED0001/sources"
},
"subscriptions": {
"data": [],
"has_more": false,
"object": "list",
"total_count": 0,
"url": "/v1/customers/cus_NORMALIZED0001/subscriptions"
},
"tax_info": null,
"tax_info_verification": null
}

View File

@@ -0,0 +1,92 @@
{
"amount_due": 0,
"amount_paid": 0,
"amount_remaining": 0,
"application_fee": null,
"attempt_count": 0,
"attempted": false,
"auto_advance": true,
"billing": "charge_automatically",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": null,
"ending_balance": null,
"finalized_at": null,
"footer": null,
"hosted_invoice_url": null,
"id": "in_NORMALIZED00000000000001",
"invoice_pdf": null,
"lines": {
"data": [
{
"amount": 48000,
"currency": "usd",
"description": "Zulip Standard",
"discountable": false,
"id": "ii_NORMALIZED00000000000001",
"invoice_item": "ii_NORMALIZED00000000000001",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 6,
"subscription": null,
"type": "invoiceitem"
},
{
"amount": -48000,
"currency": "usd",
"description": "Payment (Card ending in 4242)",
"discountable": false,
"id": "ii_NORMALIZED00000000000002",
"invoice_item": "ii_NORMALIZED00000000000002",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 2,
"url": "/v1/invoices/in_NORMALIZED00000000000001/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": 1000000000,
"number": "NORMALI-0001",
"object": "invoice",
"paid": false,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "draft",
"subscription": null,
"subtotal": 0,
"tax": 0,
"tax_percent": null,
"total": 0,
"webhooks_delivered_at": null
}

View File

@@ -0,0 +1,92 @@
{
"amount_due": 0,
"amount_paid": 0,
"amount_remaining": 0,
"application_fee": null,
"attempt_count": 0,
"attempted": true,
"auto_advance": false,
"billing": "charge_automatically",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": 1000000000,
"ending_balance": 0,
"finalized_at": 1000000000,
"footer": null,
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000001",
"id": "in_NORMALIZED00000000000001",
"invoice_pdf": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000001/pdf",
"lines": {
"data": [
{
"amount": 48000,
"currency": "usd",
"description": "Zulip Standard",
"discountable": false,
"id": "ii_NORMALIZED00000000000001",
"invoice_item": "ii_NORMALIZED00000000000001",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 6,
"subscription": null,
"type": "invoiceitem"
},
{
"amount": -48000,
"currency": "usd",
"description": "Payment (Card ending in 4242)",
"discountable": false,
"id": "ii_NORMALIZED00000000000002",
"invoice_item": "ii_NORMALIZED00000000000002",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 2,
"url": "/v1/invoices/in_NORMALIZED00000000000001/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": null,
"number": "NORMALI-0001",
"object": "invoice",
"paid": true,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "paid",
"subscription": null,
"subtotal": 0,
"tax": 0,
"tax_percent": null,
"total": 0,
"webhooks_delivered_at": 1000000000
}

View File

@@ -0,0 +1,22 @@
{
"amount": -48000,
"currency": "usd",
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"description": "Payment (Card ending in 4242)",
"discountable": false,
"id": "ii_NORMALIZED00000000000002",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "invoiceitem",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"unit_amount": -48000
}

View File

@@ -0,0 +1,22 @@
{
"amount": 48000,
"currency": "usd",
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"description": "Zulip Standard",
"discountable": false,
"id": "ii_NORMALIZED00000000000001",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "invoiceitem",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 6,
"subscription": null,
"unit_amount": 8000
}

View File

@@ -14,18 +14,18 @@
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "6dAXT9VZvwro65EK",
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_1DR0SsGh0CmXqmnwLRYxxJTu",
"id": "card_NORMALIZED00000000000001",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
},
"client_ip": "107.202.144.213",
"created": 1540918394,
"id": "tok_1DR0SsGh0CmXqmnwBW7Lj2FR",
"client_ip": "0.0.0.0",
"created": 1000000000,
"id": "tok_NORMALIZED00000000000001",
"livemode": false,
"object": "token",
"type": "card",

View File

@@ -1,168 +0,0 @@
{
"account_balance": 0,
"created": 1539881153,
"currency": "usd",
"default_source": {
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_DoHBcS2dBGOP9t",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "6dAXT9VZvwro65EK",
"funding": "credit",
"id": "card_1DMedAGh0CmXqmnwDLwrAV1v",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
},
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_DoHBcS2dBGOP9t",
"invoice_prefix": "3B3F5D6",
"livemode": false,
"metadata": {
"realm_id": "1",
"realm_str": "zulip"
},
"object": "customer",
"shipping": null,
"sources": {
"data": [
{
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_DoHBcS2dBGOP9t",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "6dAXT9VZvwro65EK",
"funding": "credit",
"id": "card_1DMedAGh0CmXqmnwDLwrAV1v",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/customers/cus_DoHBcS2dBGOP9t/sources"
},
"subscriptions": {
"data": [
{
"application_fee_percent": null,
"billing": "charge_automatically",
"billing_cycle_anchor": 1539881154,
"cancel_at_period_end": false,
"canceled_at": null,
"created": 1539881154,
"current_period_end": 1571417154,
"current_period_start": 1539881154,
"customer": "cus_DoHBcS2dBGOP9t",
"days_until_due": null,
"discount": null,
"ended_at": null,
"id": "sub_DoHBD49xn11qGo",
"items": {
"data": [
{
"created": 1539881154,
"id": "si_DoHB9flY9e7zrZ",
"metadata": {},
"object": "subscription_item",
"plan": {
"active": true,
"aggregate_usage": null,
"amount": 8000,
"billing_scheme": "per_unit",
"created": 1539831971,
"currency": "usd",
"id": "plan_Do3xCvbzO89OsR",
"interval": "year",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": "annual",
"object": "plan",
"product": "prod_Do3x494SetTDpx",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"quantity": 8,
"subscription": "sub_DoHBD49xn11qGo"
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/subscription_items?subscription=sub_DoHBD49xn11qGo"
},
"livemode": false,
"metadata": {},
"object": "subscription",
"plan": {
"active": true,
"aggregate_usage": null,
"amount": 8000,
"billing_scheme": "per_unit",
"created": 1539831971,
"currency": "usd",
"id": "plan_Do3xCvbzO89OsR",
"interval": "year",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": "annual",
"object": "plan",
"product": "prod_Do3x494SetTDpx",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"quantity": 8,
"start": 1539881154,
"status": "active",
"tax_percent": 0.0,
"trial_end": null,
"trial_start": null
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/customers/cus_DoHBcS2dBGOP9t/subscriptions"
},
"tax_info": null,
"tax_info_verification": null
}

View File

@@ -1,168 +0,0 @@
{
"account_balance": 0,
"created": 1539881153,
"currency": "usd",
"default_source": {
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_DoHBcS2dBGOP9t",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "6dAXT9VZvwro65EK",
"funding": "credit",
"id": "card_1DMedAGh0CmXqmnwDLwrAV1v",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
},
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_DoHBcS2dBGOP9t",
"invoice_prefix": "3B3F5D6",
"livemode": false,
"metadata": {
"realm_id": "1",
"realm_str": "zulip"
},
"object": "customer",
"shipping": null,
"sources": {
"data": [
{
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_DoHBcS2dBGOP9t",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "6dAXT9VZvwro65EK",
"funding": "credit",
"id": "card_1DMedAGh0CmXqmnwDLwrAV1v",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/customers/cus_DoHBcS2dBGOP9t/sources"
},
"subscriptions": {
"data": [
{
"application_fee_percent": null,
"billing": "charge_automatically",
"billing_cycle_anchor": 1539881154,
"cancel_at_period_end": false,
"canceled_at": null,
"created": 1539881154,
"current_period_end": 1571417154,
"current_period_start": 1539881154,
"customer": "cus_DoHBcS2dBGOP9t",
"days_until_due": null,
"discount": null,
"ended_at": null,
"id": "sub_DoHBD49xn11qGo",
"items": {
"data": [
{
"created": 1539881154,
"id": "si_DoHB9flY9e7zrZ",
"metadata": {},
"object": "subscription_item",
"plan": {
"active": true,
"aggregate_usage": null,
"amount": 8000,
"billing_scheme": "per_unit",
"created": 1539831971,
"currency": "usd",
"id": "plan_Do3xCvbzO89OsR",
"interval": "year",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": "annual",
"object": "plan",
"product": "prod_Do3x494SetTDpx",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"quantity": 8,
"subscription": "sub_DoHBD49xn11qGo"
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/subscription_items?subscription=sub_DoHBD49xn11qGo"
},
"livemode": false,
"metadata": {},
"object": "subscription",
"plan": {
"active": true,
"aggregate_usage": null,
"amount": 8000,
"billing_scheme": "per_unit",
"created": 1539831971,
"currency": "usd",
"id": "plan_Do3xCvbzO89OsR",
"interval": "year",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": "annual",
"object": "plan",
"product": "prod_Do3x494SetTDpx",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"quantity": 8,
"start": 1539881154,
"status": "active",
"tax_percent": 0.0,
"trial_end": null,
"trial_start": null
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/customers/cus_DoHBcS2dBGOP9t/subscriptions"
},
"tax_info": null,
"tax_info_verification": null
}

View File

@@ -1,85 +0,0 @@
{
"amount_due": 64000,
"amount_paid": 0,
"amount_remaining": 64000,
"application_fee": null,
"attempt_count": 0,
"attempted": false,
"billing": "charge_automatically",
"billing_reason": "upcoming",
"charge": null,
"closed": false,
"currency": "usd",
"customer": "cus_DoHBcS2dBGOP9t",
"date": 1571417154,
"description": "",
"discount": null,
"due_date": null,
"ending_balance": 0,
"forgiven": false,
"lines": {
"data": [
{
"amount": 64000,
"currency": "usd",
"description": "8 user \u00d7 Zulip Cloud Standard (at $80.00 / year)",
"discountable": true,
"id": "sli_31180ead97e161",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1603039554,
"start": 1571417154
},
"plan": {
"active": true,
"aggregate_usage": null,
"amount": 8000,
"billing_scheme": "per_unit",
"created": 1539831971,
"currency": "usd",
"id": "plan_Do3xCvbzO89OsR",
"interval": "year",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": "annual",
"object": "plan",
"product": "prod_Do3x494SetTDpx",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"proration": false,
"quantity": 8,
"subscription": "sub_DoHBD49xn11qGo",
"subscription_item": "si_DoHB9flY9e7zrZ",
"type": "subscription"
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/invoices/upcoming/lines?customer=cus_DoHBcS2dBGOP9t"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": 1571420754,
"number": "3B3F5D6-0002",
"object": "invoice",
"paid": false,
"period_end": 1571417154,
"period_start": 1539881154,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": null,
"subscription": "sub_DoHBD49xn11qGo",
"subtotal": 64000,
"tax": 0,
"tax_percent": 0.0,
"total": 64000,
"webhooks_delivered_at": null
}

View File

@@ -1,85 +0,0 @@
{
"amount_due": 64000,
"amount_paid": 0,
"amount_remaining": 64000,
"application_fee": null,
"attempt_count": 0,
"attempted": false,
"billing": "charge_automatically",
"billing_reason": "upcoming",
"charge": null,
"closed": false,
"currency": "usd",
"customer": "cus_DoHBcS2dBGOP9t",
"date": 1571417154,
"description": "",
"discount": null,
"due_date": null,
"ending_balance": 0,
"forgiven": false,
"lines": {
"data": [
{
"amount": 64000,
"currency": "usd",
"description": "8 user \u00d7 Zulip Cloud Standard (at $80.00 / year)",
"discountable": true,
"id": "sli_31180ead97e161",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1603039554,
"start": 1571417154
},
"plan": {
"active": true,
"aggregate_usage": null,
"amount": 8000,
"billing_scheme": "per_unit",
"created": 1539831971,
"currency": "usd",
"id": "plan_Do3xCvbzO89OsR",
"interval": "year",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": "annual",
"object": "plan",
"product": "prod_Do3x494SetTDpx",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"proration": false,
"quantity": 8,
"subscription": "sub_DoHBD49xn11qGo",
"subscription_item": "si_DoHB9flY9e7zrZ",
"type": "subscription"
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/invoices/upcoming/lines?customer=cus_DoHBcS2dBGOP9t"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": 1571420754,
"number": "3B3F5D6-0002",
"object": "invoice",
"paid": false,
"period_end": 1571417154,
"period_start": 1539881154,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": null,
"subscription": "sub_DoHBD49xn11qGo",
"subtotal": 64000,
"tax": 0,
"tax_percent": 0.0,
"total": 64000,
"webhooks_delivered_at": null
}

View File

@@ -1,82 +0,0 @@
{
"application_fee_percent": null,
"billing": "charge_automatically",
"billing_cycle_anchor": 1539881154,
"cancel_at_period_end": false,
"canceled_at": null,
"created": 1539881154,
"current_period_end": 1571417154,
"current_period_start": 1539881154,
"customer": "cus_DoHBcS2dBGOP9t",
"days_until_due": null,
"discount": null,
"ended_at": null,
"id": "sub_DoHBD49xn11qGo",
"items": {
"data": [
{
"created": 1539881154,
"id": "si_DoHB9flY9e7zrZ",
"metadata": {},
"object": "subscription_item",
"plan": {
"active": true,
"aggregate_usage": null,
"amount": 8000,
"billing_scheme": "per_unit",
"created": 1539831971,
"currency": "usd",
"id": "plan_Do3xCvbzO89OsR",
"interval": "year",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": "annual",
"object": "plan",
"product": "prod_Do3x494SetTDpx",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"quantity": 8,
"subscription": "sub_DoHBD49xn11qGo"
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/subscription_items?subscription=sub_DoHBD49xn11qGo"
},
"livemode": false,
"metadata": {},
"object": "subscription",
"plan": {
"active": true,
"aggregate_usage": null,
"amount": 8000,
"billing_scheme": "per_unit",
"created": 1539831971,
"currency": "usd",
"id": "plan_Do3xCvbzO89OsR",
"interval": "year",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": "annual",
"object": "plan",
"product": "prod_Do3x494SetTDpx",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"quantity": 8,
"start": 1539881154,
"status": "active",
"tax_percent": 0.0,
"trial_end": null,
"trial_start": null
}

View File

@@ -0,0 +1,39 @@
{
"account_balance": 0,
"created": 1000000000,
"currency": null,
"default_source": null,
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"footer": null
},
"livemode": false,
"metadata": {
"realm_id": "1",
"realm_str": "zulip"
},
"object": "customer",
"shipping": null,
"sources": {
"data": [],
"has_more": false,
"object": "list",
"total_count": 0,
"url": "/v1/customers/cus_NORMALIZED0001/sources"
},
"subscriptions": {
"data": [],
"has_more": false,
"object": "list",
"total_count": 0,
"url": "/v1/customers/cus_NORMALIZED0001/subscriptions"
},
"tax_info": null,
"tax_info_verification": null
}

View File

@@ -0,0 +1,72 @@
{
"amount_due": 984000,
"amount_paid": 0,
"amount_remaining": 984000,
"application_fee": null,
"attempt_count": 0,
"attempted": false,
"auto_advance": true,
"billing": "send_invoice",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": 1000000000,
"ending_balance": null,
"finalized_at": null,
"footer": null,
"hosted_invoice_url": null,
"id": "in_NORMALIZED00000000000001",
"invoice_pdf": null,
"lines": {
"data": [
{
"amount": 984000,
"currency": "usd",
"description": "Zulip Standard",
"discountable": false,
"id": "ii_NORMALIZED00000000000001",
"invoice_item": "ii_NORMALIZED00000000000001",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1357095845,
"start": 1325473445
},
"plan": null,
"proration": false,
"quantity": 123,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/invoices/in_NORMALIZED00000000000001/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": null,
"number": "NORMALI-0001",
"object": "invoice",
"paid": false,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "draft",
"subscription": null,
"subtotal": 984000,
"tax": 0,
"tax_percent": null,
"total": 984000,
"webhooks_delivered_at": null
}

View File

@@ -0,0 +1,72 @@
{
"amount_due": 100,
"amount_paid": 0,
"amount_remaining": 100,
"application_fee": null,
"attempt_count": 0,
"attempted": false,
"auto_advance": true,
"billing": "send_invoice",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": 1000000000,
"ending_balance": null,
"finalized_at": null,
"footer": null,
"hosted_invoice_url": null,
"id": "in_NORMALIZED00000000000002",
"invoice_pdf": null,
"lines": {
"data": [
{
"amount": 100,
"currency": "usd",
"description": "Zulip Standard - renewal",
"discountable": false,
"id": "ii_NORMALIZED00000000000002",
"invoice_item": "ii_NORMALIZED00000000000002",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1388631845,
"start": 1357095845
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/invoices/in_NORMALIZED00000000000002/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": null,
"number": "NORMALI-0002",
"object": "invoice",
"paid": false,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "draft",
"subscription": null,
"subtotal": 100,
"tax": 0,
"tax_percent": null,
"total": 100,
"webhooks_delivered_at": null
}

View File

@@ -0,0 +1,72 @@
{
"amount_due": 984000,
"amount_paid": 0,
"amount_remaining": 984000,
"application_fee": null,
"attempt_count": 0,
"attempted": false,
"auto_advance": true,
"billing": "send_invoice",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": 1000000000,
"ending_balance": 0,
"finalized_at": 1000000000,
"footer": null,
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000001",
"id": "in_NORMALIZED00000000000001",
"invoice_pdf": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000001/pdf",
"lines": {
"data": [
{
"amount": 984000,
"currency": "usd",
"description": "Zulip Standard",
"discountable": false,
"id": "ii_NORMALIZED00000000000001",
"invoice_item": "ii_NORMALIZED00000000000001",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1357095845,
"start": 1325473445
},
"plan": null,
"proration": false,
"quantity": 123,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/invoices/in_NORMALIZED00000000000001/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": null,
"number": "NORMALI-0001",
"object": "invoice",
"paid": false,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "open",
"subscription": null,
"subtotal": 984000,
"tax": 0,
"tax_percent": null,
"total": 984000,
"webhooks_delivered_at": 1000000000
}

View File

@@ -0,0 +1,72 @@
{
"amount_due": 100,
"amount_paid": 0,
"amount_remaining": 100,
"application_fee": null,
"attempt_count": 0,
"attempted": false,
"auto_advance": true,
"billing": "send_invoice",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": 1000000000,
"ending_balance": 0,
"finalized_at": 1000000000,
"footer": null,
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000002",
"id": "in_NORMALIZED00000000000002",
"invoice_pdf": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000002/pdf",
"lines": {
"data": [
{
"amount": 100,
"currency": "usd",
"description": "Zulip Standard - renewal",
"discountable": false,
"id": "ii_NORMALIZED00000000000002",
"invoice_item": "ii_NORMALIZED00000000000002",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1388631845,
"start": 1357095845
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/invoices/in_NORMALIZED00000000000002/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": null,
"number": "NORMALI-0002",
"object": "invoice",
"paid": false,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "open",
"subscription": null,
"subtotal": 100,
"tax": 0,
"tax_percent": null,
"total": 100,
"webhooks_delivered_at": 1000000000
}

View File

@@ -0,0 +1,151 @@
{
"data": [
{
"amount_due": 100,
"amount_paid": 0,
"amount_remaining": 100,
"application_fee": null,
"attempt_count": 0,
"attempted": false,
"auto_advance": true,
"billing": "send_invoice",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": 1000000000,
"ending_balance": 0,
"finalized_at": 1000000000,
"footer": null,
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000002",
"id": "in_NORMALIZED00000000000002",
"invoice_pdf": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000002/pdf",
"lines": {
"data": [
{
"amount": 100,
"currency": "usd",
"description": "Zulip Standard - renewal",
"discountable": false,
"id": "ii_NORMALIZED00000000000002",
"invoice_item": "ii_NORMALIZED00000000000002",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1388631845,
"start": 1357095845
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/invoices/in_NORMALIZED00000000000002/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": null,
"number": "NORMALI-0002",
"object": "invoice",
"paid": false,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "open",
"subscription": null,
"subtotal": 100,
"tax": 0,
"tax_percent": null,
"total": 100,
"webhooks_delivered_at": 1000000000
},
{
"amount_due": 984000,
"amount_paid": 0,
"amount_remaining": 984000,
"application_fee": null,
"attempt_count": 0,
"attempted": false,
"auto_advance": true,
"billing": "send_invoice",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": 1000000000,
"ending_balance": 0,
"finalized_at": 1000000000,
"footer": null,
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000001",
"id": "in_NORMALIZED00000000000001",
"invoice_pdf": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000001/pdf",
"lines": {
"data": [
{
"amount": 984000,
"currency": "usd",
"description": "Zulip Standard",
"discountable": false,
"id": "ii_NORMALIZED00000000000001",
"invoice_item": "ii_NORMALIZED00000000000001",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1357095845,
"start": 1325473445
},
"plan": null,
"proration": false,
"quantity": 123,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/invoices/in_NORMALIZED00000000000001/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": null,
"number": "NORMALI-0001",
"object": "invoice",
"paid": false,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "open",
"subscription": null,
"subtotal": 984000,
"tax": 0,
"tax_percent": null,
"total": 984000,
"webhooks_delivered_at": 1000000000
}
],
"has_more": false,
"object": "list",
"url": "/v1/invoices"
}

View File

@@ -0,0 +1,22 @@
{
"amount": 984000,
"currency": "usd",
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"description": "Zulip Standard",
"discountable": false,
"id": "ii_NORMALIZED00000000000001",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "invoiceitem",
"period": {
"end": 1357095845,
"start": 1325473445
},
"plan": null,
"proration": false,
"quantity": 123,
"subscription": null,
"unit_amount": 8000
}

View File

@@ -0,0 +1,22 @@
{
"amount": 100,
"currency": "usd",
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"description": "Zulip Standard - renewal",
"discountable": false,
"id": "ii_NORMALIZED00000000000002",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "invoiceitem",
"period": {
"end": 1388631845,
"start": 1357095845
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"unit_amount": 100
}

View File

@@ -1,168 +0,0 @@
{
"account_balance": 0,
"created": 1539832157,
"currency": "usd",
"default_source": {
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_Do40UO0WhJ4ZIl",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "6dAXT9VZvwro65EK",
"funding": "credit",
"id": "card_1DMRsvGh0CmXqmnwRFN7yRRD",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
},
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_Do40UO0WhJ4ZIl",
"invoice_prefix": "7783290",
"livemode": false,
"metadata": {
"realm_id": "1",
"realm_str": "zulip"
},
"object": "customer",
"shipping": null,
"sources": {
"data": [
{
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_Do40UO0WhJ4ZIl",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "6dAXT9VZvwro65EK",
"funding": "credit",
"id": "card_1DMRsvGh0CmXqmnwRFN7yRRD",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/customers/cus_Do40UO0WhJ4ZIl/sources"
},
"subscriptions": {
"data": [
{
"application_fee_percent": null,
"billing": "charge_automatically",
"billing_cycle_anchor": 1539832158,
"cancel_at_period_end": false,
"canceled_at": null,
"created": 1539832158,
"current_period_end": 1571368158,
"current_period_start": 1539832158,
"customer": "cus_Do40UO0WhJ4ZIl",
"days_until_due": null,
"discount": null,
"ended_at": null,
"id": "sub_Do40s9CYZB3Ib8",
"items": {
"data": [
{
"created": 1539832159,
"id": "si_Do40INfOLVpONR",
"metadata": {},
"object": "subscription_item",
"plan": {
"active": true,
"aggregate_usage": null,
"amount": 8000,
"billing_scheme": "per_unit",
"created": 1539831971,
"currency": "usd",
"id": "plan_Do3xCvbzO89OsR",
"interval": "year",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": "annual",
"object": "plan",
"product": "prod_Do3x494SetTDpx",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"quantity": 8,
"subscription": "sub_Do40s9CYZB3Ib8"
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/subscription_items?subscription=sub_Do40s9CYZB3Ib8"
},
"livemode": false,
"metadata": {},
"object": "subscription",
"plan": {
"active": true,
"aggregate_usage": null,
"amount": 8000,
"billing_scheme": "per_unit",
"created": 1539831971,
"currency": "usd",
"id": "plan_Do3xCvbzO89OsR",
"interval": "year",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": "annual",
"object": "plan",
"product": "prod_Do3x494SetTDpx",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"quantity": 8,
"start": 1539832158,
"status": "active",
"tax_percent": 0.0,
"trial_end": null,
"trial_start": null
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/customers/cus_Do40UO0WhJ4ZIl/subscriptions"
},
"tax_info": null,
"tax_info_verification": null
}

View File

@@ -1,82 +0,0 @@
{
"application_fee_percent": null,
"billing": "charge_automatically",
"billing_cycle_anchor": 1539832158,
"cancel_at_period_end": false,
"canceled_at": null,
"created": 1539832158,
"current_period_end": 1571368158,
"current_period_start": 1539832158,
"customer": "cus_Do40UO0WhJ4ZIl",
"days_until_due": null,
"discount": null,
"ended_at": null,
"id": "sub_Do40s9CYZB3Ib8",
"items": {
"data": [
{
"created": 1539832159,
"id": "si_Do40INfOLVpONR",
"metadata": {},
"object": "subscription_item",
"plan": {
"active": true,
"aggregate_usage": null,
"amount": 8000,
"billing_scheme": "per_unit",
"created": 1539831971,
"currency": "usd",
"id": "plan_Do3xCvbzO89OsR",
"interval": "year",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": "annual",
"object": "plan",
"product": "prod_Do3x494SetTDpx",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"quantity": 8,
"subscription": "sub_Do40s9CYZB3Ib8"
}
],
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/subscription_items?subscription=sub_Do40s9CYZB3Ib8"
},
"livemode": false,
"metadata": {},
"object": "subscription",
"plan": {
"active": true,
"aggregate_usage": null,
"amount": 8000,
"billing_scheme": "per_unit",
"created": 1539831971,
"currency": "usd",
"id": "plan_Do3xCvbzO89OsR",
"interval": "year",
"interval_count": 1,
"livemode": false,
"metadata": {},
"nickname": "annual",
"object": "plan",
"product": "prod_Do3x494SetTDpx",
"tiers": null,
"tiers_mode": null,
"transform_usage": null,
"trial_period_days": null,
"usage_type": "licensed"
},
"quantity": 8,
"start": 1539832158,
"status": "active",
"tax_percent": 0.0,
"trial_end": null,
"trial_start": null
}

View File

@@ -0,0 +1,78 @@
{
"amount": 48000,
"amount_refunded": 0,
"application": null,
"application_fee": null,
"application_fee_amount": null,
"balance_transaction": "txn_NORMALIZED00000000000001",
"captured": true,
"created": 1000000000,
"currency": "usd",
"customer": "cus_NORMALIZED0001",
"description": "Upgrade to Zulip Standard, $80.0 x 6",
"destination": null,
"dispute": null,
"failure_code": null,
"failure_message": null,
"fraud_details": {},
"id": "ch_NORMALIZED00000000000001",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "charge",
"on_behalf_of": null,
"order": null,
"outcome": {
"network_status": "approved_by_network",
"reason": null,
"risk_level": "normal",
"risk_score": 00,
"seller_message": "Payment complete.",
"type": "authorized"
},
"paid": true,
"payment_intent": null,
"receipt_email": "hamlet@zulip.com",
"receipt_number": null,
"receipt_url": "https://pay.stripe.com/receipts/acct_NORMALIZED000001/ch_NORMALIZED00000000000001/rcpt_NORMALIZED000000000000000000001",
"refunded": false,
"refunds": {
"data": [],
"has_more": false,
"object": "list",
"total_count": 0,
"url": "/v1/charges/ch_NORMALIZED00000000000001/refunds"
},
"review": null,
"shipping": null,
"source": {
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_NORMALIZED0001",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_NORMALIZED00000000000001",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
},
"source_transfer": null,
"statement_descriptor": "Zulip Standard",
"status": "succeeded",
"transfer_data": null,
"transfer_group": null
}

View File

@@ -1,14 +1,18 @@
{
"account_balance": 0,
"created": 1539881153,
"created": 1000000000,
"currency": null,
"default_source": "card_1DMedAGh0CmXqmnwDLwrAV1v",
"default_source": "card_NORMALIZED00000000000001",
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_DoHBcS2dBGOP9t",
"invoice_prefix": "3B3F5D6",
"id": "cus_NORMALIZED0001",
"invoice_prefix": "NORMA01",
"invoice_settings": {
"custom_fields": null,
"footer": null
},
"livemode": false,
"metadata": {
"realm_id": "1",
@@ -29,14 +33,14 @@
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_DoHBcS2dBGOP9t",
"customer": "cus_NORMALIZED0001",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "6dAXT9VZvwro65EK",
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_1DMedAGh0CmXqmnwDLwrAV1v",
"id": "card_NORMALIZED00000000000001",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
@@ -47,14 +51,14 @@
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/customers/cus_DoHBcS2dBGOP9t/sources"
"url": "/v1/customers/cus_NORMALIZED0001/sources"
},
"subscriptions": {
"data": [],
"has_more": false,
"object": "list",
"total_count": 0,
"url": "/v1/customers/cus_DoHBcS2dBGOP9t/subscriptions"
"url": "/v1/customers/cus_NORMALIZED0001/subscriptions"
},
"tax_info": null,
"tax_info_verification": null

View File

@@ -0,0 +1,92 @@
{
"amount_due": 0,
"amount_paid": 0,
"amount_remaining": 0,
"application_fee": null,
"attempt_count": 0,
"attempted": false,
"auto_advance": true,
"billing": "charge_automatically",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": null,
"ending_balance": null,
"finalized_at": null,
"footer": null,
"hosted_invoice_url": null,
"id": "in_NORMALIZED00000000000001",
"invoice_pdf": null,
"lines": {
"data": [
{
"amount": 48000,
"currency": "usd",
"description": "Zulip Standard",
"discountable": false,
"id": "ii_NORMALIZED00000000000001",
"invoice_item": "ii_NORMALIZED00000000000001",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1357095845,
"start": 1325473445
},
"plan": null,
"proration": false,
"quantity": 6,
"subscription": null,
"type": "invoiceitem"
},
{
"amount": -48000,
"currency": "usd",
"description": "Payment (Card ending in 4242)",
"discountable": false,
"id": "ii_NORMALIZED00000000000002",
"invoice_item": "ii_NORMALIZED00000000000002",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 2,
"url": "/v1/invoices/in_NORMALIZED00000000000001/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": 1000000000,
"number": "NORMALI-0001",
"object": "invoice",
"paid": false,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "draft",
"subscription": null,
"subtotal": 0,
"tax": 0,
"tax_percent": null,
"total": 0,
"webhooks_delivered_at": null
}

View File

@@ -0,0 +1,112 @@
{
"amount_due": 80697,
"amount_paid": 0,
"amount_remaining": 80697,
"application_fee": null,
"attempt_count": 0,
"attempted": false,
"auto_advance": true,
"billing": "charge_automatically",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": null,
"ending_balance": null,
"finalized_at": null,
"footer": null,
"hosted_invoice_url": null,
"id": "in_NORMALIZED00000000000002",
"invoice_pdf": null,
"lines": {
"data": [
{
"amount": 7255,
"currency": "usd",
"description": "Additional license (Feb 5, 2013 - Jan 2, 2014)",
"discountable": false,
"id": "ii_NORMALIZED00000000000003",
"invoice_item": "ii_NORMALIZED00000000000003",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1388631845,
"start": 1360033445
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"type": "invoiceitem"
},
{
"amount": 56000,
"currency": "usd",
"description": "Zulip Standard - renewal",
"discountable": false,
"id": "ii_NORMALIZED00000000000004",
"invoice_item": "ii_NORMALIZED00000000000004",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1388631845,
"start": 1357095845
},
"plan": null,
"proration": false,
"quantity": 7,
"subscription": null,
"type": "invoiceitem"
},
{
"amount": 17442,
"currency": "usd",
"description": "Additional license (Apr 11, 2012 - Jan 2, 2013)",
"discountable": false,
"id": "ii_NORMALIZED00000000000005",
"invoice_item": "ii_NORMALIZED00000000000005",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1357095845,
"start": 1334113445
},
"plan": null,
"proration": false,
"quantity": 3,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 3,
"url": "/v1/invoices/in_NORMALIZED00000000000002/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": 1000000000,
"number": "NORMALI-0002",
"object": "invoice",
"paid": false,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "draft",
"subscription": null,
"subtotal": 80697,
"tax": 0,
"tax_percent": null,
"total": 80697,
"webhooks_delivered_at": null
}

View File

@@ -0,0 +1,92 @@
{
"amount_due": 0,
"amount_paid": 0,
"amount_remaining": 0,
"application_fee": null,
"attempt_count": 0,
"attempted": true,
"auto_advance": false,
"billing": "charge_automatically",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": 1000000000,
"ending_balance": 0,
"finalized_at": 1000000000,
"footer": null,
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000001",
"id": "in_NORMALIZED00000000000001",
"invoice_pdf": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000001/pdf",
"lines": {
"data": [
{
"amount": 48000,
"currency": "usd",
"description": "Zulip Standard",
"discountable": false,
"id": "ii_NORMALIZED00000000000001",
"invoice_item": "ii_NORMALIZED00000000000001",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1357095845,
"start": 1325473445
},
"plan": null,
"proration": false,
"quantity": 6,
"subscription": null,
"type": "invoiceitem"
},
{
"amount": -48000,
"currency": "usd",
"description": "Payment (Card ending in 4242)",
"discountable": false,
"id": "ii_NORMALIZED00000000000002",
"invoice_item": "ii_NORMALIZED00000000000002",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 2,
"url": "/v1/invoices/in_NORMALIZED00000000000001/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": null,
"number": "NORMALI-0001",
"object": "invoice",
"paid": true,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "paid",
"subscription": null,
"subtotal": 0,
"tax": 0,
"tax_percent": null,
"total": 0,
"webhooks_delivered_at": 1000000000
}

View File

@@ -0,0 +1,112 @@
{
"amount_due": 80697,
"amount_paid": 0,
"amount_remaining": 80697,
"application_fee": null,
"attempt_count": 0,
"attempted": false,
"auto_advance": true,
"billing": "charge_automatically",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": 1000000000,
"ending_balance": 0,
"finalized_at": 1000000000,
"footer": null,
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000002",
"id": "in_NORMALIZED00000000000002",
"invoice_pdf": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000002/pdf",
"lines": {
"data": [
{
"amount": 7255,
"currency": "usd",
"description": "Additional license (Feb 5, 2013 - Jan 2, 2014)",
"discountable": false,
"id": "ii_NORMALIZED00000000000003",
"invoice_item": "ii_NORMALIZED00000000000003",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1388631845,
"start": 1360033445
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"type": "invoiceitem"
},
{
"amount": 56000,
"currency": "usd",
"description": "Zulip Standard - renewal",
"discountable": false,
"id": "ii_NORMALIZED00000000000004",
"invoice_item": "ii_NORMALIZED00000000000004",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1388631845,
"start": 1357095845
},
"plan": null,
"proration": false,
"quantity": 7,
"subscription": null,
"type": "invoiceitem"
},
{
"amount": 17442,
"currency": "usd",
"description": "Additional license (Apr 11, 2012 - Jan 2, 2013)",
"discountable": false,
"id": "ii_NORMALIZED00000000000005",
"invoice_item": "ii_NORMALIZED00000000000005",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1357095845,
"start": 1334113445
},
"plan": null,
"proration": false,
"quantity": 3,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 3,
"url": "/v1/invoices/in_NORMALIZED00000000000002/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": 1000000000,
"number": "NORMALI-0002",
"object": "invoice",
"paid": false,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "open",
"subscription": null,
"subtotal": 80697,
"tax": 0,
"tax_percent": null,
"total": 80697,
"webhooks_delivered_at": 1000000000
}

View File

@@ -0,0 +1,211 @@
{
"data": [
{
"amount_due": 80697,
"amount_paid": 0,
"amount_remaining": 80697,
"application_fee": null,
"attempt_count": 0,
"attempted": false,
"auto_advance": true,
"billing": "charge_automatically",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": 1000000000,
"ending_balance": 0,
"finalized_at": 1000000000,
"footer": null,
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000002",
"id": "in_NORMALIZED00000000000002",
"invoice_pdf": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000002/pdf",
"lines": {
"data": [
{
"amount": 7255,
"currency": "usd",
"description": "Additional license (Feb 5, 2013 - Jan 2, 2014)",
"discountable": false,
"id": "ii_NORMALIZED00000000000003",
"invoice_item": "ii_NORMALIZED00000000000003",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1388631845,
"start": 1360033445
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"type": "invoiceitem"
},
{
"amount": 56000,
"currency": "usd",
"description": "Zulip Standard - renewal",
"discountable": false,
"id": "ii_NORMALIZED00000000000004",
"invoice_item": "ii_NORMALIZED00000000000004",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1388631845,
"start": 1357095845
},
"plan": null,
"proration": false,
"quantity": 7,
"subscription": null,
"type": "invoiceitem"
},
{
"amount": 17442,
"currency": "usd",
"description": "Additional license (Apr 11, 2012 - Jan 2, 2013)",
"discountable": false,
"id": "ii_NORMALIZED00000000000005",
"invoice_item": "ii_NORMALIZED00000000000005",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1357095845,
"start": 1334113445
},
"plan": null,
"proration": false,
"quantity": 3,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 3,
"url": "/v1/invoices/in_NORMALIZED00000000000002/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": 1000000000,
"number": "NORMALI-0002",
"object": "invoice",
"paid": false,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "open",
"subscription": null,
"subtotal": 80697,
"tax": 0,
"tax_percent": null,
"total": 80697,
"webhooks_delivered_at": 1000000000
},
{
"amount_due": 0,
"amount_paid": 0,
"amount_remaining": 0,
"application_fee": null,
"attempt_count": 0,
"attempted": true,
"auto_advance": false,
"billing": "charge_automatically",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"default_source": null,
"description": "",
"discount": null,
"due_date": 1000000000,
"ending_balance": 0,
"finalized_at": 1000000000,
"footer": null,
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000001",
"id": "in_NORMALIZED00000000000001",
"invoice_pdf": "https://pay.stripe.com/invoice/invst_NORMALIZED0000000000000001/pdf",
"lines": {
"data": [
{
"amount": 48000,
"currency": "usd",
"description": "Zulip Standard",
"discountable": false,
"id": "ii_NORMALIZED00000000000001",
"invoice_item": "ii_NORMALIZED00000000000001",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1357095845,
"start": 1325473445
},
"plan": null,
"proration": false,
"quantity": 6,
"subscription": null,
"type": "invoiceitem"
},
{
"amount": -48000,
"currency": "usd",
"description": "Payment (Card ending in 4242)",
"discountable": false,
"id": "ii_NORMALIZED00000000000002",
"invoice_item": "ii_NORMALIZED00000000000002",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 2,
"url": "/v1/invoices/in_NORMALIZED00000000000001/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": null,
"number": "NORMALI-0001",
"object": "invoice",
"paid": true,
"period_end": 1000000000,
"period_start": 1000000000,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "paid",
"subscription": null,
"subtotal": 0,
"tax": 0,
"tax_percent": null,
"total": 0,
"webhooks_delivered_at": 1000000000
}
],
"has_more": false,
"object": "list",
"url": "/v1/invoices"
}

View File

@@ -0,0 +1,22 @@
{
"amount": -48000,
"currency": "usd",
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"description": "Payment (Card ending in 4242)",
"discountable": false,
"id": "ii_NORMALIZED00000000000002",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "invoiceitem",
"period": {
"end": 1000000000,
"start": 1000000000
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"unit_amount": -48000
}

View File

@@ -0,0 +1,22 @@
{
"amount": 48000,
"currency": "usd",
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"description": "Zulip Standard",
"discountable": false,
"id": "ii_NORMALIZED00000000000001",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "invoiceitem",
"period": {
"end": 1357095845,
"start": 1325473445
},
"plan": null,
"proration": false,
"quantity": 6,
"subscription": null,
"unit_amount": 8000
}

View File

@@ -0,0 +1,22 @@
{
"amount": 17442,
"currency": "usd",
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"description": "Additional license (Apr 11, 2012 - Jan 2, 2013)",
"discountable": false,
"id": "ii_NORMALIZED00000000000005",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "invoiceitem",
"period": {
"end": 1357095845,
"start": 1334113445
},
"plan": null,
"proration": false,
"quantity": 3,
"subscription": null,
"unit_amount": 5814
}

View File

@@ -0,0 +1,22 @@
{
"amount": 56000,
"currency": "usd",
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"description": "Zulip Standard - renewal",
"discountable": false,
"id": "ii_NORMALIZED00000000000004",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "invoiceitem",
"period": {
"end": 1388631845,
"start": 1357095845
},
"plan": null,
"proration": false,
"quantity": 7,
"subscription": null,
"unit_amount": 8000
}

View File

@@ -0,0 +1,22 @@
{
"amount": 7255,
"currency": "usd",
"customer": "cus_NORMALIZED0001",
"date": 1000000000,
"description": "Additional license (Feb 5, 2013 - Jan 2, 2014)",
"discountable": false,
"id": "ii_NORMALIZED00000000000003",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "invoiceitem",
"period": {
"end": 1388631845,
"start": 1360033445
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"unit_amount": 7255
}

View File

@@ -0,0 +1,33 @@
{
"card": {
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "unchecked",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "unchecked",
"brand": "Visa",
"country": "US",
"cvc_check": "unchecked",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "NORMALIZED000001",
"funding": "credit",
"id": "card_NORMALIZED00000000000001",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
},
"client_ip": "0.0.0.0",
"created": 1000000000,
"id": "tok_NORMALIZED00000000000001",
"livemode": false,
"object": "token",
"type": "card",
"used": false
}

View File

@@ -0,0 +1,78 @@
{
"amount": 64000,
"amount_refunded": 0,
"application": null,
"application_fee": null,
"application_fee_amount": null,
"balance_transaction": "txn_1DxdeSGh0CmXqmnw9I7ziL6D",
"captured": true,
"created": 1548695524,
"currency": "usd",
"customer": "cus_EQUd48LphR5ahk",
"description": "Upgrade to Zulip Standard, $80.0 x 8",
"destination": null,
"dispute": null,
"failure_code": null,
"failure_message": null,
"fraud_details": {},
"id": "ch_1DxdeSGh0CmXqmnwsw80Rn8n",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "charge",
"on_behalf_of": null,
"order": null,
"outcome": {
"network_status": "approved_by_network",
"reason": null,
"risk_level": "normal",
"risk_score": 46,
"seller_message": "Payment complete.",
"type": "authorized"
},
"paid": true,
"payment_intent": null,
"receipt_email": "hamlet@zulip.com",
"receipt_number": null,
"receipt_url": "https://pay.stripe.com/receipts/acct_1BWYgHGh0CmXqmnw/ch_1DxdeSGh0CmXqmnwsw80Rn8n/rcpt_EQUda9O5I5cYpJL0yxiRbxnPbWZ415D",
"refunded": false,
"refunds": {
"data": [],
"has_more": false,
"object": "list",
"total_count": 0,
"url": "/v1/charges/ch_1DxdeSGh0CmXqmnwsw80Rn8n/refunds"
},
"review": null,
"shipping": null,
"source": {
"address_city": "Pacific",
"address_country": "United States",
"address_line1": "Under the sea,",
"address_line1_check": "pass",
"address_line2": null,
"address_state": null,
"address_zip": "33333",
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_EQUd48LphR5ahk",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "6dAXT9VZvwro65EK",
"funding": "credit",
"id": "card_1DxdeRGh0CmXqmnwu3BibWtM",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
"object": "card",
"tokenization_method": null
},
"source_transfer": null,
"statement_descriptor": "Zulip Standard",
"status": "succeeded",
"transfer_data": null,
"transfer_group": null
}

View File

@@ -1,14 +1,18 @@
{
"account_balance": 0,
"created": 1539832157,
"created": 1548695523,
"currency": null,
"default_source": "card_1DMRsvGh0CmXqmnwRFN7yRRD",
"default_source": "card_1DxdeRGh0CmXqmnwu3BibWtM",
"delinquent": false,
"description": "zulip (Zulip Dev)",
"discount": null,
"email": "hamlet@zulip.com",
"id": "cus_Do40UO0WhJ4ZIl",
"invoice_prefix": "7783290",
"id": "cus_EQUd48LphR5ahk",
"invoice_prefix": "9F53235",
"invoice_settings": {
"custom_fields": null,
"footer": null
},
"livemode": false,
"metadata": {
"realm_id": "1",
@@ -29,14 +33,14 @@
"address_zip_check": "pass",
"brand": "Visa",
"country": "US",
"customer": "cus_Do40UO0WhJ4ZIl",
"customer": "cus_EQUd48LphR5ahk",
"cvc_check": "pass",
"dynamic_last4": null,
"exp_month": 3,
"exp_year": 2033,
"fingerprint": "6dAXT9VZvwro65EK",
"funding": "credit",
"id": "card_1DMRsvGh0CmXqmnwRFN7yRRD",
"id": "card_1DxdeRGh0CmXqmnwu3BibWtM",
"last4": "4242",
"metadata": {},
"name": "Ada Starr",
@@ -47,14 +51,14 @@
"has_more": false,
"object": "list",
"total_count": 1,
"url": "/v1/customers/cus_Do40UO0WhJ4ZIl/sources"
"url": "/v1/customers/cus_EQUd48LphR5ahk/sources"
},
"subscriptions": {
"data": [],
"has_more": false,
"object": "list",
"total_count": 0,
"url": "/v1/customers/cus_Do40UO0WhJ4ZIl/subscriptions"
"url": "/v1/customers/cus_EQUd48LphR5ahk/subscriptions"
},
"tax_info": null,
"tax_info_verification": null

View File

@@ -0,0 +1,92 @@
{
"amount_due": 0,
"amount_paid": 0,
"amount_remaining": 0,
"application_fee": null,
"attempt_count": 0,
"attempted": false,
"auto_advance": true,
"billing": "charge_automatically",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_EQUd48LphR5ahk",
"date": 1548695526,
"default_source": null,
"description": "",
"discount": null,
"due_date": null,
"ending_balance": null,
"finalized_at": null,
"footer": null,
"hosted_invoice_url": null,
"id": "in_1DxdeUGh0CmXqmnwoowtAcQW",
"invoice_pdf": null,
"lines": {
"data": [
{
"amount": 64000,
"currency": "usd",
"description": "Zulip Standard",
"discountable": false,
"id": "ii_1DxdeTGh0CmXqmnw7MfZoBVx",
"invoice_item": "ii_1DxdeTGh0CmXqmnw7MfZoBVx",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1357095845,
"start": 1325473445
},
"plan": null,
"proration": false,
"quantity": 8,
"subscription": null,
"type": "invoiceitem"
},
{
"amount": -64000,
"currency": "usd",
"description": "Payment (Card ending in 4242)",
"discountable": false,
"id": "ii_1DxdeTGh0CmXqmnwDYYlalDE",
"invoice_item": "ii_1DxdeTGh0CmXqmnwDYYlalDE",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1548695525,
"start": 1548695525
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 2,
"url": "/v1/invoices/in_1DxdeUGh0CmXqmnwoowtAcQW/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": 1548699126,
"number": "9F53235-0001",
"object": "invoice",
"paid": false,
"period_end": 1548695526,
"period_start": 1548695526,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "draft",
"subscription": null,
"subtotal": 0,
"tax": 0,
"tax_percent": null,
"total": 0,
"webhooks_delivered_at": null
}

View File

@@ -0,0 +1,92 @@
{
"amount_due": 0,
"amount_paid": 0,
"amount_remaining": 0,
"application_fee": null,
"attempt_count": 0,
"attempted": true,
"auto_advance": false,
"billing": "charge_automatically",
"billing_reason": "manual",
"charge": null,
"currency": "usd",
"custom_fields": null,
"customer": "cus_EQUd48LphR5ahk",
"date": 1548695526,
"default_source": null,
"description": "",
"discount": null,
"due_date": 1551287527,
"ending_balance": 0,
"finalized_at": 1548695527,
"footer": null,
"hosted_invoice_url": "https://pay.stripe.com/invoice/invst_8N3Zw202aBfkZSHzyjUVcv9vrE",
"id": "in_1DxdeUGh0CmXqmnwoowtAcQW",
"invoice_pdf": "https://pay.stripe.com/invoice/invst_8N3Zw202aBfkZSHzyjUVcv9vrE/pdf",
"lines": {
"data": [
{
"amount": 64000,
"currency": "usd",
"description": "Zulip Standard",
"discountable": false,
"id": "ii_1DxdeTGh0CmXqmnw7MfZoBVx",
"invoice_item": "ii_1DxdeTGh0CmXqmnw7MfZoBVx",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1357095845,
"start": 1325473445
},
"plan": null,
"proration": false,
"quantity": 8,
"subscription": null,
"type": "invoiceitem"
},
{
"amount": -64000,
"currency": "usd",
"description": "Payment (Card ending in 4242)",
"discountable": false,
"id": "ii_1DxdeTGh0CmXqmnwDYYlalDE",
"invoice_item": "ii_1DxdeTGh0CmXqmnwDYYlalDE",
"livemode": false,
"metadata": {},
"object": "line_item",
"period": {
"end": 1548695525,
"start": 1548695525
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"type": "invoiceitem"
}
],
"has_more": false,
"object": "list",
"total_count": 2,
"url": "/v1/invoices/in_1DxdeUGh0CmXqmnwoowtAcQW/lines"
},
"livemode": false,
"metadata": {},
"next_payment_attempt": null,
"number": "9F53235-0001",
"object": "invoice",
"paid": true,
"period_end": 1548695526,
"period_start": 1548695526,
"receipt_number": null,
"starting_balance": 0,
"statement_descriptor": "Zulip Standard",
"status": "paid",
"subscription": null,
"subtotal": 0,
"tax": 0,
"tax_percent": null,
"total": 0,
"webhooks_delivered_at": 1548695526
}

View File

@@ -0,0 +1,22 @@
{
"amount": -64000,
"currency": "usd",
"customer": "cus_EQUd48LphR5ahk",
"date": 1548695525,
"description": "Payment (Card ending in 4242)",
"discountable": false,
"id": "ii_1DxdeTGh0CmXqmnwDYYlalDE",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "invoiceitem",
"period": {
"end": 1548695525,
"start": 1548695525
},
"plan": null,
"proration": false,
"quantity": 1,
"subscription": null,
"unit_amount": -64000
}

View File

@@ -0,0 +1,22 @@
{
"amount": 64000,
"currency": "usd",
"customer": "cus_EQUd48LphR5ahk",
"date": 1548695525,
"description": "Zulip Standard",
"discountable": false,
"id": "ii_1DxdeTGh0CmXqmnw7MfZoBVx",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "invoiceitem",
"period": {
"end": 1357095845,
"start": 1325473445
},
"plan": null,
"proration": false,
"quantity": 8,
"subscription": null,
"unit_amount": 8000
}

View File

@@ -0,0 +1,22 @@
{
"amount": 17442,
"currency": "usd",
"customer": "cus_EQUd48LphR5ahk",
"date": 1548695527,
"description": "Additional license (Apr 11, 2012 - Jan 2, 2013)",
"discountable": false,
"id": "ii_1DxdeVGh0CmXqmnwf6cLlEA7",
"invoice": null,
"livemode": false,
"metadata": {},
"object": "invoiceitem",
"period": {
"end": 1357095845,
"start": 1334113445
},
"plan": null,
"proration": false,
"quantity": 3,
"subscription": null,
"unit_amount": 5814
}

Some files were not shown because too many files have changed in this diff Show More