def register(username, password): """Register an account.""" c = get_config() # Limit accounts by email? if not domain_allowed(username): return resp(error="{} accounts only!".format( c.registration.email_domain )), BAD_REQUEST # Conflict? user = g.db.query(User).filter(User.username == username).first() if user and user.verified: return resp(error="User already exists."), CONFLICT # Make their account. if not user: user = User(username=username, password=hash_pass(password)) g.db.add(user) g.db.commit() # Serialize the activation token. token = signed_serialize({"t": "activate", "u": user.id}) print("Activation token:" + token) # Email them the token. try: send_email(username, token) except Exception as e: print("Couldn't send mail! " + e) return resp(message="Account created. Check your email for " "activation link."), CREATED
def cas_callback(ticket): c = get_config() r = requests.get(c.cas_url + "/validate", params=dict( ticket=ticket, service=url_for(".cas_callback", _external=True), )) resp_values = r.text.split() if len(resp_values) == 2: is_valid, username = resp_values username = username.lower() if is_valid == "yes": # Auth successful! if not domain_allowed(username): return render_template("error.html", error="{} Accounts Only!".format( c.registration.email_domain )) user = g.db.query(User).filter(User.username == username).first() if not user: user = User(username=username, password="******", verified=True) g.db.add(user) g.db.commit() session["auth"] = True session["user_id"] = user.id return redirect(url_for("index")) return render_template("error.html", error="Authentication error.")
def send_email(address, token): """Send the verification e-mail.""" c = get_config() link = url_for(".verify", token=token, _external=True) # Prepare the e-mail message. msg = MIMEMultipart("alternative") msg["Subject"] = "Verify your account for the [____] Train" msg["From"] = "[____] Train <{}>".format(c.mail.sender) msg["To"] = address html = render_template("activate_email.html", link=link) text = text_verify(link) part1 = MIMEText(text.encode("UTF-8"), "plain", "UTF-8") part2 = MIMEText(html.encode("UTF-8"), "html", "UTF-8") # Attach msg.attach(part1) msg.attach(part2) # Send email smtp = None if c.mail.ssl: smtp = SMTP_SSL(c.mail.host) else: smtp = SMTP(c.mail.host) if c.mail.username and c.mail.password: smtp.login(c.mail.username, c.mail.password) smtp.sendmail(msg["From"], address, msg.as_string()) smtp.quit()
def domain_allowed(email): """Check if the email is allowed to register.""" c = get_config() if c.registration.limit_domains: if not email.lower().endswith(c.registration.email_domain): return False return True
def list_users(): c = get_config() if c.slack_token == "x": return dict(ok=False, error="Missing Slack API token") r = requests.get("https://slack.com/api/users.list", params=dict(token=c.slack_token)) return r.json()
def signed_deserialize(token): """De-serialize signed data.""" c = get_config() s = URLSafeSerializer(c.secrets.signing_key) try: result = s.loads(token) return result except: return None
def create_app(): app = Flask(__name__) c = get_config() app.config["SECRET_KEY"] = c.secrets.session_key app.config["PERMANENT_SESSION_LIFETIME"] = timedelta(days=365) app.jinja_env.block_start_string = "[%" app.jinja_env.block_end_string = "%]" app.jinja_env.variable_start_string = "[[" app.jinja_env.variable_end_string = "]]" app.jinja_env.comment_start_string = "[#" app.jinja_env.comment_end_string = "#]" app.jinja_env.block_start_string = "[%" app.jinja_env.block_end_string = "%]" app.jinja_env.variable_start_string = "[[" app.jinja_env.variable_end_string = "]]" app.jinja_env.comment_start_string = "[#" app.jinja_env.comment_end_string = "#]" @app.before_request def before_request(): g.db = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine)) g.user = None if "auth" in session and session["auth"]: user = g.db.query(User).get(session["user_id"]) g.user = user session.permanent = True @app.teardown_appcontext def after_request(exception=None): g.db.remove() @app.route("/") def index(): user = None if g.user: user = g.user.serialize return render_template("index.html", user=user, config=c, title=c.app_title, logo=c.logo_url, ) app.register_blueprint(account_bp, url_prefix="/v1/account") app.register_blueprint(train_bp, url_prefix="/v1/train") return app
def post_message(message, usernames=None): c = get_config() if usernames is None: message = "<!channel>: {}".format(message) else: for user in usernames: message = "<@{}> ".format(user) + message requests.post(c.slack_hook, headers={"Content-Type": "application/json"}, data=json.dumps(dict( text=message, channel=c.slack_channel, username="******", icon_emoji=":train:" )))
def cas_login(): c = get_config() service = url_for(".cas_callback", _external=True) return redirect(c.cas_url + "/login?service=" + service)
def hash_pass(passwd): """Hash the password.""" c = get_config() return bcrypt.hashpw(text_type(passwd).encode("utf-8"), bcrypt.gensalt(int(c.bcrypt.iterations))).decode("utf-8")
def signed_serialize(data): """Serialize signed data.""" c = get_config() s = URLSafeSerializer(c.secrets.signing_key) return s.dumps(data)