Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ dist/
build/
*.egg-info/
.DS_Store
.vscode/settings.json
.vscode/settings.json
.idea/
13 changes: 13 additions & 0 deletions .run/devserver.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="devserver" type="ShConfigurationType">
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
<option name="SCRIPT_PATH" value="/usr/local/bin/pipenv" />
<option name="SCRIPT_OPTIONS" value="run devserver" />
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
<option name="INTERPRETER_PATH" value="/bin/zsh" />
<option name="INTERPRETER_OPTIONS" value="" />
<method v="2" />
</configuration>
</component>
13 changes: 13 additions & 0 deletions .run/initdb.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="initdb" type="ShConfigurationType">
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
<option name="SCRIPT_PATH" value="/usr/local/bin/pipenv" />
<option name="SCRIPT_OPTIONS" value="run initdb" />
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
<option name="INTERPRETER_PATH" value="/bin/zsh" />
<option name="INTERPRETER_OPTIONS" value="" />
<method v="2" />
</configuration>
</component>
2 changes: 1 addition & 1 deletion jcrm_lite/api/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .api import register_api
from .api import bp
50 changes: 25 additions & 25 deletions jcrm_lite/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,41 @@
from ..db.models import Contact
from ..db.model_utils import jsonify_one, jsonify_list
from ..auth import login_required
from flask import jsonify, request, session
from flask import Blueprint, jsonify, request, session
from datetime import datetime

API_PREFIX = '/api/v1'
bp = Blueprint('api', __name__, url_prefix='/api/v1')


def register_api(app):
@bp.route('/contacts', methods=['GET'])
@login_required
def get_contacts():
contacts = Contact.query.all()
return jsonify_list(contacts)

@app.route(API_PREFIX + '/contacts', methods=['GET'])
@login_required
def get_contacts():
contacts = Contact.query.all()
return jsonify_list(contacts)

@app.route(API_PREFIX + '/contact/<int:contact_id>', methods=['GET'])
@login_required
def get_contact(contact_id):
contact = Contact.query.filter_by(id=contact_id).one()
return jsonify_one(contact)
@bp.route('/contact/<int:contact_id>', methods=['GET'])
@login_required
def get_contact(contact_id):
contact = Contact.query.filter_by(id=contact_id).one()
return jsonify_one(contact)

@app.route(API_PREFIX + '/contact/<int:contact_id>', methods=['PUT'])
@login_required
def update_contact(contact_id):

data = request.get_json()
@bp.route('/contact/<int:contact_id>', methods=['PUT'])
@login_required
def update_contact(contact_id):

contact = Contact.query.filter_by(id=contact_id).one()
data = request.get_json()

contact.company_name = data['company_name']
contact.first_name = data['first_name']
contact.last_name = data['last_name']
contact = Contact.query.filter_by(id=contact_id).one()

contact.updated_date = datetime.utcnow()
contact.updated_user_id = session.get("user_id")
contact.company_name = data['company_name']
contact.first_name = data['first_name']
contact.last_name = data['last_name']

db.session.commit()
contact.updated_date = datetime.utcnow()
contact.updated_user_id = session.get('user_id')

return jsonify({'success': True})
db.session.commit()

return jsonify({'success': True})
3 changes: 0 additions & 3 deletions jcrm_lite/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ def create_app(test_config=None):
db.init_app(app)
initdb.register_command(app)

# init auth
app.register_blueprint(auth.bp)

# routes
routes.register_routes(app)

Expand Down
4 changes: 1 addition & 3 deletions jcrm_lite/auth/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
from .auth import (
login_required, bp
)
from .auth import login_required, bp
46 changes: 23 additions & 23 deletions jcrm_lite/auth/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from ..db import db
from ..db.models import User

bp = Blueprint("auth", __name__, url_prefix="/auth")
bp = Blueprint('auth', __name__, url_prefix='/auth')


