diff --git a/app/controllers/api_controller.rb b/app/controllers/api/v1/base_controller.rb old mode 100755 new mode 100644 similarity index 63% rename from app/controllers/api_controller.rb rename to app/controllers/api/v1/base_controller.rb index 1a38c7b0..faf8cf49 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api/v1/base_controller.rb @@ -1,4 +1,4 @@ -class ApiController < ActionController::Base +class ::Api::V1::BaseController < ActionController::Base protect_from_forgery with: :null_session before_action :authenticate_user_from_token! @@ -8,7 +8,15 @@ def authenticate_user_from_token! end end + protected + + def current_user + access_token = AccessToken.find_token(get_token) + return access_token.user + end + private + def get_token if params.key?(:access_token) return params[:access_token] @@ -22,17 +30,4 @@ def get_token def raise_unauthorized head :unauthorized end - - protected - def current_user - user = if params.key?("email") - User.find_by_email(params["email"]) - elsif params.key?("uid") - User.find_by_uid(params["uid"]) - elsif params.key?("username") - User.find_by_user_login_id(params["username"]) - end - raise_unauthorized if user.blank? - return user - end end diff --git a/app/controllers/api/v1/groups_controller.rb b/app/controllers/api/v1/groups_controller.rb new file mode 100755 index 00000000..f6ff06f1 --- /dev/null +++ b/app/controllers/api/v1/groups_controller.rb @@ -0,0 +1,18 @@ +class ::Api::V1::GroupsController < ::Api::V1::BaseController + def create + if current_user.admin? + @group = Group.new(group_params) + if @group.save + render json: { status: 'created' }, status: :ok + else + render json: { status: 'error' }, status: :unprocessable_entity + end + end + end + + private + + def group_params + params.require(:group).permit(:name) + end +end diff --git a/app/controllers/api/v1/users_controller.rb b/app/controllers/api/v1/users_controller.rb index 3811eaed..49fd7dcf 100755 --- a/app/controllers/api/v1/users_controller.rb +++ b/app/controllers/api/v1/users_controller.rb @@ -1,5 +1,6 @@ -class ::Api::V1::UsersController < ApiController - # respond_to :json, only: [:show] +class ::Api::V1::UsersController < ::Api::V1::BaseController + before_action :set_user, only: [:show, :update] + def create user = user_params if User.add_temp_user user[:name], user[:email] @@ -10,7 +11,6 @@ def create end def show - @user = current_user if @user.present? user_attrs = %w( email uid name active admin home_dir shell public_key user_login_id @@ -25,10 +25,21 @@ def show end def update - @user = current_user render json: { success: @user.update_profile(user_params) } end + private + + def set_user + @user = if params.key?("email") + User.find_by_email(params["email"]) + elsif params.key?("uid") + User.find_by_uid(params["uid"]) + elsif params.key?("username") + User.find_by_user_login_id(params["username"]) + end + end + def user_params if params.key?(:user) params.require(:user).permit(:name, :email, :public_key, :product_name) diff --git a/app/controllers/api/v1/vpns_controller.rb b/app/controllers/api/v1/vpns_controller.rb new file mode 100755 index 00000000..3c6c42c9 --- /dev/null +++ b/app/controllers/api/v1/vpns_controller.rb @@ -0,0 +1,32 @@ +class ::Api::V1::VpnsController < ::Api::V1::BaseController + before_action :set_vpn, only: [:assign_group] + + def create + if current_user.admin? + @vpn = Vpn.new(vpn_params) + if @vpn.save + render json: { status: 'created' }, status: :ok + else + render json: { status: 'error' }, status: :unprocessable_entity + end + end + end + + def assign_group + if current_user.admin? + @vpn.groups.delete_all + @vpn.groups << Group.where(id: params[:group_id]).first + render json: { status: 'group assigned' }, status: :ok + end + end + + private + + def set_vpn + @vpn = Vpn.find(params[:id]) + end + + def vpn_params + params.require(:vpn).permit(:name, :host_name, :ip_address) + end +end diff --git a/app/models/access_token.rb b/app/models/access_token.rb index 2e305b0e..e1eeb749 100644 --- a/app/models/access_token.rb +++ b/app/models/access_token.rb @@ -7,9 +7,12 @@ class AccessToken < ApplicationRecord before_save :hash_token! + def self.find_token challenge_token + AccessToken.where(hashed_token: Digest::SHA512.hexdigest(challenge_token)).first + end + def self.valid_token challenge_token - token = AccessToken.where(hashed_token: Digest::SHA512.hexdigest(challenge_token)) - return token.present? + find_token(challenge_token).present? end private diff --git a/config/routes.rb b/config/routes.rb index ef914640..4f4f13b0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -82,6 +82,13 @@ post 'users' => 'users#create', as: 'add_users_api', format: :json get 'users/profile' => 'users#show', format: :json, :constraints => { format: 'json' } post 'users/profile' => 'users#update', format: :json, :constraints => { format: 'json' } + + resources :groups, only: [:create], format: :json + resources :vpns, only: [:create], format: :json do + member do + post 'assign_group' + end + end end end diff --git a/spec/controllers/api_controller_spec.rb b/spec/controllers/api/v1/api_controller_spec.rb similarity index 84% rename from spec/controllers/api_controller_spec.rb rename to spec/controllers/api/v1/api_controller_spec.rb index 894bd03b..8362006d 100644 --- a/spec/controllers/api_controller_spec.rb +++ b/spec/controllers/api/v1/api_controller_spec.rb @@ -1,8 +1,8 @@ require 'rails_helper' -RSpec.describe ApiController, type: :controller do +RSpec.describe ::Api::V1::BaseController, type: :controller do - controller(ApiController) do + controller(::Api::V1::BaseController) do def index head :ok end diff --git a/spec/controllers/api/v1/groups_controller_spec.rb b/spec/controllers/api/v1/groups_controller_spec.rb new file mode 100755 index 00000000..a982056a --- /dev/null +++ b/spec/controllers/api/v1/groups_controller_spec.rb @@ -0,0 +1,35 @@ +require 'rails_helper' + +RSpec.describe ::Api::V1::GroupsController, type: :controller do + let(:valid_attributes) { + {name: 'jumbo'} + } + + before(:each) do + @user = build(:user) + @user.access_token = build(:access_token) + @user.save + @token = @user.access_token.token + end + + describe 'Authenticated' do + describe 'Create Group' do + context 'with valid_attributes' do + it 'should create groups' do + post :create, params: {group: valid_attributes, access_token: @token} + expect(response.status).to eq(200) + group = Group.where(name: valid_attributes[:name]).first + expect(group.blank?).to eq(false) + expect(group.name).to eq(valid_attributes[:name]) + end + end + end + end + + describe 'Unauthenticated' do + it 'gives 401 when access token is invalid' do + post :create, params: {group: valid_attributes, access_token: 'foo'} + expect(response.status).to eq(401) + end + end +end diff --git a/spec/controllers/api/v1/vpns_controller_spec.rb b/spec/controllers/api/v1/vpns_controller_spec.rb new file mode 100755 index 00000000..9981924e --- /dev/null +++ b/spec/controllers/api/v1/vpns_controller_spec.rb @@ -0,0 +1,49 @@ +require 'rails_helper' + +RSpec.describe ::Api::V1::VpnsController, type: :controller do + let(:valid_attributes) { + {name: 'jumbo'} + } + + before(:each) do + @user = build(:user) + @user.access_token = build(:access_token) + @user.save + @token = @user.access_token.token + end + + describe 'Authenticated' do + describe 'Create Vpn' do + context 'with valid_attributes' do + it 'should create vpns' do + post :create, params: {vpn: valid_attributes, access_token: @token} + expect(response.status).to eq(200) + vpn = Vpn.where(name: valid_attributes[:name]).first + expect(vpn.blank?).to eq(false) + expect(vpn.name).to eq(valid_attributes[:name]) + end + end + end + + describe 'Assign Group to VPN' do + it 'should replace existing vpn group with new group' do + vpn = create(:vpn) + group_1 = create(:group) + group_2 = create(:group) + vpn.groups << group_1 + vpn.groups << group_2 + group_3 = create(:group) + post :assign_group, params: {access_token: @token, id: vpn.id, group_id: group_3.id} + expect(vpn.groups.count).to eq 1 + expect(vpn.groups.first).to eq group_3 + end + end + end + + describe 'Unauthenticated' do + it 'gives 401 when access token is invalid' do + post :create, params: {vpn: valid_attributes, access_token: 'foo'} + expect(response.status).to eq(401) + end + end +end diff --git a/spec/models/access_token_spec.rb b/spec/models/access_token_spec.rb index d2599f8a..a512f684 100644 --- a/spec/models/access_token_spec.rb +++ b/spec/models/access_token_spec.rb @@ -17,7 +17,13 @@ @access_token.save! end - describe "self.authenticate" do + describe "self.find_token" do + it "should return access token object if it finds matching token" do + expect(AccessToken.find_token(@access_token.token)).to eq @access_token + end + end + + describe "self.valid_token" do it "should return true if it finds matching token" do expect(AccessToken.valid_token(@access_token.token)).to eq true end