From c9e43eadf670e8ef6a157d2adb726da4983d5af9 Mon Sep 17 00:00:00 2001 From: Leo McArdle Date: Fri, 5 Apr 2019 13:44:49 +0100 Subject: [PATCH] FEATURE: first pass at dinopark sign-up flow Specs still need to be written. https://github.com/mozilla/discourse/issues/186 --- .../controllers/dinopark-sign-up.js.es6 | 69 +++++++++++++++++++ .../initializers/dinopark-sign-up.js.es6 | 27 ++++++++ .../templates/modal/dinopark-sign-up.hbs | 39 +++++++++++ assets/stylesheets/common/mozilla-iam.scss | 6 ++ config/initializers/patch_auth_result.rb | 4 ++ config/initializers/patch_users_controller.rb | 1 + config/locales/client.en.yml | 10 +++ lib/mozilla_iam.rb | 2 + lib/mozilla_iam/api/person_v2.rb | 12 ++++ lib/mozilla_iam/auth_result_extensions.rb | 16 +++++ lib/mozilla_iam/authenticator.rb | 6 +- .../users_controller_extensions.rb | 14 ++++ plugin.rb | 2 +- 13 files changed, 205 insertions(+), 3 deletions(-) create mode 100644 assets/javascripts/discourse/controllers/dinopark-sign-up.js.es6 create mode 100644 assets/javascripts/discourse/initializers/dinopark-sign-up.js.es6 create mode 100644 assets/javascripts/discourse/templates/modal/dinopark-sign-up.hbs create mode 100644 config/initializers/patch_auth_result.rb create mode 100644 config/initializers/patch_users_controller.rb create mode 100644 lib/mozilla_iam/auth_result_extensions.rb create mode 100644 lib/mozilla_iam/users_controller_extensions.rb diff --git a/assets/javascripts/discourse/controllers/dinopark-sign-up.js.es6 b/assets/javascripts/discourse/controllers/dinopark-sign-up.js.es6 new file mode 100644 index 0000000..0550c54 --- /dev/null +++ b/assets/javascripts/discourse/controllers/dinopark-sign-up.js.es6 @@ -0,0 +1,69 @@ +import ModalFunctionality from "discourse/mixins/modal-functionality" +import showModal from "discourse/lib/show-modal" +import { on } from "ember-addons/ember-computed-decorators" +import { ajax } from "discourse/lib/ajax" +import { userPath } from "discourse/lib/url" + +export default Ember.Controller.extend(ModalFunctionality, { + createAccount: Ember.inject.controller("create-account"), + + showingConfirm: false, + tosChecked: false, + submitted: false, + + @on("init") + fetchConfirmationValue() { + return ajax(userPath("hp.json")).then(json => { + this.setProperties({ + accountPasswordConfirm: json.value, + accountChallenge: json.challenge + .split("") + .reverse() + .join("") + }); + }); + }, + + actions: { + normalSignup() { + const options = this.get("options") + const createAccountController = this.get("createAccount") + createAccountController.setProperties({ + accountEmail: options.email, + accountUsername: options.username, + accountName: options.name, + authOptions: Ember.Object.create(options) + }) + showModal("createAccount") + }, + + findProfile() { + this.set("showingConfirm", true) + }, + + confirm() { + this.set("submitted", true) + return ajax(userPath(), { + data: { + username: this.get("options").dinopark_profile.username, + email: this.get("options").email, + password_confirmation: this.get("accountPasswordConfirm"), + challenge: this.get("accountChallenge"), + dinopark_enabled: true + }, + type: "POST" + }).then(result => { + if (result.success) { + var destination_url = this.get("options.destination_url") + window.location = destination_url ? destination_url : "/" + } else { + this.set("submitted", false) + this.flash(result.message || I18n.t("create_account.failed"), "error") + } + }, () => { + this.set("submitted", false) + this.flash(I18n.t("create_account.failed"), "error") + }) + } + } +}); diff --git a/assets/javascripts/discourse/initializers/dinopark-sign-up.js.es6 b/assets/javascripts/discourse/initializers/dinopark-sign-up.js.es6 new file mode 100644 index 0000000..2fd6ef8 --- /dev/null +++ b/assets/javascripts/discourse/initializers/dinopark-sign-up.js.es6 @@ -0,0 +1,27 @@ +import { withPluginApi } from 'discourse/lib/plugin-api' +import showModal from "discourse/lib/show-modal" + +export default { + name: 'dinopark-sign-up', + initialize () { + withPluginApi('0.8.30', api => { + + api.modifyClass("controller:login", { + dinoparkSignUpController: Ember.inject.controller("dinopark-sign-up"), + + authenticationComplete(options) { + if (options.dinopark_profile) { + const dinoParkSignUpController = this.get("dinoparkSignUpController") + dinoParkSignUpController.setProperties({ + options: options + }) + showModal("dinopark-sign-up") + } else { + this._super(options) + } + } + }) + + }) + } +} diff --git a/assets/javascripts/discourse/templates/modal/dinopark-sign-up.hbs b/assets/javascripts/discourse/templates/modal/dinopark-sign-up.hbs new file mode 100644 index 0000000..fb98109 --- /dev/null +++ b/assets/javascripts/discourse/templates/modal/dinopark-sign-up.hbs @@ -0,0 +1,39 @@ +{{#d-modal-body class="dinopark-sign-up"}} + {{#if showingConfirm}} +

