Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User Management backend - Base #26

Closed
wants to merge 27 commits into from

Conversation

DoRTaL94
Copy link
Collaborator

@DoRTaL94 DoRTaL94 commented Apr 11, 2020

fixes #27.
We created the models we are going to work with and the database handler.
We're going to send 3 more PRs that will include: login, logout and signup logic.
@ahinoamta @RoniRush

@DoRTaL94 DoRTaL94 requested a review from simzacks April 11, 2020 16:53
backend/__init__.py Outdated Show resolved Hide resolved
setup.sh Outdated Show resolved Hide resolved
backend/models/response_user.py Outdated Show resolved Hide resolved
backend/models/response_user.py Outdated Show resolved Hide resolved
backend/models/response_user.py Outdated Show resolved Hide resolved
setup.sh Outdated Show resolved Hide resolved
@simzacks
Copy link
Collaborator

please resolve the conflicts in the conflicting files by pulling the latest master, rebasing and fixing

@ahinoamta ahinoamta requested review from ahinoamta and simzacks April 12, 2020 12:21
- Added to_json function to User model that
exposes less information to the client.

- Added types to methods parameters

- Added id column to token_blacklist table
@DoRTaL94 DoRTaL94 changed the title User Management backend #12 WIP User Management backend Apr 12, 2020
@DoRTaL94 DoRTaL94 changed the title WIP User Management backend User Management backend Apr 13, 2020
Copy link
Contributor

@lmilbaum lmilbaum left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is not issue linked to this RP.
There are unresolved conversations. Please verify the reviewers resolve them.
This PR is huge. Can you break it to smaller ones?

@ahinoamta
Copy link
Collaborator

@lioramilbaum

There is not issue linked to this RP - ack.
There are unresolved conversations. Please verify the reviewers resolve them - **We are waiting for @simzacks review 😄 **.
This PR is huge. Can you break it to smaller ones? - The PR already reviewed by Sim, there are few changes according to the CR that require last review. We will be glad if this PR will be approved, and for the next PRs we will pay more attention about the PR size.
@DoRTaL94 @RoniRush

requirements.txt Outdated Show resolved Hide resolved
setup.sh Outdated Show resolved Hide resolved
@DoRTaL94 DoRTaL94 requested a review from ifireball April 16, 2020 14:13
.gitignore Outdated Show resolved Hide resolved
Vagrantfile Outdated
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/bionic64"
config.vm.provision :shell, path: "setup.sh"
config.vm.network :forwarded_port, guest: FLASK_PORT, host: FLASK_PORT
config.vm.network :forwarded_port, guest: POSTGRESQL_PORT, host: POSTGRESQL_PORT
config.vm.network "public_network"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC, this means that the Vagrant machine will get a DHCP IP address when it is started and you will access the app directly from that IP address.
How are you planning on keeping track/publishing of that IP address? Or are you planning on using DYNDNS?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When vagrant start up it shows its public IP inside the console. Should I make its public IP static?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You really shouldn't be connecting your development VM to the public network. It exposes it to the network outside your development machine which is not something you generally want and can cause issues for other developers down the line because the way the machine works can now be affected by the network the developer's machine happens to be connected to...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see. So making it a private network and set a static IP will be okay?

Copy link
Collaborator

@ifireball ifireball Apr 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting a static IP can also cause issues if it will happen to clash with an IP in someone's home network. The best approach is to not make any hard assumptions and just let Vagrant allocate an internal dynamic IP automatically.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack.

Copy link
Collaborator Author

@DoRTaL94 DoRTaL94 Apr 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ifireball I changed the network definition to private, executed vagrant up and everything went smooth. But when I executed vagrant destroy and vagrant up again I got this issue hashicorp/vagrant#3083 .
The solution I found that worked for me was hashicorp/vagrant#8878 (comment) .
Should I add this to the Vagrantfile ?

Edit 1: To be more exact, after the second vagrant up this command aborted and I got this message:

A host only network interface you're attempting to configure via DHCP
already has a conflicting host only adapter with DHCP enabled. The
DHCP on this adapter is incompatible with the DHCP settings. Two
host only network interfaces are not allowed to overlap, and each
host only network interface can have only one DHCP server. Please
reconfigure your host only network or remove the virtual machine
using the other host only network.

