diff --git a/Gemfile b/Gemfile
index a33ae6b..f636d77 100644
--- a/Gemfile
+++ b/Gemfile
@@ -23,6 +23,8 @@ gem "redis", "~> 4.0"
gem "bootsnap", require: false
+gem "rails-i18n", "~> 7.0"
+
gem "image_processing", "~> 1.2"
gem "pundit", "~> 2.2"
diff --git a/Gemfile.lock b/Gemfile.lock
index def0681..05d6373 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -249,6 +249,9 @@ GEM
ruby-graphviz (~> 1.2)
rails-html-sanitizer (1.4.3)
loofah (~> 2.3)
+ rails-i18n (7.0.5)
+ i18n (>= 0.7, < 2)
+ railties (>= 6.0.0, < 8)
railties (7.0.3.1)
actionpack (= 7.0.3.1)
activesupport (= 7.0.3.1)
@@ -357,6 +360,7 @@ DEPENDENCIES
rack-cors (~> 1.1)
rails (~> 7.0.3, >= 7.0.3.1)
rails-erd (~> 1.7)
+ rails-i18n (~> 7.0)
redis (~> 4.0)
rspec-rails (~> 5.1)
sassc-rails
diff --git a/app/admin/roles.rb b/app/admin/roles.rb
deleted file mode 100644
index 288fb6e..0000000
--- a/app/admin/roles.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-ActiveAdmin.register Role do
- permit_params :name
-end
diff --git a/app/admin/users.rb b/app/admin/users.rb
index 872ed37..b063edb 100644
--- a/app/admin/users.rb
+++ b/app/admin/users.rb
@@ -1,5 +1,5 @@
ActiveAdmin.register User do
- permit_params :email, :name, role_ids: []
+ permit_params :email, :name, roles: []
index do
selectable_column
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 09705d1..6b4dcfa 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -1,2 +1,3 @@
class ApplicationController < ActionController::Base
+ before_action :authenticate_user!
end
diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb
index e014b0d..f95f169 100644
--- a/app/controllers/users/omniauth_callbacks_controller.rb
+++ b/app/controllers/users/omniauth_callbacks_controller.rb
@@ -14,7 +14,7 @@ module Users
else
session['devise.google_data'] = request.env['omniauth.auth'].except('extra')
- redirect_to new_user_registration_url, alert: 'User not found.'
+ redirect_to new_user_session_url, alert: 'User not found.'
end
end
end
diff --git a/app/graphql/types/user_type.rb b/app/graphql/types/user_type.rb
index 93e9560..24b3209 100644
--- a/app/graphql/types/user_type.rb
+++ b/app/graphql/types/user_type.rb
@@ -9,9 +9,5 @@ module Types
field :email, String, null: false
field :roles, [Enums::RoleEnum], null: false
field :avatar_url, String, null: true
-
- def roles
- object.roles.map(&:name)
- end
end
end
diff --git a/app/javascript/components/Appbar/Appbar.tsx b/app/javascript/components/Appbar/Appbar.tsx
index 5ff9150..e8c968c 100644
--- a/app/javascript/components/Appbar/Appbar.tsx
+++ b/app/javascript/components/Appbar/Appbar.tsx
@@ -11,6 +11,7 @@ import { classNames } from '../../utils';
import { DashboardRoutePaths, QuestionRoutePaths, SessionRoutePaths } from '../../routes'
import { turnOff } from '../../services/store/unsavedChanges';
import { CurrentUserAvatar } from "../CurrentUserAvatar";
+import { localFetch } from '../../utils/localFetch';
const UserMenu: FC = () => {
const { user } = useCurrentUser();
@@ -21,8 +22,14 @@ const UserMenu: FC = () => {
const doLogout = () => {
setConfirmLogout(false)
+
dispatch(turnOff())
- history.push('/')
+
+ localFetch('/users/sign_out', {
+ method: 'DELETE'
+ }).then(() => {
+ window.location.href = '/'
+ })
}
const handleLogout = () => {
diff --git a/app/javascript/utils/localFetch.ts b/app/javascript/utils/localFetch.ts
new file mode 100644
index 0000000..36bde7e
--- /dev/null
+++ b/app/javascript/utils/localFetch.ts
@@ -0,0 +1,24 @@
+type LocalFetch = typeof fetch
+
+export const localFetch: LocalFetch = (input, init) => {
+ const { headers, ...rest } = init ?? {}
+
+ const crfsToken = document
+ .querySelector("[name='csrf-token']")
+ ?.getAttribute('content')
+
+ if (!crfsToken) {
+ throw new Error('CSRF token not found')
+ }
+
+ const customInt: RequestInit = {
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-CSRF-Token': crfsToken,
+ ...(headers ?? {}),
+ },
+ ...rest,
+ }
+
+ return fetch(input, customInt)
+}
diff --git a/app/models/role.rb b/app/models/role.rb
deleted file mode 100644
index a612a08..0000000
--- a/app/models/role.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# == Schema Information
-#
-# Table name: roles
-#
-# id :bigint not null, primary key
-# name :string
-# created_at :datetime not null
-# updated_at :datetime not null
-#
-# Indexes
-#
-# index_roles_on_name (name) UNIQUE
-#
-class Role < ApplicationRecord
- has_and_belongs_to_many :users
-
- validates :name, presence: true, uniqueness: true
-end
diff --git a/app/models/user.rb b/app/models/user.rb
index b825d38..a20c75e 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -10,6 +10,7 @@
# remember_created_at :datetime
# reset_password_sent_at :datetime
# reset_password_token :string
+# roles :string default([]), is an Array
# created_at :datetime not null
# updated_at :datetime not null
#
@@ -19,21 +20,31 @@
# index_users_on_reset_password_token (reset_password_token) UNIQUE
#
class User < ApplicationRecord
+ extend Enumerize
+
devise :database_authenticatable,
- :registerable,
:recoverable,
:rememberable,
:validatable,
:omniauthable,
omniauth_providers: [:google_oauth2]
- has_and_belongs_to_many :roles
+ enumerize :roles,
+ multiple: true,
+ default: :teacher,
+ in: %i[admin nde coordinator center_director pro_rector teacher]
validates :name, presence: true
+ roles.values.each do |role|
+ define_method "#{role}?" do
+ roles.include?(role)
+ end
+ end
+
def self.from_omniauth(email, avatar_url)
- @user = User.find_by!(email: email)
- @user.update(avatar_url: avatar_url)
- @user
+ User.find_by(email: email).tap do |user|
+ user.update(avatar_url: avatar_url) unless user.nil?
+ end
end
end
diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb
index eee630d..46a9435 100644
--- a/app/policies/application_policy.rb
+++ b/app/policies/application_policy.rb
@@ -6,7 +6,7 @@ class ApplicationPolicy
def initialize(user, record)
@user = user
@record = record
- @roles = user.roles.map { |r| r.name.to_sym }
+ @roles = user.roles
end
def is?(role)
diff --git a/config/initializers/locale.rb b/config/initializers/locale.rb
new file mode 100644
index 0000000..ba31f86
--- /dev/null
+++ b/config/initializers/locale.rb
@@ -0,0 +1 @@
+I18n.default_locale = 'pt-BR'
\ No newline at end of file
diff --git a/config/locales/activeadmin.pt-BR.yml b/config/locales/activeadmin.pt-BR.yml
new file mode 100644
index 0000000..e7bde81
--- /dev/null
+++ b/config/locales/activeadmin.pt-BR.yml
@@ -0,0 +1,143 @@
+pt-BR:
+ active_admin:
+ dashboard: "Painel Administrativo"
+ dashboard_welcome:
+ welcome: "Bem vindo ao Active Admin. Esta é a página de painéis padrão."
+ call_to_action: "Para adicionar seções ao painel, verifique 'app/admin/dashboard.rb'"
+ view: "Visualizar"
+ edit: "Editar"
+ delete: "Remover"
+ delete_confirmation: "Você tem certeza que deseja remover este item?"
+ create_another: "Criar outro %{model}"
+ new_model: "Novo(a) %{model}"
+ edit_model: "Editar %{model}"
+ delete_model: "Remover %{model}"
+ details: "Detalhes do(a) %{model}"
+ cancel: "Cancelar"
+ empty: "Vazio"
+ previous: "Anterior"
+ next: "Próximo"
+ download: "Baixar:"
+ has_many_new: "Adicionar Novo(a) %{model}"
+ has_many_delete: "Remover"
+ has_many_remove: "Remover"
+ filters:
+ buttons:
+ filter: "Filtrar"
+ clear: "Limpar Filtros"
+ predicates:
+ contains: "Contém"
+ equals: "Igual A"
+ starts_with: "Começa com"
+ ends_with: "Termina com"
+ greater_than: "Maior Que"
+ less_than: "Menor Que"
+ gteq_datetime: "Maior ou igual a"
+ lteq_datetime: "Menor ou igual a"
+ from: "A partir de"
+ to: "Até"
+ search_status:
+ headline: "Buscou:"
+ current_scope: "Em:"
+ current_filters: "Filtros escolhidos:"
+ no_current_filters: "Nenhum"
+ status_tag:
+ "yes": "Sim"
+ "no": "Não"
+ "unset": "Não"
+ main_content: "Por favor implemente %{model}#main_content para exibir conteúdo."
+ logout: "Sair"
+ powered_by: "Powered by %{active_admin} %{version}"
+ sidebars:
+ filters: "Filtros"
+ search_status: "Buscou"
+ pagination:
+ empty: "Nenhum(a) %{model} encontrado(a)"
+ one: "Exibindo 1 %{model}"
+ one_page: "Exibindo todos(as) os(as) %{n} %{model}"
+ multiple: "Exibindo %{model} %{from} - %{to} de um total de %{total}"
+ multiple_without_total: "Exibindo %{model} %{from} - %{to}"
+ per_page: "Por página: "
+ entry:
+ one: "registro"
+ other: "registros"
+ any: "Qualquer"
+ blank_slate:
+ content: "Não existem %{resource_name} ainda."
+ link: "Novo"
+ dropdown_actions:
+ button_label: "Ações"
+ batch_actions:
+ button_label: "Ações em lote"
+ default_confirmation: "Tem certeza que quer fazer isso?"
+ delete_confirmation: "Tem certeza que deseja excluir estes %{plural_model}?"
+ succesfully_destroyed:
+ one: "Excluiu com sucesso 1 %{model}"
+ other: "Excluiu com sucesso %{count} %{plural_model}"
+ selection_toggle_explanation: "(Alternar Seleção)"
+ action_label: "%{title} Selecionado"
+ labels:
+ destroy: "Excluir"
+ comments:
+ created_at: "Criado em"
+ resource_type: "Tipo de Objeto"
+ author_type: "Tipo de Autor"
+ body: "Conteúdo"
+ author: "Autor"
+ add: "Adicionar Comentário"
+ delete: "Deletar comentário"
+ delete_confirmation: "Tem certeza que deseja excluir este comentário?"
+ resource: "Objeto"
+ no_comments_yet: "Nenhum comentário."
+ author_missing: "Anônimo"
+ title_content: "Comentários: %{count}"
+ errors:
+ empty_text: "O comentário não foi salvo porque o texto estava vazio."
+ devise:
+ username:
+ title: "Nome de Usuário"
+ email:
+ title: "E-mail"
+ subdomain:
+ title: "Subdomínio"
+ password:
+ title: "Senha"
+ password_confirmation:
+ title: "Confirmação de senha"
+ sign_up:
+ title: "Cadastre-se"
+ submit: "Continuar"
+ login:
+ title: "Conta"
+ remember_me: "Lembrar da senha"
+ submit: "Entrar"
+ reset_password:
+ title: "Esqueceu sua senha?"
+ submit: "Reinicie minha senha"
+ change_password:
+ title: "Troque sua senha"
+ submit: "Troque minha senha"
+ unlock:
+ title: "Reenviar instruções de desbloqueio"
+ submit: "Reenviar instruções de desbloqueio"
+ resend_confirmation_instructions:
+ title: "Reenviar instruções de confirmação"
+ submit: "Reenviar instruções de confirmação"
+ links:
+ sign_up: "Criar conta"
+ sign_in: "Entrar"
+ forgot_your_password: "Esqueceu sua senha?"
+ sign_in_with_omniauth_provider: "Entre com o %{provider}"
+ resend_unlock_instructions: "Reenviar instruções de desbloqueio"
+ resend_confirmation_instructions: "Reenviar instruções de confirmação"
+ unsupported_browser:
+ headline: "O ActiveAdmin não oferece suporte ao Internet Explorer versão 8 ou inferior."
+ recommendation: "Nós recomendamos atualizar para a última versão do Internet Explorer, Google Chrome, ou Firefox."
+ turn_off_compatibility_view: "Se você está usando o IE 9 ou superior, desligue o \"Modo de Exibição de Compatibilidade\"."
+ access_denied:
+ message: "Você não tem permissão para realizar o solicitado"
+ index_list:
+ table: "Tabela"
+ block: "Lista"
+ grid: "Grid"
+ blog: "Blog"
\ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index d9cf4bf..d2c385d 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -10,7 +10,11 @@ Rails.application.routes.draw do
post "/graphql", to: "graphql#execute"
- ActiveAdmin.routes(self)
+
+ authenticate :user, ->(u) { u.admin? } do
+ ActiveAdmin.routes(self)
+ end
+
if Rails.env.development?
mount GraphqlPlayground::Rails::Engine, at: "/playground", graphql_path: "/graphql"
diff --git a/db/migrate/20220725224431_add_roles_to_user.rb b/db/migrate/20220725224431_add_roles_to_user.rb
new file mode 100644
index 0000000..ac81403
--- /dev/null
+++ b/db/migrate/20220725224431_add_roles_to_user.rb
@@ -0,0 +1,5 @@
+class AddRolesToUser < ActiveRecord::Migration[7.0]
+ def change
+ add_column(:users, :roles, :string, array: true, null: true, default: [])
+ end
+end
diff --git a/db/migrate/20220725225343_drop_roles.rb b/db/migrate/20220725225343_drop_roles.rb
new file mode 100644
index 0000000..3760387
--- /dev/null
+++ b/db/migrate/20220725225343_drop_roles.rb
@@ -0,0 +1,5 @@
+class DropRoles < ActiveRecord::Migration[7.0]
+ def change
+ drop_table :roles
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index f622139..00eeb43 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.0].define(version: 2022_07_22_153417) do
+ActiveRecord::Schema[7.0].define(version: 2022_07_25_225343) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -118,13 +118,6 @@ ActiveRecord::Schema[7.0].define(version: 2022_07_22_153417) do
t.index ["user_id"], name: "index_review_requests_on_user_id"
end
- create_table "roles", force: :cascade do |t|
- t.string "name"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["name"], name: "index_roles_on_name", unique: true
- end
-
create_table "roles_users", id: false, force: :cascade do |t|
t.bigint "user_id", null: false
t.bigint "role_id", null: false
@@ -153,6 +146,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_07_22_153417) do
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "avatar_url"
+ t.string "roles", default: [], array: true
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
diff --git a/spec/factories/roles.rb b/spec/factories/roles.rb
deleted file mode 100644
index d06efc0..0000000
--- a/spec/factories/roles.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# == Schema Information
-#
-# Table name: roles
-#
-# id :bigint not null, primary key
-# name :string
-# created_at :datetime not null
-# updated_at :datetime not null
-#
-# Indexes
-#
-# index_roles_on_name (name) UNIQUE
-#
-FactoryBot.define do
- factory :role do
-
- end
-end
diff --git a/spec/factories/users.rb b/spec/factories/users.rb
index 62ad826..bbddcec 100644
--- a/spec/factories/users.rb
+++ b/spec/factories/users.rb
@@ -10,6 +10,7 @@
# remember_created_at :datetime
# reset_password_sent_at :datetime
# reset_password_token :string
+# roles :string default([]), is an Array
# created_at :datetime not null
# updated_at :datetime not null
#
diff --git a/spec/models/role_spec.rb b/spec/models/role_spec.rb
deleted file mode 100644
index 6f65c40..0000000
--- a/spec/models/role_spec.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# == Schema Information
-#
-# Table name: roles
-#
-# id :bigint not null, primary key
-# name :string
-# created_at :datetime not null
-# updated_at :datetime not null
-#
-# Indexes
-#
-# index_roles_on_name (name) UNIQUE
-#
-require 'rails_helper'
-
-RSpec.describe Role, type: :model do
- pending "add some examples to (or delete) #{__FILE__}"
-end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index b150fb6..3daa4a6 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -10,6 +10,7 @@
# remember_created_at :datetime
# reset_password_sent_at :datetime
# reset_password_token :string
+# roles :string default([]), is an Array
# created_at :datetime not null
# updated_at :datetime not null
#