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

Ro auth wip #73

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
21 changes: 21 additions & 0 deletions lib/quack/password.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
defmodule Quack.Password do
alias Quack.Repo
import Ecto.Changeset, only: [put_change: 3]
import Comeonin.Bcrypt, only: [hashpwsalt: 1]

@doc """
Encrypts password in the user changeset and stores it to the changeset as `encrypted_password`.
"""
def encrypt_password(changeset) do
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

defp instead of def?

put_change(changeset, :encrypted_password, hashpwsalt(changeset.params["password"]))
end

@doc """
Encrypts password in the user changeset and stores it to the database.
"""
def encrypt_password_and_save_user(changeset) do
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

changeset
|> encrypt_password
|> Repo.insert
end
end
3 changes: 2 additions & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ defmodule Quack.Mixfile do
# Type `mix help deps` for examples and options
defp deps do
[{:phoenix, "~> 0.14"},
{:phoenix_ecto, "~> 0.4"},
{:phoenix_ecto, "~> 0.5"},
{:postgrex, ">= 0.0.0"},
{:phoenix_html, "~> 1.1"},
{:phoenix_live_reload, "~> 0.4.3", only: :dev},
{:comeonin, "~> 1.0"},
{:cowboy, "~> 1.0"}]
end
end
3 changes: 2 additions & 1 deletion mix.lock
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
%{"cowboy": {:hex, :cowboy, "1.0.2"},
%{"comeonin": {:hex, :comeonin, "1.0.5"},
"cowboy": {:hex, :cowboy, "1.0.2"},
"cowlib": {:hex, :cowlib, "1.0.1"},
"decimal": {:hex, :decimal, "1.1.0"},
"ecto": {:hex, :ecto, "0.12.1"},
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
},
"dependencies": {
"flux": "^2.0.3",
"jquery": "^2.1.4",
"object-assign": "^3.0.0",
"react": "^0.13.3",
"react-router": "^0.13.3"
Expand Down
10 changes: 10 additions & 0 deletions priv/repo/migrations/20150721043946_AddFieldsToUser.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
defmodule Quack.Repo.Migrations.AddFieldsToUser do
use Ecto.Migration

def change do
alter table(:users) do
add :email, :string
add :password_encrypted, :string
end
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Both columns need indexes. Probably should be null: false also.

end
end
23 changes: 23 additions & 0 deletions web/controllers/registration_controller.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
defmodule Quack.RegistrationController do
use Quack.Web, :controller

alias Quack.Password

plug :scrub_params, "user" when action in [:create]

def create(conn, params) do
changeset = User.changeset(%User{}, params["user"])

if changeset.valid? do
new_user = Password.encrypt_password_and_save_user(changeset)

conn
|> put_flash(:info, "Successfully registered and logged in")
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

How does put_flash work in an xhr? Or this is wip still?

|> put_session(:current_user, new_user)
|> redirect(to: page_path(conn, :index))
else
# render json error
json conn, %{error: "WHOOPS!"}
end
end
end
9 changes: 8 additions & 1 deletion web/models/user.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ defmodule Quack.User do
use Quack.Web, :model

schema "users" do
field :email, :string
field :name, :string
field :password_encrypted, :string
field :password, :string, virtual: true
field :password_confirmation, :string, virtual: true
has_many :messages, Message

timestamps
end

@required_fields ~w(name)
@required_fields ~w(email name password password_confirmation)
@optional_fields ~w()

@doc """
Expand All @@ -20,5 +24,8 @@ defmodule Quack.User do
def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
|> validate_unique(:email, on: Quack.Repo, downcase: true)
|> validate_length(:password, min: 6)
|> validate_confirmation(:password, message: "passwords do not match")
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Whoa! Didn't know this existed. Cool.

end
end
9 changes: 5 additions & 4 deletions web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ defmodule Quack.Router do
get "/", PageController, :index
end

# Other scopes may use custom stacks.
# scope "/api", Quack do
# pipe_through :api
# end
scope "/api", Quack do
pipe_through :api

post "/register", RegistrationController, :create
end
end
14 changes: 14 additions & 0 deletions web/static/js/actions/actions.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var AppDispatcher = require('../dispatcher/app_dispatcher');
var ActionTypes = require('../constants/constants').ActionTypes;
var QuackAPI = require('../data/api');
var QuackSocket = require('../data/socket');
var UserStore = require('../stores/user_store');
var UserCommandHandler = require('../utils/user_command_handler');
Expand Down Expand Up @@ -50,6 +51,19 @@ module.exports = {
);
},

registerUser: function(userParams) {
QuackAPI.post({
user: userParams
});
// dispatch(
// ActionTypes.REGISTER_USER,
// {
// email: userParams.email,
// password: userParams.password
// }
// );
},

subscribe: function(roomName) {
dispatch(ActionTypes.SUBSCRIBE, roomName);
this.flashNotify('Joining ' + roomName);
Expand Down
4 changes: 2 additions & 2 deletions web/static/js/components/login.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ var Actions = require('../actions/actions');
var Navigation = require('react-router').Navigation;
var KeyCodes = require('../utils/keycodes');

var About = React.createClass({
var Login = React.createClass({
mixins: [Navigation],
render: function () {
return (
Expand Down Expand Up @@ -42,4 +42,4 @@ var About = React.createClass({

});

module.exports = About;
module.exports = Login;
1 change: 1 addition & 0 deletions web/static/js/components/quack.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ var Quack = React.createClass({
<nav>
<ul>
<li><Link to="login">Login</Link></li>
<li><Link to="register">Register</Link></li>
<li><Link to="about">About</Link></li>
<li><Link to="chat">Chat</Link></li>
</ul>
Expand Down
56 changes: 56 additions & 0 deletions web/static/js/components/register.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
var React = require('react');
var Actions = require('../actions/actions');
var Navigation = require('react-router').Navigation;
var KeyCodes = require('../utils/keycodes');

var Register = React.createClass({
mixins: [Navigation],

render: function () {
return (
<article className="register">
<input type="text" placeholder="email" onChange={this._onChange.bind(this, 'email')} onKeyDown={this._onKeyDown} />
<input type="password" placeholder="password" onChange={this._onChange.bind(this, 'password')} onKeyDown={this._onKeyDown} />
<a className="quack" onClick={this._onClick} href="#">Register</a>
</article>
);
},

getInitialState: function() {
return {
email: "",
password: ""
};
},

_onChange: function(field, event) {
event.preventDefault();
var newState = {};
newState[field] = event.target.value;
this.setState(newState);
},

_onClick: function(e) {
e.preventDefault();
this._registerUser();
},

_onKeyDown: function(event) {
if (event.keyCode === KeyCodes.enter) {
event.preventDefault();
this._registerUser();
}
},

_register: function() {
Actions.registerUser({
email: this.state.email,
password: this.state.password
});

// this.transitionTo('chat');
}

});

module.exports = Register;
1 change: 1 addition & 0 deletions web/static/js/constants/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports = {
EDIT_LAST_MESSAGE: null,
INCOMING_MESSAGE: null,
NOTIFY: null,
REGISTER_USER: null,
SUBSCRIBE: null,
UNSUBSCRIBE: null,
USER_LIST_CHANGE: null,
Expand Down
19 changes: 19 additions & 0 deletions web/static/js/data/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
var $ = require('jquery');
Copy link
Contributor

Choose a reason for hiding this comment

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

I suggest to use superagent to do ajax requests:
http://visionmedia.github.io/superagent/
Jquery is a bit too heavy for this sole task!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

👍

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Actually, I believe we can use the ajax functionality in phoenix.js


var QuackAPI = {
post: function(params) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If this always posts to /register lets put that in the name.

$.ajax({
type: 'post',
url: '/api/register',
data: params,
success: function() {
console.log('Success!');
},
error: function() {
console.log('Error! :(');
}
});
}
};

module.exports = QuackAPI;
2 changes: 2 additions & 0 deletions web/static/js/routes/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ var About = require('../components/about.jsx');
var Quack = require('../components/quack.jsx');
var Chat = require('../components/chat.jsx');
var Login = require('../components/login.jsx');
var Register = require('../components/register.jsx');

var routes = (
<Route path='/' handler={Quack}>
<DefaultRoute name="login" handler={Login} />
<Route name="register" handler={Register} />
<Route name="chat" handler={Chat} />
<Route name="about" handler={About}/>
</Route>
Expand Down
2 changes: 2 additions & 0 deletions web/web.ex
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ defmodule Quack.Web do

# Import URL helpers from the router
import Quack.Router.Helpers

alias Quack.User
end
end

Expand Down