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

Users and favorites #46

Open
wants to merge 25 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
9e9e918
Add request testing for new user creation.
Gallup93 Oct 13, 2020
007d00f
Add gem 'bcrypt'
Gallup93 Oct 13, 2020
04dd82f
Add migration for password_digest on User model
Gallup93 Oct 13, 2020
be9ff8a
Update User factory to include password_digest
Gallup93 Oct 13, 2020
0a74da6
Update User model validations with uniqueness for email and Add passw…
Gallup93 Oct 13, 2020
0f5ac37
Add passwordDigest to user_type.rb
Gallup93 Oct 13, 2020
9c9983f
Add field: create_user mutation to mutation_type.rb
Gallup93 Oct 13, 2020
ffaa63f
Add create_user mutation
Gallup93 Oct 13, 2020
6431b1c
Refactor testing to account for updates made to favorites functionality
Gallup93 Oct 14, 2020
749249e
Add model test to 'favorites' joins table
Gallup93 Oct 14, 2020
dca6143
Create 'favorites' table in db
Gallup93 Oct 14, 2020
1864b02
Add user Model, Update model relationships to account for 'favorites'
Gallup93 Oct 14, 2020
38dab15
Add GraphQL type for Favorite
Gallup93 Oct 14, 2020
20183ad
Refactor favorite street art mutation
Gallup93 Oct 14, 2020
6db24b5
Refactor create street art mutation
Gallup93 Oct 14, 2020
434068e
Remove passwordDigest from user type
Gallup93 Oct 16, 2020
8bb4e4f
Add Type for AuthProviderCredentialsInput
Gallup93 Oct 16, 2020
daf3762
Refactor create_user mutation for user authentication
Gallup93 Oct 16, 2020
9247e32
Refactor testing query for user creation
Gallup93 Oct 16, 2020
1cd9c92
Add test for signing in a user
Gallup93 Nov 16, 2020
dc30158
Add mutation for signing in a user
Gallup93 Nov 16, 2020
328e290
Add mutation type for signing in a user
Gallup93 Nov 16, 2020
b22d3ec
Add JWT gem to gemfile
Gallup93 Nov 16, 2020
ab512b1
Add class for JSON Web Token authentication functionality
Gallup93 Nov 16, 2020
40a386b
Implement actual JWT functionality to the SignInUser mutation
Gallup93 Nov 16, 2020
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
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ gem 'coffee-rails'
gem 'travis'
gem 'faker'
gem 'factory_bot_rails'
gem 'bcrypt'
gem 'jwt'

group :development, :test do
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
Expand Down
4 changes: 4 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ GEM
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
arel (8.0.0)
bcrypt (3.1.16)
builder (3.2.4)
byebug (11.1.3)
coderay (1.1.3)
Expand Down Expand Up @@ -91,6 +92,7 @@ GEM
i18n (1.8.5)
concurrent-ruby (~> 1.0)
json (2.3.1)
jwt (2.2.2)
launchy (2.4.3)
addressable (~> 2.3)
listen (3.1.5)
Expand Down Expand Up @@ -226,6 +228,7 @@ PLATFORMS
ruby

DEPENDENCIES
bcrypt
byebug
coffee-rails
factory_bot_rails
Expand All @@ -234,6 +237,7 @@ DEPENDENCIES
figaro
graphiql-rails
graphql
jwt
listen (>= 3.0.5, < 3.2)
pg
pry
Expand Down
27 changes: 14 additions & 13 deletions app/graphql/mutations/create_street_art.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,19 @@ def resolve(latitude: nil, longitude: nil, address: nil, city: nil, state: nil,
zipcode: nil, image_urls:, description: nil, artist_name: nil, art_name: nil,
instagram_handle: nil, favorite: false, visited: false, user_id:)

User.find(user_id).street_arts.create!(latitude: latitude,
longitude: longitude,
address: address,
city: city,
state: state,
zipcode: zipcode,
image_urls: image_urls,
description: description,
artist_name: artist_name,
art_name: art_name,
instagram_handle: instagram_handle,
favorite: favorite,
visited: visited)
StreetArt.create(latitude: latitude,
longitude: longitude,
address: address,
city: city,
state: state,
zipcode: zipcode,
image_urls: image_urls,
description: description,
artist_name: artist_name,
art_name: art_name,
instagram_handle: instagram_handle,
favorite: favorite,
visited: visited,
user_id: user_id)
end
end
18 changes: 18 additions & 0 deletions app/graphql/mutations/create_user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class Mutations::CreateUser < Mutations::BaseMutation
class AuthProviderSignupData < Types::BaseInputObject
argument :credentials, Types::AuthProviderCredentialsInput, required: false
end

argument :username, String, required: true
argument :auth_provider, AuthProviderSignupData, required: false

type Types::UserType

def resolve(username: nil, auth_provider: nil)
User.create!(
username: username,
email: auth_provider&.[](:credentials)&.[](:email),
password: auth_provider&.[](:credentials)&.[](:password)
)
end
end
10 changes: 4 additions & 6 deletions app/graphql/mutations/favorite_street_art.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
class Mutations::FavoriteStreetArt < Mutations::BaseMutation
argument :favorite, Boolean, required: true
argument :user_id, Integer, required: true
argument :street_art_id, Integer, required: true

type Types::StreetArtType
type Types::FavoriteType

