def change_user_acl(): session_token = request.form['session_token'] acl_data = request.form['acl'] db = database.Database() auth_user_id = db.validate_session(session_token) if auth_user_id: auth_user_ctx = UserContext(auth_user_id, db, current_app.logger) if auth_user_ctx.check_acl("change-permissions"): user_id = int(request.form['user_id']) user_ctx = UserContext(user_id, db, current_app.logger) user_event = Event("Users Changed Permissions", db, current_app.logger) event_data = {"email_address": user_ctx.user_info["email_address"], "user_id": user_id, "new_acl_data": acl_data} user_event.log_event(auth_user_id, event_data) result = db.update_user_permissions(user_id, json.loads(acl_data)) if result: message = "Access Control List updated for " + user_ctx.user_info['email_address'] return render_template("admin/admin_confirmation.jinja2", session_token=session_token, title="ACL Updated", confirmation_title="ACL Updated", confirmation_message=message, confirmation_type="acl_updated", default_choice="OK") else: abort(500) abort(403)
def onboard_user(): session_token = request.form["session_token"] db = database.Database() user_id = db.validate_session(session_token) if user_id: user_ctx = UserContext(user_id, db, current_app.logger) auth = user_ctx.check_acl("onboard-users") if auth: acl = json.loads(request.form["acl"]) # TODO make sure the user is not issuing permissions they don't have themselves full_name = request.form["full_name"] email = request.form["email_address"] pw_hash = request.form["pw_hash"] ip_addr = request.access_route[-1] new_user_id = db.onboard_user(full_name, email, pw_hash, json.dumps(acl), ip_addr) if new_user_id: new_user_context = UserContext(new_user_id, db, current_app.logger) new_user_event = Event("Users Create User", db, current_app.logger) new_user_event.log_event(user_id, {"user_id": new_user_id, "email": email, "full_name": full_name, "acl": json.dumps(acl)}) db.update_user_permissions(new_user_id, json.dumps(acl)) message = "Successfully created new user " + new_user_context.user_info["email_address"] return render_template("admin/admin_confirmation.jinja2", session_token=session_token, confirmation_type="onboarded_new_user", confirmation_title="Created New User", confirmation_message=message, default_choice="Create Another User", choices=["Administration"]) else: abort(500) abort(403)
def admin_create_user_acl(): session_token = request.form["session_token"] full_name = request.form["full_name"] email_address = request.form["email_address"] password = request.form["password"] password_repeat = request.form["password_repeat"] if EMAIL_REGEX.match(email_address) is None: return render_template("admin/admin_create_user.jinja2", session_token=session_token, create_user_error="Invalid e-mail address.") if len(password) < 8: return render_template("admin/admin_create_user.jinja2", session_token=session_token, create_user_error="Password must be at least 8 characters in length.") if password == password_repeat: data = email_address + password pw_hash = sha256(data.encode("utf-8")).hexdigest() else: return render_template("admin/admin_create_user.jinja2", session_token=session_token, create_user_error="Password must match both times.") db = database.Database(current_app.logger) user_id = db.validate_session(session_token) ctx = UserContext(user_id, db, current_app.logger) if user_id: authorized = db.validate_permission(user_id, "onboard-users") if authorized: ip_addr = request.access_route[-1] result = db.create_user(full_name, email_address, password, ip_addr) if result: if result[0] == -1: return render_template("admin/admin_create_user.jinja2", session_token=session_token, create_user_error="E-mail address already exists in the database.") else: user_ctx = UserContext(result[0], db, current_app.logger) # default permissions user_ctx.add_permission("own-any-token") user_ctx.add_permission("transfer-owned-token") db.update_user_permissions(result[0], user_ctx.acl()) create_user_event = Event("Users Create User", db, logger=current_app.logger) metadata = {"ip_addr": ip_addr, "created_by": ctx.user_info['email_address'], "new_user_email_address": email_address, "new_user_id": result[0]} create_user_event.log_event(user_id, json.dumps(metadata)) return render_template("admin/admin_create_user.jinja2", session_token=session_token, create_user_error="User created successfully.") abort(403)
def recover_password(self): db = Database(self.logger) new_event = Event("Mailer Password Reset", db, self.logger) confirmation_code = os.urandom(16).hex() user_id = db.validate_email(self.email_address) if user_id: new_event_id = new_event.log_event( user_id, { "ip_address": self.ip_address, "confirmation": confirmation_code })
def create_tokens_form(): session_token = request.form["session_token"] if session_token: db = database.Database(logger=current_app.logger) logger = current_app.logger user_id = db.validate_session(session_token) ctx = UserContext(user_id, db, logger) auth = ctx.check_acl("launch-ico") token_name = request.form['token_name'] if not TOKEN_NAME_REGEX.match(token_name): create_token_error = "Invalid token name, must consist of 4-36 alphanumeric characters only." return render_template("admin/admin_confirmation.jinja2", session_token=session_token, confirmation_title="Invalid ERC20 parameter(s)", confirmation_message=create_token_error, confirmation_type="create_erc20_failed", default_choice="OK") token_symbol = request.form['token_symbol'] if len(token_symbol) > 0 and not TOKEN_SYMBOL_REGEX.match(token_symbol): create_token_error = "Invalid token symbol, must consist of between 1-5 uppercase letters or numbers. This field is optional." return render_template("admin/admin_confirmation.jinja2", session_token=session_token, confirmation_title="Invalid ERC20 parameter(s)", confirmation_message=create_token_error, confirmation_type="create_erc20_failed", default_choice="OK") elif len(token_symbol) == 0: token_symbol = None token_count = request.form['token_count'] if not TOKEN_COUNT_REGEX.match(token_count): return render_template("admin/admin_confirmation.jinja2", session_token=session_token, confirmation_title="Invalid ERC20 parameter(s)", confirmation_message="Invalid initial token count value, must be a positive integer.", confirmation_type="create_erc20_failed", default_choice="OK") token_count = int(token_count) if auth: sc = SmartContract(token_name=token_name, token_symbol=token_symbol, token_count=token_count, logger=current_app.logger, owner_id=user_id) if sc.smart_contract_id > 0: new_event = Event("ERC20 Token Created", db, current_app.logger) new_event.log_event(user_id, {"ip_address": request.access_route[-1], "token_name": token_name, "token_symbol": token_symbol, "token_count": token_count, "token_id": sc.smart_contract_id, }) return redirect(url_for("admin.admin_tokens", session_token=session_token)) else: create_token_error = "Token with this name already managed by ERC20Master, to make things less " create_token_error += "confusing, please use a unique token name." return render_template("admin/admin_confirmation.jinja2", session_token=session_token, title="Error", confirmation_title="Token Name Exists", confirmation_message=create_token_error, confirmation_type="create_erc20_failed", default_choice="OK") abort(403)
def admin_confirm(): session_token = request.form["session_token"] confirmation_type = request.form["confirmation_type"] confirmation_val = request.form["confirmation_value"] choice = request.form["choice"] if confirmation_type == "recover_email": if choice == "Send E-mail": email_address = request.form['email_address'] mailer = Mailer(email_address, request.access_route[-1], current_app.logger) mailer.recover_password() return render_template("admin/admin_login.jinja2", error=""" If the e-mail address is in the database, instructions have been sent on how to recover your password. Please check your spam/junk mail folder. """) return redirect(url_for('homepage')) elif confirmation_type == "no_erc20_tokens": return redirect(url_for('admin.admin_tokens', session_token=session_token)) elif confirmation_type == "erc20_publish" and choice == "Cancel": return redirect(url_for('admin.admin_tokens', session_token=session_token)) elif confirmation_type == "create_erc20_failed" and choice == "OK": return redirect(url_for('admin.admin_tokens', session_token=session_token)) elif confirmation_type == "onboarded_new_user": if choice == "Administration": return redirect(url_for('admin.admin_main', session_token=session_token)) else: return redirect(url_for('admin.create_user', session_token=session_token)) elif confirmation_type == "reset-password": if choice == "Cancel": return redirect(url_for("admin.view_users", session_token=session_token, limit=PAGE_LIMIT, offset=0)) elif confirmation_type == "acl_updated": if choice == "OK": return redirect(url_for("admin.view_users", session_token=session_token, limit=PAGE_LIMIT, offset=0)) db = database.Database(logger=current_app.logger) user_id = db.validate_session(session_token) if user_id: user_ctx = UserContext(user_id, db, current_app.logger) if confirmation_type == "erc20_publish": token_id = int(confirmation_val) sc = SmartContract(smart_token_id=token_id) credits = Credits(user_id, db, logger=current_app.logger) if sc.smart_contract_id > 0: event_data = {"token_name": sc.token_name, "token_symbol": sc.token_symbol, "token_count": sc.tokens, "token_id": sc.smart_contract_id, "ip_address": request.access_route[-1]} if user_ctx.check_acl("launch-ico"): credits_balance = credits.get_credit_balance() if credits_balance >= credits.erc20_publish_price: new_event = Event("ERC20 Token Mined", db, logger=current_app.logger) event_id = new_event.log_event(user_id, event_data) event_data["event_id"] = event_id credits.debit(credits.erc20_publish_price, event_data) command_id = db.post_command(json.dumps({"erc20_function":"publish", "token_name":sc.token_name, "token_symbol":sc.token_symbol, "token_count":sc.tokens, "token_id":sc.smart_contract_id}), 100) if command_id: return redirect(url_for("admin.admin_tokens", session_token=session_token)) else: abort(500) else: credits.logger.error("Insufficient credits for ERC20 Publish: " + user_ctx.user_info["email_address"]) abort(403) elif confirmation_type == "reset-password": user_id = int(confirmation_val) if request.form["password"] != request.form["repeat_password"]: return render_template("admin/admin_confirmation.jinja2", confirmation_type="reset-password", confirmation_value=user_id, title="Reset Password", confirmation_title="Reset Password", confirmation_message="Passwords must match both times.", new_password=True, choices=["Cancel"], default_choice="Reset Password", session_token=session_token) if db.reset_password(int(confirmation_val), request.form["password"]): return redirect(url_for("admin.view_users", session_token=session_token, limit=PAGE_LIMIT, offset=0)) elif confirmation_type == "issue-credits": if choice == "Issue Credits" and user_ctx.check_acl("issue-credits"): user_credits = Credits(confirmation_val, db, current_app.logger) amount = int(request.form["credits"]) # max issued credits 10,000 if 0 < amount < 100000: user_credits.issue_credits(amount, {"ip_addr": request.access_route[-1], "admin": user_id}) return redirect( url_for("admin.view_users", session_token=session_token, limit=PAGE_LIMIT, offset=0)) else: raise ValueError abort(403)