Email Invite URLs not Generating


#1

Hi all! I’m having an issue where I’ve set up the mail server using SES and running the test
PYTHONPATH=. bin/run ./manage.py send_test_mail
works just fine, I get the email on REDASH_MAIL_DEFAULT_SENDER from REDASH_MAIL_DEFAULT_SENDER.

Now when setting up new users in the UI they seem to not get an invite email. I do get the message:
The user has been created and should receive an invite email soon. You can use the following link to invite them yourself: https://mydomain.co/invite/blabla

Tried inviting while logged in as the REDASH_MAIL_DEFAULT_SENDER (me@mydomain.co) - same thing.

Remoting into the server image and running
PYTHONPATH=. bin/run ./manage.py users invite newuser@mydomain.co newuser me@mydomain.co

Got me this:

sed: can’t read .env: No such file or directory
[2017-08-22 11:23:13,037][PID:49][INFO][root] Generating grammar tables from /usr/lib/python2.7/lib2to3/Grammar.txt
[2017-08-22 11:23:13,060][PID:49][INFO][root] Generating grammar tables from /usr/lib/python2.7/lib2to3/PatternGrammar.txt
Traceback (most recent call last):
File “/app/manage.py”, line 9, in
manager()
File “/usr/local/lib/python2.7/dist-packages/click/core.py”, line 716, in call
return self.main(*args, **kwargs)
File “/usr/local/lib/python2.7/dist-packages/flask/cli.py”, line 345, in main
return AppGroup.main(self, *args, **kwargs)
File “/usr/local/lib/python2.7/dist-packages/click/core.py”, line 696, in main
rv = self.invoke(ctx)
File “/usr/local/lib/python2.7/dist-packages/click/core.py”, line 1060, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File “/usr/local/lib/python2.7/dist-packages/click/core.py”, line 1060, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File “/usr/local/lib/python2.7/dist-packages/click/core.py”, line 889, in invoke
return ctx.invoke(self.callback, **ctx.params)
File “/usr/local/lib/python2.7/dist-packages/click/core.py”, line 534, in invoke
return callback(*args, **kwargs)
File “/usr/local/lib/python2.7/dist-packages/click/decorators.py”, line 17, in new_func
return f(get_current_context(), *args, **kwargs)
File “/usr/local/lib/python2.7/dist-packages/flask/cli.py”, line 229, in decorator
return __ctx.invoke(f, *args, **kwargs)
File “/usr/local/lib/python2.7/dist-packages/click/core.py”, line 534, in invoke
return callback(*args, **kwargs)
File “/app/redash/cli/users.py”, line 171, in invite
invite_user(org, user_from, user)
File “/app/redash/handlers/users.py”, line 17, in invite_user
send_invite_email(inviter, user, invite_url, org)
File “/app/redash/authentication/account.py”, line 40, in send_invite_email
html_content = render_template(‘emails/invite.html’, **context)
File “/usr/local/lib/python2.7/dist-packages/flask/templating.py”, line 134, in render_template
context, ctx.app)
File “/usr/local/lib/python2.7/dist-packages/flask/templating.py”, line 116, in _render
rv = template.render(context)
File “/usr/local/lib/python2.7/dist-packages/jinja2/environment.py”, line 989, in render
return self.environment.handle_exception(exc_info, True)
File “/usr/local/lib/python2.7/dist-packages/jinja2/environment.py”, line 754, in handle_exception
reraise(exc_type, exc_value, tb)
File “/app/redash/templates/emails/invite.html”, line 1, in top-level template code
{% extends “emails/layout.html” %}
File “/app/redash/templates/emails/layout.html”, line 558, in top-level template code
{% block content %}
File “/app/redash/templates/emails/invite.html”, line 16, in block “content”
Your Redash account is: {{ url_for(‘redash.index’, org_slug=org.slug, _external=True) }}
File “/usr/local/lib/python2.7/dist-packages/flask/helpers.py”, line 298, in url_for
raise RuntimeError('Application was not able to create a URL ’
RuntimeError: Application was not able to create a URL adapter for request independent URL generation. You might be able to fix this by setting the SERVER_NAME config variable.

If I echo back my REDASH_HOST it is correct - the root of my redash, so that has been set.
This is my docker-compose.yml

version: ‘2’
services:
server:
image: redash/redash:latest
command: server
depends_on:
- redis
ports:
- “5000:5000”
environment:
PYTHONUNBUFFERED: 0
REDASH_LOG_LEVEL: “INFO”
REDASH_REDIS_URL: “redis://redis:6379/0”
REDASH_DATABASE_URL: "postgres://{RDS_POSTGRES_USER}:{RDS_POSTGRES_PASSWORD}@{RDS_ENDPOINT}:{RDS_PORT}/{RDS_POSTGRES_DBNAME}" REDASH_COOKIE_SECRET: {COOKIE_SECRET}
REDASH_WEB_WORKERS: 4
REDASH_MAIL_SERVER: {REDASH_MAIL_SERVER} REDASH_MAIL_PORT: {REDASH_MAIL_PORT}
REDASH_MAIL_USE_TLS: {REDASH_MAIL_USE_TLS} REDASH_MAIL_USE_SSL: {REDASH_MAIL_USE_SSL}
REDASH_MAIL_USERNAME: {REDASH_MAIL_USERNAME} REDASH_MAIL_PASSWORD: {REDASH_MAIL_PASSWORD}
REDASH_MAIL_DEFAULT_SENDER: {REDASH_MAIL_DEFAULT_SENDER} REDASH_HOST: {REDASH_HOST}
REDASH_ENFORCE_HTTPS: “true”
worker:
image: redash/redash:latest
command: scheduler
environment:
PYTHONUNBUFFERED: 0
REDASH_LOG_LEVEL: “INFO”
REDASH_REDIS_URL: “redis://redis:6379/0”
REDASH_DATABASE_URL: “postgres://{RDS_POSTGRES_USER}:{RDS_POSTGRES_PASSWORD}@{RDS_ENDPOINT}:{RDS_PORT}/${RDS_POSTGRES_DBNAME}”
QUEUES: “queries,scheduled_queries,celery”
WORKERS_COUNT: 2
redis:
image: redis:3.0-alpine
nginx:
image: redash/nginx:latest
ports:
- “80:80”
- “443:443”
depends_on:
- server
links:
- server:redash
volumes:
- ./nginx-conf:/etc/nginx/conf.d/
- /etc/letsencrypt/:/etc/letsencrypt/
- /etc/ssl/certs/:/etc/ssl/certs/

And this is my .env

RDS_POSTGRES_USER=user
RDS_POSTGRES_PASSWORD=pw
RDS_ENDPOINT=endpoint
RDS_PORT=5432
RDS_POSTGRES_DBNAME=postgres
COOKIE_SECRET=cookies!
REDASH_MAIL_SERVER=email-smtp.us-east-1.amazonaws.com
REDASH_MAIL_PORT=587
REDASH_MAIL_USE_TLS=true
REDASH_MAIL_USE_SSL=false
REDASH_MAIL_USERNAME=user
REDASH_MAIL_PASSWORD=pw
REDASH_MAIL_DEFAULT_SENDER=me@mydomain.co
REDASH_HOST=https://mydomain.co

The me@mydomain.co and the newuser@mydomain.co emails have been verified in SES. And the host is as simple as the above - mydomain is data.mycompanyname.co so nothing weird in it. Any ideas?


#2

I was still facing this issue with redash 5.0.2 and given Google SSO isn’t working, I needed to bulk invite users …

Solved with https://code.luasoftware.com/tutorials/flask/flask-url-for/

have to have a request - can use app.test_request_context

For example, importing users from a csv:

import csv
from redash import models, settings, create_app
from redash.handlers.users import invite_user
from flask import current_app

inviting_user_email = "mymail@mail.com"

app = current_app or create_app()
org = models.Organization.get_by_slug("default")
groups = [org.default_group.id]
user_from = models.User.get_by_email_and_org(inviting_user_email, org)
with open('users.csv', 'rb') as csvfile, app.test_request_context(base_url="https://{}".format(settings.HOST)):
  userreader = csv.reader(csvfile, delimiter=',', quotechar='"')
  for user in userreader:
    user_new = models.User(org=org, name=user[0], email=user[1], group_ids=groups)
    models.db.session.add(user_new)
    models.db.session.commit()
    invite_user(org, user_from, user_new)
    print("An invitation was sent to [%s] at [%s]." % (user[0], user[1]))

#3

What made you think Google SSO isn’t working? It’s supported using OAuth.