Merge branch 'next-minor' into develop

This commit is contained in:
Benjamin Neff 2019-05-12 00:25:52 +02:00
commit 314239ff2a
No known key found for this signature in database
GPG key ID: 971464C3F1A90194
27 changed files with 197 additions and 96 deletions

1
.gitignore vendored
View file

@ -11,7 +11,6 @@ app/assets/images/custom/
# Configuration files
config/diaspora.yml
config/initializers/secret_token.rb
config/initializers/twofa_encryption_key.rb
.bundle
vendor/bundle/
vendor/cache/

View file

@ -20,6 +20,8 @@
## Bug fixes
## Features
* Add line mentioning diaspora\* on the splash page [#7966](https://github.com/diaspora/diaspora/pull/7966)
* Improve communication about signing up on closed pods [#7896](https://github.com/diaspora/diaspora/pull/7896)
# 0.7.11.0
@ -27,6 +29,9 @@
* Enable paranoid mode for devise [#8003](https://github.com/diaspora/diaspora/pull/8003)
* Refactor likes cucumber test [#8002](https://github.com/diaspora/diaspora/pull/8002)
## Bug fixes
* Fix old photos without remote url for export [#8012](https://github.com/diaspora/diaspora/pull/8012)
## Features
* Add a manifest.json file as a first step to make diaspora\* a Progressive Web App [#7998](https://github.com/diaspora/diaspora/pull/7998)
* Allow `web+diaspora://` links to link to a profile with only the diaspora ID [#8000](https://github.com/diaspora/diaspora/pull/8000)

View file

@ -42,6 +42,14 @@
padding: 15px;
}
.part-of-diaspora {
font-style: italic;
a {
color: $white;
}
}
.login-form {
fieldset { background: none; }

View file

@ -1,5 +1,4 @@
.page-registrations.action-new,
.page-registrations.action-create {
.page-registrations {
.ball {
background: image-url('branding/ball.png') no-repeat;
background-size: contain;
@ -12,19 +11,24 @@
height: 633px;
}
@media (max-width: $screen-xs-max) {
.v-center {
height: auto;
}
}
.content {
display: table-cell;
vertical-align: middle;
h2 {
h1 {
font-size: 35px;
margin: 12px;
text-align: center;
margin: 12px 0;
}
}
form {
max-width: 400px;
max-width: 500px;
}
.captcha-img {

View file

@ -5,9 +5,9 @@
# the COPYRIGHT file.
class RegistrationsController < Devise::RegistrationsController
before_action :check_registrations_open_or_valid_invite!
before_action :check_registrations_open_or_valid_invite!, except: :registrations_closed
layout -> { request.format == :mobile ? "application" : "with_header" }
layout -> { request.format == :mobile ? "application" : "with_header_with_footer" }
def create
@user = User.build(user_params)
@ -28,13 +28,17 @@ class RegistrationsController < Devise::RegistrationsController
end
end
def registrations_closed
render "registrations/registrations_closed"
end
private
def check_registrations_open_or_valid_invite!
return true if AppConfig.settings.enable_registrations? || invite.try(:can_be_used?)
flash[:error] = params[:invite] ? t("registrations.invalid_invite") : t("registrations.closed")
redirect_to new_user_session_path
flash[:error] = t("registrations.invalid_invite") if params[:invite]
redirect_to registrations_closed_path
end
def invite

View file

@ -19,11 +19,10 @@ class User < ApplicationRecord
scope :halfyear_actives, ->(time = Time.now) { logged_in_since(time - 6.month) }
scope :active, -> { joins(:person).where(people: {closed_account: false}) }
attribute :otp_secret
attr_encrypted :otp_secret, if: false, prefix: "plain_"
devise :two_factor_authenticatable,
:two_factor_backupable,
otp_secret_encryption_key: AppConfig.twofa_encryption_key,
otp_backup_code_length: 16,
otp_number_of_backup_codes: 10

View file

@ -4,6 +4,10 @@
.row
.col-md-8.text-center
%h1= t("home.default.headline", pod_name: pod_name)
- if pod_name != "diaspora*"
%h2.part-of-diaspora
!= t("home.default.part_of_diaspora",
diaspora_site_link: link_to(t("home.default.diaspora_site_link"), "https://diasporafoundation.org/"))
%h2= t("home.default.byline")
.col-md-4.login-form
= render partial: "sessions/form", locals: {mobile: false, resource: User.new, resource_name: :user}

View file

@ -1,5 +1,5 @@
%ul.nav.navbar-nav.navbar-right
- if AppConfig.settings.enable_registrations? && !current_page?(controller: "/registrations", action: :new)
- unless current_page?(controller: "/registrations", action: :new)
%li= link_to t("devise.shared.links.sign_up"), new_user_registration_path, class: "login"
- unless current_page?(controller: "/sessions", action: :new)
%li= link_to t("devise.shared.links.sign_in"), new_user_session_path, class: "login"

View file

@ -4,7 +4,7 @@
- if mobile
%legend
= image_tag("branding/logos/header-logo2x.png", height: 40, width: 40)
= t("aspects.aspect_stream.make_something")
= AppConfig.settings.pod_name
- if mobile
= f.label :email, t("registrations.new.email"), class: "control-label", id: "emailLabel"

View file

@ -0,0 +1,11 @@
%h2
= t("devise.shared.links.sign_up_closed")
!= t("registrations.closed.closed_pod",
wiki: link_to(t("registrations.closed.another_pod"), "https://diasporafoundation.org/getting_started/sign_up"))
!= t("registrations.closed.find_pods",
poduptime: link_to("Poduptime", "https://podupti.me/"))
!= t("registrations.closed.other_questions",
wiki: link_to("Wiki", "https://wiki.diasporafoundation.org/Choosing_a_pod"))

View file

@ -1,12 +1,11 @@
#registration
.container
.row
.col-md-10.offset1
.col-md-7.hidden-phone
%h1.ball
.col-md-5.v-center
.content.text-center
%h2#pod-name
= AppConfig.settings.pod_name
.col-sm-6.hidden-xs
.ball
.col-sm-6.col-xs-12.v-center
.content.text-center
%h1#pod-name
= AppConfig.settings.pod_name
= render partial: "form", locals: {mobile: false}
= render partial: "form", locals: {mobile: false}

View file

@ -0,0 +1,8 @@
#registration
.container
.row
.col-sm-6.hidden-xs
.ball
.col-sm-6.col-xs-12.v-center
.content
= render partial: "registrations_closed"

View file

@ -0,0 +1,10 @@
.stream#main-stream
- flash.each do |name, msg|
.expose#flash-container
.flash-message{class: "message alert alert-#{flash_class name}", role: "alert"}
= msg
.login-form
.login-container
= render partial: "registrations_closed"

View file

@ -553,6 +553,8 @@ en:
home:
default:
headline: "Welcome to %{pod_name}"
part_of_diaspora: "Part of the %{diaspora_site_link}"
diaspora_site_link: "diaspora* federated network"
byline: "The online social world where you are in control"
be_who_you_want_to_be: "Be who you want to be"
be_who_you_want_to_be_info: "A lot of networks insist that you use your real identity. Not diaspora*. Here you can choose who you want to be, and share as much or as little about yourself as you want. It really is up to you how you want to interact with other people."
@ -1050,7 +1052,11 @@ en:
terms_link: "terms of service"
create:
success: "Youve joined diaspora*!"
closed: "Signups are closed on this diaspora* pod."
closed:
closed_pod: "This pod is currently closed to new registrations. However, you can still join the diaspora* network by registering on %{wiki}. Because all pods are interconnected, you will have access to the same content there."
another_pod: "another pod"
find_pods: "Theres a list of pods you can sign up to at %{poduptime}."
other_questions: "If you have any other questions regarding choosing a pod, check out our %{wiki}."
invalid_invite: "The invite link you provided is no longer valid!"
reshares:

View file

@ -129,6 +129,7 @@ Rails.application.routes.draw do
devise_scope :user do
get "/users/sign_up" => "registrations#new", :as => :new_user_registration
post "/users" => "registrations#create", :as => :user_registration
get "/registrations_closed" => "registrations#registrations_closed", :as => :registrations_closed
end
get "users/invitations" => "invitations#new", :as => "new_user_invitation"

View file

@ -2,10 +2,12 @@
class AddDeviseTwoFactorToUsers < ActiveRecord::Migration[5.1]
def change
add_column :users, :encrypted_otp_secret, :string
add_column :users, :encrypted_otp_secret_iv, :string
add_column :users, :encrypted_otp_secret_salt, :string
add_column :users, :consumed_timestep, :integer
add_column :users, :otp_required_for_login, :boolean
change_table :users, bulk: true do |t|
t.string :encrypted_otp_secret
t.string :encrypted_otp_secret_iv
t.string :encrypted_otp_secret_salt
t.integer :consumed_timestep
t.boolean :otp_required_for_login
end
end
end

View file

@ -0,0 +1,11 @@
# frozen_string_literal: true
class FixMissingRemotePhotoFields < ActiveRecord::Migration[5.1]
def up
Photo.where(remote_photo_path: nil).each do |photo|
photo.write_attribute(:unprocessed_image, photo.read_attribute(:processed_image))
photo.update_remote_path
photo.save!
end
end
end

View file

@ -0,0 +1,52 @@
# frozen_string_literal: true
class DecryptTwoFactorSecret < ActiveRecord::Migration[5.1]
class User < ApplicationRecord
end
def up
add_column :users, :plain_otp_secret, :string
key = twofa_encryption_key
decrypt_existing_secrets(key) if key
change_table :users, bulk: true do |t|
t.remove :encrypted_otp_secret
t.remove :encrypted_otp_secret_iv
t.remove :encrypted_otp_secret_salt
end
end
def down
raise ActiveRecord::IrreversibleMigration
end
private
def twofa_encryption_key
if AppConfig.heroku?
ENV["TWOFA_ENCRYPTION_KEY"]
else
key_file = File.expand_path("../../config/initializers/twofa_encryption_key.rb", File.dirname(__FILE__))
if File.exist? key_file
require key_file
File.delete(key_file)
return Diaspora::Application.config.twofa_encryption_key
end
end
end
def decrypt_existing_secrets(key)
User.where.not(encrypted_otp_secret: nil).each do |user|
user.plain_otp_secret = Encryptor.decrypt(
value: user.encrypted_otp_secret.unpack("m").first,
key: key,
iv: user.encrypted_otp_secret_iv.unpack("m").first,
salt: user.encrypted_otp_secret_salt.slice(1..-1).unpack("m").first
)
user.save!
end
end
end

View file

@ -98,11 +98,11 @@ Feature: new user registration
Then I should not be able to sign up
And I should have a validation error on "user_password, user_password_confirmation"
Scenario: User signs up with an already existing username and email and then tries to sign in (Issue #6136)
Scenario: User signs up with an already existing username and email and then tries to sign in
When I log out manually
And I go to the new user registration page
And I fill in the new user form with an existing email and username
And I fill in the new user form
And I submit the form
Then I should see a flash message indicating failure
When I click the sign in button
When I follow "Sign in"
Then I should not see a flash message indicating failure

View file

@ -0,0 +1,24 @@
@javascript
Feature: New user registration
In order to use Diaspora*
As a desktop user
I want to register an account
Scenario: user signs up and goes to getting started
Given I am on the new user registration page
When I fill in the new user form
And I press "Create account"
Then I should be on the getting started page
And I should see the 'getting started' contents
Scenario: registrations are closed, user is informed
Given the registrations are closed
When I am on the new user registration page
Then I should see "Open signups are closed at this time"
Scenario: User is unable to register even by manually sending the POST request
Given I am on the new user registration page
When I fill in the new user form
Given the registrations are closed
When I press "Create account"
Then I should see "Open signups are closed at this time"

View file

@ -5,8 +5,7 @@ Feature: New user registration
I want to register an account
Background:
Given I am on the login page
And I follow "Create account" within "#main-nav"
Given I am on the new user registration page
Scenario: user signs up and goes to getting started
When I fill in the new user form

View file

@ -74,3 +74,11 @@ end
Then (/^I should see the 'getting started' contents$/) do
confirm_getting_started_contents
end
Given /^the registrations are closed$/ do
AppConfig.settings.enable_registrations = false
end
When /^I fill in the new user form$/ do
fill_in_new_user_form
end

View file

@ -218,20 +218,12 @@ When /^I view "([^\"]*)"'s first post$/ do |email|
visit post_path(post)
end
When /^I fill in the new user form/ do
fill_in_new_user_form
end
And /^I should be able to friend "([^\"]*)"$/ do |email|
user = User.find_by_email(email)
step 'I should see a ".aspect-dropdown"'
step "I should see \"#{user.name}\""
end
When /^I click the sign in button$/ do
click_link "Sign in"
end
Given /^I did request my photos$/ do
@me.perform_export_photos!
end

View file

@ -68,24 +68,6 @@ module Configuration
end
end
def twofa_encryption_key
if heroku?
return ENV["TWOFA_ENCRYPTION_KEY"] if ENV["TWOFA_ENCRYPTION_KEY"]
warn "FATAL: Running on Heroku with TWOFA_ENCRYPTION_KEY unset"
warn " Run heroku config:add TWOFA_ENCRYPTION_KEY=#{SecureRandom.hex(32)}"
abort
else
key_file = File.expand_path(
"../config/initializers/twofa_encryption_key.rb",
File.dirname(__FILE__)
)
system "DISABLE_SPRING=1 bin/rake generate:twofa_key" unless File.exist? key_file
require key_file
Diaspora::Application.config.twofa_encryption_key
end
end
def version_string
return @version_string unless @version_string.nil?

View file

@ -1,24 +0,0 @@
# frozen_string_literal: true
namespace :generate do
desc "Generates a key for encrypting 2fa tokens"
task :twofa_key do
path = Rails.root.join("config", "initializers", "twofa_encryption_key.rb")
key = SecureRandom.hex(32)
File.open(path, "w") do |f|
f.write <<~CONF
# frozen_string_literal: true
# The 2fa encryption key is used to encrypt users' OTP tokens in the database.
# You can regenerate this key by running `rake generate:twofa_key`
# If you change this key after a user has set up 2fa
# the users' tokens cannot be recovered
# and they will not be able to log in again!
Diaspora::Application.config.twofa_encryption_key = "#{key}"
CONF
end
end
end

View file

@ -25,16 +25,14 @@ describe RegistrationsController, type: :controller do
AppConfig.settings.enable_registrations = false
end
it "redirects #new to the login page" do
it "redirects #new to the registrations closed page" do
get :new
expect(flash[:error]).to eq(I18n.t("registrations.closed"))
expect(response).to redirect_to new_user_session_path
expect(response).to redirect_to registrations_closed_path
end
it "redirects #create to the login page" do
it "redirects #create to the registrations closed page" do
post :create, params: valid_params
expect(flash[:error]).to eq(I18n.t("registrations.closed"))
expect(response).to redirect_to new_user_session_path
expect(response).to redirect_to registrations_closed_path
end
it "does not redirect if there is a valid invite token" do
@ -45,7 +43,8 @@ describe RegistrationsController, type: :controller do
it "does redirect if there is an invalid invite token" do
get :new, params: {invite: {token: "fssdfsd"}}
expect(response).to redirect_to new_user_session_path
expect(flash[:error]).to eq(I18n.t("registrations.invalid_invite"))
expect(response).to redirect_to registrations_closed_path
end
it "does redirect if there are no invites available with this code" do
@ -53,7 +52,7 @@ describe RegistrationsController, type: :controller do
code.update_attributes(count: 0)
get :new, params: {invite: {token: code.token}}
expect(response).to redirect_to new_user_session_path
expect(response).to redirect_to registrations_closed_path
end
it "does redirect when invitations are closed now" do
@ -61,7 +60,7 @@ describe RegistrationsController, type: :controller do
AppConfig.settings.invitations.open = false
get :new, params: {invite: {token: code.token}}
expect(response).to redirect_to new_user_session_path
expect(response).to redirect_to registrations_closed_path
end
it "does not redirect when the registration is open" do

View file

@ -984,9 +984,7 @@ describe User, :type => :model do
exported_at
exported_photos_at
consumed_timestep
encrypted_otp_secret
encrypted_otp_secret_iv
encrypted_otp_secret_salt
plain_otp_secret
otp_backup_codes
otp_required_for_login
otp_secret