Edit 2: I found another solution for this problem that not need any modification to Vagrantfile - https://www.gitmemory.com/issue/hashicorp/vagrant/3083/502713875 .

I'd really appreciate your advice on how to proceed.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either of those 2 solutions work, but whichever you do, you should have a comment that references the problem and the solution

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. I think the easiest solution, that also won't require the team to fix it manually every time, would be the Vagrantfile solution.

backend/__init__.py Outdated Show resolved Hide resolved
backend/models/token.py Outdated Show resolved Hide resolved
setup.sh Outdated Show resolved Hide resolved
@DoRTaL94 DoRTaL94 requested a review from simzacks April 20, 2020 11:41
@DoRTaL94 DoRTaL94 changed the title User Management backend User Management backend - Base Apr 20, 2020
echo "running flask_init.py"
export FLASK_APP=/vagrant/flask_init.py
python3 -m flask run --host=0.0.0.0 >> /vagrant/log.log 2>&1 &
echo "configuring database"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Executing this kind of SQL manually during the setup stage means you get a new database every time you bring up the system - this might work out in development but not in staging or production.

The technique for managing database configuration over time with Git is called "database migrations" here is a post introducing this concept:
https://rollout.io/blog/database-migration/
The examples there are for Ruby-on-Rails but the same concepts apply to Flask and SQLAlchemy

Here is a DB migration framework you can use with SQLAlchemy:
https://alembic.sqlalchemy.org/en/latest/

Copy link
Collaborator Author

@DoRTaL94 DoRTaL94 Apr 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Executing this kind of SQL manually during the setup stage means you get a new database every time you bring up the system

Should we create the database manually ? But on the next vagrant up we'll need to create it again... That is why I added those lines to setup.sh so we wouldn't need to do it over and over again.

The technique for managing database configuration over time with Git is called "database migrations"

Doesn't it migrate only the tables schema without the data ? and if so on vagrant destroy all the data will be gone. How does it different from creating a new database on every vagrant up ?

Edit: I've added Flask-Migrate extension to the project that handles SQLAlchemy database migrations for Flask applications using Alembic. It super easy to use and it configures Alembic in the proper way to work with our Flask and SQLAlchemy application.
Regarding of the question I asked:

Doesn't it migrate only the tables schema without the data ? and if so on vagrant destroy all the data will be gone.

I solved this issue of the data being destroyed by saving it inside the vagrant synced folder.
I used vagrant triggers so just before vagrant destroy is executed I save the data and
after vagrant up is executed I restore the data.
But I still need the SQL commands inside setup.sh to be executed so the database will be created.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I squashed some commits so this file is no longer reachable through this commit.
This file could be found here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what vagrant workflow you're aiming for, but I think the current solution looks too complex and may not be needed.