def login_required(view):
Expand All @@ -17,7 +17,7 @@ def login_required(view):
@functools.wraps(view)
def wrapped_view(**kwargs):
if g.user is None:
return redirect(url_for("auth.login"))
return redirect(url_for('auth.login'))

return view(**kwargs)

Expand All @@ -28,35 +28,35 @@ def wrapped_view(**kwargs):
def load_logged_in_user():
"""If a user id is stored in the session, load the user object from
the database into ``g.user``."""
user_id = session.get("user_id")
user_id = session.get('user_id')

if user_id is None:
g.user = None
else:
g.user = User.query.filter_by(id=user_id).first()


@bp.route("/register", methods=("GET", "POST"))
@bp.route('/register', methods=('GET', 'POST'))
def register():
"""Register a new user.

Validates that the username is not already taken. Hashes the
password for security.
"""
if request.method == "POST":
username = request.form["username"]
password = request.form["password"]
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
error = None

if not username:
error = "Username is required."
error = 'Username is required.'
elif not password:
error = "Password is required."
error = 'Password is required.'
elif (
User.query.filter_by(username=username).first()
is not None
):
error = "User {0} is already registered.".format(username)
error = 'User {0} is already registered.'.format(username)

if error is None:
# the name is available, store it in the database and go to
Expand All @@ -66,40 +66,40 @@ def register():
password=generate_password_hash(password)
))
db.session.commit()
return redirect(url_for("auth.login"))
return redirect(url_for('auth.login'))

flash(error)

return render_template("auth/register.html")
return render_template('auth/register.html')


@bp.route("/login", methods=("GET", "POST"))
@bp.route('/login', methods=('GET', 'POST'))
def login():
"""Log in a registered user by adding the user id to the session."""
if request.method == "POST":
username = request.form["username"]
password = request.form["password"]
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
error = None

user = User.query.filter_by(username=username).first()
if user is None:
error = "Incorrect username."
error = 'Incorrect username.'
elif not check_password_hash(user.password, password):
error = "Incorrect password."
error = 'Incorrect password.'

if error is None:
# store the user id in a new session and return to the index
session.clear()
session["user_id"] = user.id
return redirect(url_for("index"))
session['user_id'] = user.id
return redirect(url_for('index'))

flash(error)

return render_template("auth/login.html")
return render_template('auth/login.html')


@bp.route("/logout")
@bp.route('/logout')
def logout():
"""Clear the current session, including the stored user id."""
session.clear()
return redirect(url_for("index"))
return redirect(url_for('index'))
6 changes: 4 additions & 2 deletions jcrm_lite/routes.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@

from flask import render_template
from .auth import login_required
from .api import register_api
from .api import bp as api_bp
from .auth import bp as auth_bp


def register_routes(app):
Expand All @@ -12,4 +13,5 @@ def register_routes(app):
def index(path='/'):
return render_template('app.html')

register_api(app)
app.register_blueprint(auth_bp)
app.register_blueprint(api_bp)
12 changes: 6 additions & 6 deletions jcrm_lite/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@
<span class="navbar-text">
<ul class="list-inline m-0">
{% if g.user %}
<li class="list-inline-item wide"><span style="padding-right: 8px;">{{ g.user['username'] }}</span>
<li class="list-inline-item"><a href="{{ url_for('auth.logout') }}">Log Out</a>
{% else %}
<li class="list-inline-item wide"><a href="{{ url_for('auth.register') }}">Create Account</a>
<li class="list-inline-item"><a href="{{ url_for('auth.login') }}">Log In</a>
{% endif %}
<li class="list-inline-item wide"><span style="padding-right: 8px;">{{ g.user['username'] }}</span></li>
<li class="list-inline-item"><a href="{{ url_for('auth.logout') }}">Log Out</a></li>
{% else %}
<li class="list-inline-item wide"><a href="{{ url_for('auth.register') }}">Create Account</a></li>
<li class="list-inline-item"><a href="{{ url_for('auth.login') }}">Log In</a></li>
{% endif %}
</ul>
</span>
</div>
Expand Down