From 425939bc7d49436dea66dcb88fce2e22ad6e64e4 Mon Sep 17 00:00:00 2001 From: realtradam Date: Sun, 14 Apr 2024 21:53:27 -0400 Subject: implement basic authflow with github --- .gitignore | 3 + app/controllers/api/v1/auth_controller.rb | 86 +++++++++++++++++++++++++ app/controllers/homepage_controller.rb | 1 + app/javascript/components/App.jsx | 5 +- app/javascript/routes/index.jsx | 32 ++++++--- config/application.rb | 8 +++ config/routes.rb | 3 + test/controllers/api/v1/auth_controller_test.rb | 7 ++ 8 files changed, 135 insertions(+), 10 deletions(-) create mode 100644 app/controllers/api/v1/auth_controller.rb create mode 100644 test/controllers/api/v1/auth_controller_test.rb diff --git a/.gitignore b/.gitignore index 288c5a2..c5920e9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,9 @@ # or operating system, you probably want to add a global ignore instead: # git config --global core.excludesfile '~/.gitignore_global' +# Ignore secrets +/config/local_env.yml + # Ignore bundler config. /.bundle diff --git a/app/controllers/api/v1/auth_controller.rb b/app/controllers/api/v1/auth_controller.rb new file mode 100644 index 0000000..2688074 --- /dev/null +++ b/app/controllers/api/v1/auth_controller.rb @@ -0,0 +1,86 @@ +require 'net/http' +class Api::V1::AuthController < ApplicationController + class << self + def user_table + @user_table ||= {} + end + end + def data + if !cookies[:session].nil? + puts cookies[:session] + render json: Api::V1::AuthController.user_table[cookies[:session]] + else + puts "Not logged in" + end + end + def callback + # user logs in through github + # github redirects them to this endpoint with the token in the url as query params + # we need to use this token to exchange with github for user info(i.e username) + puts "Code: #{params[:code]}" # this is the github token + puts ENV["GITHUB_CLIENT_SECRET"] + puts ENV["GITHUB_CLIENT_ID"] + access_token = get_access_token(params[:code]) + user_data = get_github_user_data(access_token) + puts "USER DATA:" + pp user_data + token = "#{user_data['id']}" + hashed_token = OpenSSL::HMAC.hexdigest(ENV["ENC_ALGO"], ENV["ENC_KEY"], token + access_token) + Api::V1::AuthController.user_table[hashed_token] = user_data + puts "Hashed Token: #{hashed_token}" + cookies[:session] = hashed_token + redirect_to '/' + end + + private + + def get_github_user_data(access_token) + uri = URI("https://api.github.com/user") + headers = { Authorization: "Bearer #{access_token}" } + response = Net::HTTP.get( + uri, + headers + ) + puts "Response Body" + puts response + #if response.is_a?(Net::HTTPSuccess) + #if response.body.nil? + result = response + if !result["error"].nil? + puts "Error: #{result["error"]}" + puts response + # we had an error + # TODO + else + puts "huh?" if result.nil? + return result + end + #else + # puts "Error(body nil)" + # something went wrong? + # TODO + #end + end + + def get_access_token(github_user_code) + uri = URI("https://github.com/login/oauth/access_token?client_id=#{ENV["GITHUB_CLIENT_ID"]}&client_secret=#{ENV["GITHUB_CLIENT_SECRET"]}&code=#{github_user_code}") + #uri = URI('https://github.com/login/oauth/access_token') + headers = {Accept: 'application/json'} + response = Net::HTTP.post( + uri, + nil, + headers + ) + if response.is_a?(Net::HTTPSuccess) + result = JSON.parse(response.body) + if !result["error"].nil? + # we had an error + else + return result["access_token"] + end + else + # something went wrong? + # TODO + end + end +end diff --git a/app/controllers/homepage_controller.rb b/app/controllers/homepage_controller.rb index e09cc6e..70e3b11 100644 --- a/app/controllers/homepage_controller.rb +++ b/app/controllers/homepage_controller.rb @@ -1,4 +1,5 @@ class HomepageController < ApplicationController def index + puts params end end diff --git a/app/javascript/components/App.jsx b/app/javascript/components/App.jsx index 6d7a0c7..da6a873 100644 --- a/app/javascript/components/App.jsx +++ b/app/javascript/components/App.jsx @@ -1,4 +1,7 @@ import React from "react"; import Routes from "../routes"; -export default props => <>{Routes}; +export default (props) => { + return (); +} + diff --git a/app/javascript/routes/index.jsx b/app/javascript/routes/index.jsx index ac0f9ae..be928fc 100644 --- a/app/javascript/routes/index.jsx +++ b/app/javascript/routes/index.jsx @@ -1,13 +1,27 @@ -import React from "react"; +import React, { useState, useEffect } from "react"; import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; import Home from "../components/Home"; import Blogs from "../components/Blogs"; -export default ( - - - } /> - } /> - - -); +export default function index() +{ + const [userData, setUserData] = useState({ login: "" }); + const url = "/api/v1/auth/data"; + fetch(url).then((response) => { + if(response.ok) { + return response.json(); + } + throw new Error("Network response was not ok."); + }).then((response) => setUserData(response)); + // get user data here + // then pass it in as 'props' into the components + return (<> +

{userData.login}

+ + + } /> + } /> + + + ); +} diff --git a/config/application.rb b/config/application.rb index e1c1688..64e1c89 100644 --- a/config/application.rb +++ b/config/application.rb @@ -23,5 +23,13 @@ module GamesHost # # config.time_zone = "Central Time (US & Canada)" # config.eager_load_paths << Rails.root.join("extras") + config.before_configuration do + env_file = File.join(Rails.root, 'config', 'local_env.yml') + if File.exist?(env_file) + YAML.load(File.open(env_file)).each do |key, value| + ENV[key.to_s] = value + end + end + end end end diff --git a/config/routes.rb b/config/routes.rb index 5025b1b..d164474 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -5,6 +5,9 @@ Rails.application.routes.draw do post 'blogs/create', to: 'blog#create' get '/show/:id', to: 'blog#show' delete '/destroy/:id', to: 'blog#destroy' + + get 'auth/callback', to: 'auth#callback' + get 'auth/data', to: 'auth#data' end end root 'homepage#index' diff --git a/test/controllers/api/v1/auth_controller_test.rb b/test/controllers/api/v1/auth_controller_test.rb new file mode 100644 index 0000000..3a6d312 --- /dev/null +++ b/test/controllers/api/v1/auth_controller_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class Api::V1::AuthControllerTest < ActionDispatch::IntegrationTest + # test "the truth" do + # assert true + # end +end -- cgit v1.2.3