They way I think of it, your workflow should include several commands:

  1. A command that brings up a dev environment from scratch on a new machine (Typically the first time you run vagrant up)
  2. A command that resyncs your code changes to the dev environment (May not be needed if your intended workflow is to develop directly on the Vagrant machine). It should probably also do things like:
    1. Run any DB migrations that were not yet applied to the DB
    2. Restart the application server or otherwise have some other way to make it reload the code if it does not do that automatically
  3. A command that shuts down the environment without destroying the data in it (Typically vagrant halt)
  4. A command that brings an existing environment back up (Typically vagrant up when its not the first time you've ran it)
  5. A command that clears up the environment so it can be created from scratch (Typically vagrant destroy)

You can use different combinations of Vagrant commands and scripts to achieve the commands above, but you should have them available because they are all needed in a typical development workflow.

@DoRTaL94 DoRTaL94 requested a review from ifireball April 21, 2020 14:59
@DoRTaL94 DoRTaL94 force-pushed the user-management branch 4 times, most recently from be4d16e to 0367edc Compare April 21, 2020 21:37
Copy link
Collaborator

@simzacks simzacks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Just some minor comments.
I'm not familiar with the migration stuff so maybe @ifireball can have a look at that.

.gitignore Outdated Show resolved Hide resolved
Vagrantfile Outdated Show resolved Hide resolved
edison/config.py Show resolved Hide resolved
DoRTaL94 and others added 9 commits April 22, 2020 22:08
All files inside edison/migrations were generated automatically by the extension.
- Deleted forwarded port from Vagrantfile.

- Set Vagrantfile network definition to private

- Added triggers to Vagrantfile for up and destroy commands.
After vagrant up is executed an attempt to restore db data accures.
Before vagrant destroy is executed a save to db data accures.

- Fixed dhcp configuration conflict of the private network.
Copy link
Collaborator

@ifireball ifireball left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is becoming too big and it contains many different things:

  1. Restructuring of the Vagrant workflow
  2. An addition a DB service
  3. The addition of an ORM and a Migrations framework
  4. The addition of unit tests
  5. (Finally) the addition of some new models

You should probably think up ways to split it apart....

echo "running flask_init.py"
export FLASK_APP=/vagrant/flask_init.py
python3 -m flask run --host=0.0.0.0 >> /vagrant/log.log 2>&1 &
echo "configuring database"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what vagrant workflow you're aiming for, but I think the current solution looks too complex and may not be needed.

They way I think of it, your workflow should include several commands:

  1. A command that brings up a dev environment from scratch on a new machine (Typically the first time you run vagrant up)
  2. A command that resyncs your code changes to the dev environment (May not be needed if your intended workflow is to develop directly on the Vagrant machine). It should probably also do things like:
    1. Run any DB migrations that were not yet applied to the DB
    2. Restart the application server or otherwise have some other way to make it reload the code if it does not do that automatically
  3. A command that shuts down the environment without destroying the data in it (Typically vagrant halt)
  4. A command that brings an existing environment back up (Typically vagrant up when its not the first time you've ran it)
  5. A command that clears up the environment so it can be created from scratch (Typically vagrant destroy)

You can use different combinations of Vagrant commands and scripts to achieve the commands above, but you should have them available because they are all needed in a typical development workflow.

@@ -0,0 +1,96 @@
from __future__ import with_statement
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was this file and others like it auto-created? you should document the processes for creating/updating them and what they are used for.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, all files inside edison/migrations folder was auto created by Flask-Migrate extension.
I'll document what you suggested inside the README file in the migrations folder.

@@ -0,0 +1 @@
Generic single-database configuration.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you probably need to add more information here so your peers can learn what is the migratins directory used for and how to use/update it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack

JWT_BLACKLIST_TOKEN_CHECKS = ['access', 'refresh']
SQLALCHEMY_DATABASE_URI = 'postgresql://postgres:[email protected]/edison'

class ProductionConfig(Config):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should probably include a comment here that at last the connection string should be update once an actual production environment is established.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ack

export FLASK_APP=/vagrant/flask_init.py
python3 -m flask run --host=0.0.0.0 >> /vagrant/log.log 2>&1 &
echo "configuring database"
sudo su postgres <<POSTGRESQL_COMMANDS
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIR Postgeas has some command-line shortcuts for DB and user creation, could be cleaner to use those then inlined SQL.


class Tester(unittest.TestCase):
def test_home(self):
response = requests.get("http://127.0.0.1:5000")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this meant to run on the Vagrant VM or on the developer machine? If its the latter, 127.0.0.1 is probably not the right address to connect to. If its the former, there should be instructions somewhere to tell oyur peers how to run test.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its not a file that we created as part of this PR.
In fact this file is approved as part of issue #7.
I just changed the name of the folder containing it.

@@ -0,0 +1,11 @@
import unittest
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Id recommend using pytest is waaay less cumbersome then PyUnit.

Copy link
Collaborator Author

@DoRTaL94 DoRTaL94 Apr 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I said in the conversation above its not a file that we created as part of this PR.
But in our future tests we sure will use pytest.

@DoRTaL94
Copy link
Collaborator Author

This PR is splitted into muiltiple PRs.
The following PRs are now fixing issue #27:
#36, #37, #38, #39, #40.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

User Management backend - Base
7 participants