def resolve(favorite: ,street_art_id:)
art = StreetArt.find(street_art_id)
art.update(favorite: favorite)
art.reload
def resolve(user_id:, street_art_id:)
Favorite.create(user_id: user_id, street_art_id: street_art_id)
end
end
21 changes: 21 additions & 0 deletions app/graphql/mutations/sign_in_user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class Mutations::SignInUser < Mutations::BaseMutation
null true

argument :credentials, Types::AuthProviderCredentialsInput, required: false

field :token, String, null: true
field :user, Types::UserType, null: true

def resolve(credentials: nil)
return unless credentials

user = User.find_by email: credentials[:email]

return unless user
return unless user.authenticate(credentials[:password])

token = JsonWebToken.encode(user_id: user.id)

{user: user, token: token}
end
end
8 changes: 8 additions & 0 deletions app/graphql/types/auth_provider_credentials_input.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module Types
class AuthProviderCredentialsInput < BaseInputObject
graphql_name 'AUTH_PROVIDER_CREDENTIALS'

argument :email, String, required: true
argument :password, String, required: true
end
end
7 changes: 7 additions & 0 deletions app/graphql/types/favorite_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module Types
class FavoriteType < Types::BaseObject
field :id, ID, null: false
field :user_id, Integer, null: false
field :street_art_id, Integer, null: false
end
end
2 changes: 2 additions & 0 deletions app/graphql/types/mutation_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@ class MutationType < Types::BaseObject
field :create_street_art, mutation: Mutations::CreateStreetArt
field :favorite_street_art, mutation: Mutations::FavoriteStreetArt
field :visit_street_art, mutation: Mutations::VisitStreetArt
field :create_user, mutation: Mutations::CreateUser
field :signin_user, mutation: Mutations::SignInUser
end
end
4 changes: 4 additions & 0 deletions app/models/favorite.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class Favorite < ApplicationRecord
belongs_to :user
belongs_to :street_art
end
2 changes: 2 additions & 0 deletions app/models/street_art.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
class StreetArt < ApplicationRecord
before_save :validate_location
belongs_to :user
has_many :favorites
has_many :users, through: :favorites
# serialize :image_urls, Array
validates_presence_of :image_urls

Expand Down
7 changes: 6 additions & 1 deletion app/models/user.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
class User < ApplicationRecord
has_many :street_arts
has_many :favorites

validates_presence_of :username
validates_presence_of :email
validates :email, uniqueness: true, presence: true
validates_presence_of :password_digest, require: true

has_secure_password
end
36 changes: 36 additions & 0 deletions app/poro/json_web_token.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require 'jwt'

class JsonWebToken
# Encodes and signs the payload
def self.encode(payload)
payload.reverse_merge!(meta)
JWT.encode(payload, Rails.application.secrets.secret_key_base)
end

# Decode the JWT to get the user email
def self.decode(token)
JWT.decode(token, Rails.application.secrets.secret_key_base)
end

# Validates the payload hash for expiration and meta claims
def self.valid_payload(payload)
if expired(payload) || payload['iss'] != meta[:iss]
return false
else
return true
end
end

# Default options to be encoded in the token
def self.meta
{
exp: 7.days.from_now.to_i,
iss: 'Street Art Walk'
}
end

# Validates if the token is expired by exp parameter
def self.expired(payload)
Time.at(payload['exp']) < Time.now
end
end
5 changes: 5 additions & 0 deletions db/migrate/20201013221506_add_password_to_users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddPasswordToUsers < ActiveRecord::Migration[5.1]
def change
add_column :users, :password_digest, :string
end
end
10 changes: 10 additions & 0 deletions db/migrate/20201014051754_create_favorites.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class CreateFavorites < ActiveRecord::Migration[5.1]
def change
create_table :favorites do |t|
t.references :user, foreign_key: true
t.references :street_art, foreign_key: true

t.timestamps
end
end
end
14 changes: 13 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,20 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20200903215738) do
ActiveRecord::Schema.define(version: 20201014051754) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

create_table "favorites", force: :cascade do |t|
t.bigint "user_id"
t.bigint "street_art_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["street_art_id"], name: "index_favorites_on_street_art_id"
t.index ["user_id"], name: "index_favorites_on_user_id"
end

create_table "street_arts", force: :cascade do |t|
t.string "latitude"
t.string "longitude"
Expand All @@ -40,7 +49,10 @@
t.string "email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "password_digest"
end

add_foreign_key "favorites", "street_arts"
add_foreign_key "favorites", "users"
add_foreign_key "street_arts", "users"
end
1 change: 1 addition & 0 deletions spec/factories/street_art.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
image_urls {[ Faker::Fillmurray.image, Faker::Fillmurray.image, Faker::Fillmurray.image ]}
description { Faker::Movies::StarWars.quote }
artist_name { Faker::Artist.name }
user_id {User.last.id}
end
end
1 change: 1 addition & 0 deletions spec/factories/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
factory :user do
username { Faker::Movies::LordOfTheRings.character }
email { Faker::Internet.email }
password_digest { Faker::Internet.password }
end
end
8 changes: 8 additions & 0 deletions spec/models/favorite_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
require 'rails_helper'

RSpec.describe Favorite, type: :model do
describe 'relationships' do
it { should belong_to :user }
it { should belong_to :street_art }
end
end
Loading