{{i18n 'dinopark.sign_up.confirm_title'}}

+

{{i18n 'dinopark.sign_up.confirm_description'}}

+ {{else}} +

{{i18n 'dinopark.sign_up.prompt_title'}}

+

{{i18n 'dinopark.sign_up.prompt_subtitle'}}

+

{{i18n 'dinopark.sign_up.prompt_description'}}

+ {{/if}} + + {{input type="checkbox" id="tos-checkbox" checked=tosChecked}} + +{{/d-modal-body}} + diff --git a/assets/stylesheets/common/mozilla-iam.scss b/assets/stylesheets/common/mozilla-iam.scss index e1b15e4..9ca9584 100644 --- a/assets/stylesheets/common/mozilla-iam.scss +++ b/assets/stylesheets/common/mozilla-iam.scss @@ -1,3 +1,9 @@ +.dinopark-sign-up { + label { + display: inline; + } +} + .user-preferences { .dinopark-edit { diff --git a/config/initializers/patch_auth_result.rb b/config/initializers/patch_auth_result.rb new file mode 100644 index 0000000..325ddc5 --- /dev/null +++ b/config/initializers/patch_auth_result.rb @@ -0,0 +1,4 @@ +Auth::Result.prepend MozillaIAM::AuthResultExtensions +Auth::Result.class_eval do + attr_accessor :user_id +end diff --git a/config/initializers/patch_users_controller.rb b/config/initializers/patch_users_controller.rb new file mode 100644 index 0000000..fd88e9b --- /dev/null +++ b/config/initializers/patch_users_controller.rb @@ -0,0 +1 @@ +UsersController.prepend MozillaIAM::UsersControllerExtensions diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index dac2cd4..d3639ec 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -15,6 +15,16 @@ en: dinopark: edit_short: "Edit" edit_long: "Edit on people.mozilla.org" + sign_up: + tos: 'I agree to the privacy policy and terms of service.' + prompt_title: "Discourse integrates with Mozilla Directory profiles" + prompt_subtitle: "Would you like to link your public profile fields?" + prompt_description: "You'll be able to review and confirm the information on the next screen." + confirm_title: "Review and confirm your profile information" + confirm_description: "The following public profile fields from your Mozilla Directory profile are ready to be linked." + cancel: "Not right now" + continue: "Yes, find and link my profile" + confirm: "Confirm and create linked account" mozillians: edit: "Edit on Mozillians" mozilla_iam: diff --git a/lib/mozilla_iam.rb b/lib/mozilla_iam.rb index bfc06b1..7c5f0ca 100644 --- a/lib/mozilla_iam.rb +++ b/lib/mozilla_iam.rb @@ -8,11 +8,13 @@ require_relative 'mozilla_iam/api/person' require_relative 'mozilla_iam/api/person_v2' require_relative 'mozilla_iam/api/management' require_relative 'mozilla_iam/application_extensions' +require_relative 'mozilla_iam/auth_result_extensions' require_relative 'mozilla_iam/authenticator' require_relative 'mozilla_iam/jwks' require_relative 'mozilla_iam/jwt' require_relative 'mozilla_iam/profile' require_relative 'mozilla_iam/omniauth_oauth2_extensions' +require_relative 'mozilla_iam/users_controller_extensions' module MozillaIAM end diff --git a/lib/mozilla_iam/api/person_v2.rb b/lib/mozilla_iam/api/person_v2.rb index ab96c67..97b7a13 100644 --- a/lib/mozilla_iam/api/person_v2.rb +++ b/lib/mozilla_iam/api/person_v2.rb @@ -33,6 +33,18 @@ module MozillaIAM @location = process :location end + def blank? + @raw.blank? + end + + def to_hash + hash = {} + (instance_variables - [:@raw]).each do |var| + hash[var.to_s.delete_prefix("@")] = instance_variable_get(var) + end + hash + end + private def process(name) diff --git a/lib/mozilla_iam/auth_result_extensions.rb b/lib/mozilla_iam/auth_result_extensions.rb new file mode 100644 index 0000000..34f8d2c --- /dev/null +++ b/lib/mozilla_iam/auth_result_extensions.rb @@ -0,0 +1,16 @@ +module MozillaIAM + module AuthResultExtensions + + def to_client_hash + result = super + profile = MozillaIAM::API::PersonV2.new.profile(user_id) + unless profile.blank? + result.merge!({ + dinopark_profile: profile.to_hash + }) + end + result + end + + end +end diff --git a/lib/mozilla_iam/authenticator.rb b/lib/mozilla_iam/authenticator.rb index 8598ee0..36dc55d 100644 --- a/lib/mozilla_iam/authenticator.rb +++ b/lib/mozilla_iam/authenticator.rb @@ -34,7 +34,7 @@ module MozillaIAM raise SecondaryEmailError.new(user, email) end result.name = payload['name'] - uid = payload['sub'] + result.user_id = uid = payload['sub'] result.extra_data = { uid: uid } if user @@ -68,7 +68,9 @@ module MozillaIAM def after_create_account(user, auth) uid = auth[:extra_data][:uid] - Profile.new(user, uid).force_refresh + p = Profile.new(user, uid) + p.dinopark_enabled = true if auth[:dinopark_enabled] + p.force_refresh end def register_middleware(omniauth) diff --git a/lib/mozilla_iam/users_controller_extensions.rb b/lib/mozilla_iam/users_controller_extensions.rb new file mode 100644 index 0000000..0ac2aaa --- /dev/null +++ b/lib/mozilla_iam/users_controller_extensions.rb @@ -0,0 +1,14 @@ +module MozillaIAM + module UsersControllerExtensions + + def create + params.permit(:dinopark_enabled) + if dinopark_enabled = params[:dinopark_enabled] + session[:authentication][:dinopark_enabled] = dinopark_enabled + params[:username] = UserNameSuggester.find_available_username_based_on(params[:username]) + end + super + end + + end +end diff --git a/plugin.rb b/plugin.rb index ae7f1da..0dda09a 100644 --- a/plugin.rb +++ b/plugin.rb @@ -1,6 +1,6 @@ # name: mozilla-iam # about: A plugin to integrate Discourse with Mozilla's Identity and Access Management (IAM) system -# version: 1.2.0-alpha.10 +# version: 1.2.0-alpha.11 # authors: Leo McArdle # url: https://github.com/mozilla/discourse-mozilla-iam