2017-12-30 26 views
0

Ich habe diese Operation:Wegbereiterin Verträge überschreibt params

require 'bcrypt' 

class User::Create < Trailblazer::Operation 

    extend Contract::DSL 

    contract 'params', (Dry::Validation.Schema do 
    required(:email).filled 
    required(:password).filled 
    end) 

    step  Contract::Validate(name: 'params'), before: 'operation.new' 
    step  Model(User, :new) 
    success :generate_token 
    success :encrypt_password 
    success :assign_user_values 
    step  Contract::Build(constant: User::Contract::Create) 
    step  Contract::Validate() 
    step  Contract::Persist() 

    def generate_token(options, *) 
    token = loop do 
     random_token = SecureRandom.uuid 
     break random_token unless User.exists?(token: random_token) 
    end 

    options['data.token'] = token 
    end 

    def encrypt_password(options, params:, **) 
    options['data.password'] = BCrypt::Password.create(params[:password]) 
    end 

    def assign_user_values(options, params:, **) 
    options['model'].token = options['data.token'] 
    options['model'].password = options['data.password'] 
    options['model'].role = 'user' 
    end 

end 

Wenn ich die Operation ausführen, bekomme ich diese Ausgabe:

User::Create.(email: '[email protected]', password: 'bidule') 
    User Exists (0.6ms) SELECT 1 AS one FROM "users" WHERE "users"."token" = $1 LIMIT $2 [["token", "64423af4-5741-46af-9756-15715a632d75"], ["LIMIT", 1]] 
    (0.6ms) SELECT COUNT(*) FROM "users" WHERE "users"."email" = $1 [["email", "[email protected]"]] 
    (0.4ms) SELECT COUNT(*) FROM "users" WHERE "users"."token" = $1 [["token", "64423af4-5741-46af-9756-15715a632d75"]] 
    (0.3ms) BEGIN 
    SQL (0.5ms) INSERT INTO "users" ("email", "password", "role", "token", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id" [["email", "[email protected]"], ["password", "bidule"], ["role", "user"], ["token", "64423af4-5741-46af-9756-15715a632d75"], ["created_at", "2017-12-30 23:34:24.456817"], ["updated_at", "2017-12-30 23:34:24.456817"]] 
    (2.8ms) COMMIT 
=> <Result:true <Skill {"contract.params.params"=>{:email=>"[email protected]", :password=>"bidule"}, "representer.params.class"=>false, "result.contract.params"=>#<Dry::Validation::Result output={:email=>"[email protected]", :password=>"bidule"} errors={}>, "model.class"=>User(id: integer, email: string, password: string, role: string, token: string, created_at: datetime, updated_at: datetime), "model.action"=>:new, "model"=>#<User id: 17, email: "[email protected]", password: "bidule", role: "user", token: "64423af4-5741-46af-9756-15715a632d75", created_at: "2017-12-30 23:34:24", updated_at: "2017-12-30 23:34:24">, "result.model"=><Result:true {} >, "data.token"=>"64423af4-5741-46af-9756-15715a632d75", "data.password"=>"$2a$10$gy19txopkeM5Vovx4/ohvOuZAP2CMwtBTcCwswJq9Ije7NVrKj8Ce", "contract.default"=>#<User::Contract::Create:0x0000000004e316e8 @fields={"email"=>"[email protected]", "password"=>"bidule", "role"=>"user", "token"=>"64423af4-5741-46af-9756-15715a632d75"}, @model=#<User id: 17, email: "[email protected]", password: "bidule", role: "user", token: "64423af4-5741-46af-9756-15715a632d75", created_at: "2017-12-30 23:34:24", updated_at: "2017-12-30 23:34:24">, @mapper=#<#<Class:0x0000000004e31558>:0x0000000004e30bf8 @model=#<User id: 17, email: "[email protected]", password: "bidule", role: "user", token: "64423af4-5741-46af-9756-15715a632d75", created_at: "2017-12-30 23:34:24", updated_at: "2017-12-30 23:34:24">>, @_changes={"email"=>true, "password"=>true}, @errors=#<Reform::Form::ActiveModel::Errors:0x0000000004e30338 @base=#<User::Contract::Create:0x0000000004e316e8 ...>, @messages={}, @details={}>>, "contract.default.params"=>{:email=>"[email protected]", :password=>"bidule"}, "representer.default.class"=>false, "result.contract.default"=>#<User::Contract::Create:0x0000000004e316e8 @fields={"email"=>"[email protected]", "password"=>"bidule", "role"=>"user", "token"=>"64423af4-5741-46af-9756-15715a632d75"}, @model=#<User id: 17, email: "[email protected]", password: "bidule", role: "user", token: "64423af4-5741-46af-9756-15715a632d75", created_at: "2017-12-30 23:34:24", updated_at: "2017-12-30 23:34:24">, @mapper=#<#<Class:0x0000000004e31558>:0x0000000004e30bf8 @model=#<User id: 17, email: "[email protected]", password: "bidule", role: "user", token: "64423af4-5741-46af-9756-15715a632d75", created_at: "2017-12-30 23:34:24", updated_at: "2017-12-30 23:34:24">>, @_changes={"email"=>true, "password"=>true}, @errors=#<Reform::Form::ActiveModel::Errors:0x0000000004e30338 @base=#<User::Contract::Create:0x0000000004e316e8 ...>, @messages={}, @details={}>>} {"params"=>{:email=>"[email protected]", :password=>"bidule"}} {"pipetree"=>[>contract.params.validate,>operation.new,>model.build,>generate_token,>encrypt_password,>assign_user_values,>contract.build,>contract.default.validate,>persist.save], "contract.params"=>#<#<Class:0x0000000005261790>:0x0000000005245798 @type_map={}, @config=#<#<Class:0x0000000004b1a518>:0x00000000052616a0 @config={:input_processor=>:noop, :hash_type=>:weak, :type_map=>{}, :path=>[], :predicates=>Dry::Logic::Predicates, :registry=>#<Dry::Validation::PredicateRegistry::Unbound:0x0000000005261588 @external=Dry::Logic::Predicates, @predicates={}>, :messages=>:yaml, :messages_file=>nil, :namespace=>nil, :rules=>[[:rule, [:email, [:and, [[:rule, [:email, [:predicate, [:key?, [[:name, :email], [:input, Undefined]]]]]], [:rule, [:email, [:key, [:email, [:predicate, [:filled?, [[:input, Undefined]]]]]]]]]]]], [:rule, [:password, [:and, [[:rule, [:password, [:predicate, [:key?, [[:name, :password], [:input, Undefined]]]]]], [:rule, [:password, [:key, [:password, [:predicate, [:filled?, [[:input, Undefined]]]]]]]]]]]]], :checks=>[], :options=>{}, :input=>nil, :input_rule=>nil, :dsl_extensions=>nil, :input_processor_map=>{:sanitizer=>#<Dry::Validation::InputProcessorCompiler::Sanitizer:0x0000000004afb618 @type_compiler=#<Dry::Types::Compiler:0x0000000004afb5f0 @registry=Dry::Types>>, :json=>#<Dry::Validation::InputProcessorCompiler::JSON:0x0000000004afb5c8 @type_compiler=#<Dry::Types::Compiler:0x0000000004afb5a0 @registry=Dry::Types>>, :form=>#<Dry::Validation::InputProcessorCompiler::Form:0x0000000004afb578 @type_compiler=#<Dry::Types::Compiler:0x0000000004afb550 @registry=Dry::Types>>}, :type_specs=>false}>, @predicates=#<Dry::Validation::PredicateRegistry::Bound:0x0000000005245720 @external=Dry::Logic::Predicates, @predicates={}, @schema=#<#<Class:0x0000000005261790>:0x0000000005245798 ...>>, @rule_compiler=#<Dry::Validation::SchemaCompiler:0x0000000005245630 @predicates=#<Dry::Validation::PredicateRegistry::Bound:0x0000000005245720 @external=Dry::Logic::Predicates, @predicates={}, @schema=#<#<Class:0x0000000005261790>:0x0000000005245798 ...>>, @options={:predicate_registry=>#<Dry::Validation::PredicateRegistry::Unbound:0x0000000005261588 @external=Dry::Logic::Predicates, @predicates={}>, :message_compiler=>#<Dry::Validation::MessageCompiler:0x00000000052459c8 @messages=#<Dry::Validation::Messages::YAML data={"en.errors.or"=>"or", "en.errors.array?"=>"must be an array", "en.errors.empty?"=>"must be empty", "en.errors.excludes?"=>"must not include %{value}", "en.errors.excluded_from?.arg.default"=>"must not be one of: %{list}", "en.errors.excluded_from?.arg.range"=>"must not be one of: %{list_left} - %{list_right}", "en.errors.exclusion?"=>"must not be one of: %{list}", "en.errors.eql?"=>"must be equal to %{left}", "en.errors.not_eql?"=>"must not be equal to %{left}", "en.errors.filled?"=>"must be filled", "en.errors.format?"=>"is in invalid format", "en.errors.number?"=>"must be a number", "en.errors.odd?"=>"must be odd", "en.errors.even?"=>"must be even", "en.errors.gt?"=>"must be greater than %{num}", "en.errors.gteq?"=>"must be greater than or equal to %{num}", "en.errors.hash?"=>"must be a hash", "en.errors.included_in?.arg.default"=>"must be one of: %{list}", "en.errors.included_in?.arg.range"=>"must be one of: %{list_left} - %{list_right}", "en.errors.inclusion?"=>"must be one of: %{list}", "en.errors.includes?"=>"must include %{value}", "en.errors.bool?"=>"must be boolean", "en.errors.true?"=>"must be true", "en.errors.false?"=>"must be false", "en.errors.int?"=>"must be an integer", "en.errors.float?"=>"must be a float", "en.errors.decimal?"=>"must be a decimal", "en.errors.date?"=>"must be a date", "en.errors.date_time?"=>"must be a date time", "en.errors.time?"=>"must be a time", "en.errors.key?"=>"is missing", "en.errors.attr?"=>"is missing", "en.errors.lt?"=>"must be less than %{num}", "en.errors.lteq?"=>"must be less than or equal to %{num}", "en.errors.max_size?"=>"size cannot be greater than %{num}", "en.errors.min_size?"=>"size cannot be less than %{num}", "en.errors.none?"=>"cannot be defined", "en.errors.str?"=>"must be a string", "en.errors.type?"=>"must be %{type}", "en.errors.size?.arg.default"=>"size must be %{size}", "en.errors.size?.arg.range"=>"size must be within %{size_left} - %{size_right}", "en.errors.size?.value.string.arg.default"=>"length must be %{size}", "en.errors.size?.value.string.arg.range"=>"length must be within %{size_left} - %{size_right}"}>, @options={}, @full=false, @hints=true, @locale=:en, @default_lookup_options={:locale=>:en}>, :input_processor=>#<Proc:[email protected]/app/vendor/bundle/ruby/2.3.0/gems/dry-validation-0.11.1/lib/dry/validation/schema/class_interface.rb:11 (lambda)>, :checks=>[]}, @schema=#<#<Class:0x0000000005261790>:0x0000000005245798 ...>>, @message_compiler=#<Dry::Validation::MessageCompiler:0x00000000052459c8 @messages=#<Dry::Validation::Messages::YAML data={"en.errors.or"=>"or", "en.errors.array?"=>"must be an array", "en.errors.empty?"=>"must be empty", "en.errors.excludes?"=>"must not include %{value}", "en.errors.excluded_from?.arg.default"=>"must not be one of: %{list}", "en.errors.excluded_from?.arg.range"=>"must not be one of: %{list_left} - %{list_right}", "en.errors.exclusion?"=>"must not be one of: %{list}", "en.errors.eql?"=>"must be equal to %{left}", "en.errors.not_eql?"=>"must not be equal to %{left}", "en.errors.filled?"=>"must be filled", "en.errors.format?"=>"is in invalid format", "en.errors.number?"=>"must be a number", "en.errors.odd?"=>"must be odd", "en.errors.even?"=>"must be even", "en.errors.gt?"=>"must be greater than %{num}", "en.errors.gteq?"=>"must be greater than or equal to %{num}", "en.errors.hash?"=>"must be a hash", "en.errors.included_in?.arg.default"=>"must be one of: %{list}", "en.errors.included_in?.arg.range"=>"must be one of: %{list_left} - %{list_right}", "en.errors.inclusion?"=>"must be one of: %{list}", "en.errors.includes?"=>"must include %{value}", "en.errors.bool?"=>"must be boolean", "en.errors.true?"=>"must be true", "en.errors.false?"=>"must be false", "en.errors.int?"=>"must be an integer", "en.errors.float?"=>"must be a float", "en.errors.decimal?"=>"must be a decimal", "en.errors.date?"=>"must be a date", "en.errors.date_time?"=>"must be a date time", "en.errors.time?"=>"must be a time", "en.errors.key?"=>"is missing", "en.errors.attr?"=>"is missing", "en.errors.lt?"=>"must be less than %{num}", "en.errors.lteq?"=>"must be less than or equal to %{num}", "en.errors.max_size?"=>"size cannot be greater than %{num}", "en.errors.min_size?"=>"size cannot be less than %{num}", "en.errors.none?"=>"cannot be defined", "en.errors.str?"=>"must be a string", "en.errors.type?"=>"must be %{type}", "en.errors.size?.arg.default"=>"size must be %{size}", "en.errors.size?.arg.range"=>"size must be within %{size_left} - %{size_right}", "en.errors.size?.value.string.arg.default"=>"length must be %{size}", "en.errors.size?.value.string.arg.range"=>"length must be within %{size_left} - %{size_right}"}>, @options={}, @full=false, @hints=true, @locale=:en, @default_lookup_options={:locale=>:en}>, @input_processor=#<Proc:[email protected]/app/vendor/bundle/ruby/2.3.0/gems/dry-validation-0.11.1/lib/dry/validation/schema/class_interface.rb:11 (lambda)>, @options={:predicate_registry=>#<Dry::Validation::PredicateRegistry::Unbound:0x0000000005261588 @external=Dry::Logic::Predicates, @predicates={}>, :message_compiler=>#<Dry::Validation::MessageCompiler:0x00000000052459c8 @messages=#<Dry::Validation::Messages::YAML data={"en.errors.or"=>"or", "en.errors.array?"=>"must be an array", "en.errors.empty?"=>"must be empty", "en.errors.excludes?"=>"must not include %{value}", "en.errors.excluded_from?.arg.default"=>"must not be one of: %{list}", "en.errors.excluded_from?.arg.range"=>"must not be one of: %{list_left} - %{list_right}", "en.errors.exclusion?"=>"must not be one of: %{list}", "en.errors.eql?"=>"must be equal to %{left}", "en.errors.not_eql?"=>"must not be equal to %{left}", "en.errors.filled?"=>"must be filled", "en.errors.format?"=>"is in invalid format", "en.errors.number?"=>"must be a number", "en.errors.odd?"=>"must be odd", "en.errors.even?"=>"must be even", "en.errors.gt?"=>"must be greater than %{num}", "en.errors.gteq?"=>"must be greater than or equal to %{num}", "en.errors.hash?"=>"must be a hash", "en.errors.included_in?.arg.default"=>"must be one of: %{list}", "en.errors.included_in?.arg.range"=>"must be one of: %{list_left} - %{list_right}", "en.errors.inclusion?"=>"must be one of: %{list}", "en.errors.includes?"=>"must include %{value}", "en.errors.bool?"=>"must be boolean", "en.errors.true?"=>"must be true", "en.errors.false?"=>"must be false", "en.errors.int?"=>"must be an integer", "en.errors.float?"=>"must be a float", "en.errors.decimal?"=>"must be a decimal", "en.errors.date?"=>"must be a date", "en.errors.date_time?"=>"must be a date time", "en.errors.time?"=>"must be a time", "en.errors.key?"=>"is missing", "en.errors.attr?"=>"is missing", "en.errors.lt?"=>"must be less than %{num}", "en.errors.lteq?"=>"must be less than or equal to %{num}", "en.errors.max_size?"=>"size cannot be greater than %{num}", "en.errors.min_size?"=>"size cannot be less than %{num}", "en.errors.none?"=>"cannot be defined", "en.errors.str?"=>"must be a string", "en.errors.type?"=>"must be %{type}", "en.errors.size?.arg.default"=>"size must be %{size}", "en.errors.size?.arg.range"=>"size must be within %{size_left} - %{size_right}", "en.errors.size?.value.string.arg.default"=>"length must be %{size}", "en.errors.size?.value.string.arg.range"=>"length must be within %{size_left} - %{size_right}"}>, @options={}, @full=false, @hints=true, @locale=:en, @default_lookup_options={:locale=>:en}>, :input_processor=>#<Proc:[email protected]/app/vendor/bundle/ruby/2.3.0/gems/dry-validation-0.11.1/lib/dry/validation/schema/class_interface.rb:11 (lambda)>, :checks=>[]}, @rules={:email=>#<Dry::Logic::Operations::And rules=[#<Dry::Logic::Rule::Predicate predicate=#<Method: Module(Dry::Logic::Predicates::Methods)#key?> options={:args=>[:email], :id=>:email}>, #<Dry::Logic::Operations::Key rules=[#<Dry::Logic::Rule::Predicate predicate=#<Method: Module(Dry::Logic::Predicates::Methods)#filled?> options={:args=>[]}>] options={:name=>:email, :evaluator=>#<Dry::Logic::Evaluator::Key path=[:email]>, :path=>:email, :id=>:email}>] options={:id=>:email}>, :password=>#<Dry::Logic::Operations::And rules=[#<Dry::Logic::Rule::Predicate predicate=#<Method: Module(Dry::Logic::Predicates::Methods)#key?> options={:args=>[:password], :id=>:password}>, #<Dry::Logic::Operations::Key rules=[#<Dry::Logic::Rule::Predicate predicate=#<Method: Module(Dry::Logic::Predicates::Methods)#filled?> options={:args=>[]}>] options={:name=>:password, :evaluator=>#<Dry::Logic::Evaluator::Key path=[:password]>, :path=>:password, :id=>:password}>] options={:id=>:password}>}, @checks={}, @executor=#<Dry::Validation::Executor:0x000000000524f8b0 @steps=[#<Dry::Validation::ProcessInput:0x000000000524f860 @processor=#<Proc:[email protected]/app/vendor/bundle/ruby/2.3.0/gems/dry-validation-0.11.1/lib/dry/validation/schema/class_interface.rb:11 (lambda)>>, #<Dry::Validation::ApplyRules:0x000000000524f838 @rules={:email=>#<Dry::Logic::Operations::And rules=[#<Dry::Logic::Rule::Predicate predicate=#<Method: Module(Dry::Logic::Predicates::Methods)#key?> options={:args=>[:email], :id=>:email}>, #<Dry::Logic::Operations::Key rules=[#<Dry::Logic::Rule::Predicate predicate=#<Method: Module(Dry::Logic::Predicates::Methods)#filled?> options={:args=>[]}>] options={:name=>:email, :evaluator=>#<Dry::Logic::Evaluator::Key path=[:email]>, :path=>:email, :id=>:email}>] options={:id=>:email}>, :password=>#<Dry::Logic::Operations::And rules=[#<Dry::Logic::Rule::Predicate predicate=#<Method: Module(Dry::Logic::Predicates::Methods)#key?> options={:args=>[:password], :id=>:password}>, #<Dry::Logic::Operations::Key rules=[#<Dry::Logic::Rule::Predicate predicate=#<Method: Module(Dry::Logic::Predicates::Methods)#filled?> options={:args=>[]}>] options={:name=>:password, :evaluator=>#<Dry::Logic::Evaluator::Key path=[:password]>, :path=>:password, :id=>:password}>] options={:id=>:password}>}>], @final=#<Dry::Validation::BuildErrors:0x000000000524f8d8>>>}> > 

Das Passwort des Modells wird in der Datenbank nicht verschlüsselt Ich glaube, das liegt daran, dass Contract :: Build das Passwort von den Parametern und nicht vom Modell abruft.

Irgendwelche Gedanken?

Antwort

2

Sie sollen den Wert auf dem Vertrag verschlüsseln, bevor sie das Modell synchronisiert:

def assign_user_values(options, params:, **) 
    options['model'].token = options['data.token'] 
    options['contract.default'].password = options['data.password'] 
    options['model'].role = 'user' 
end 

seit: Token und: Rolle sind nicht im Vertrag, können Sie diese Werte direkt auf dem Muster, sondern Vertrag :: Persist() wird den Wert von Params synchronisieren, also ändern Sie den Wert des Feldes im Vertrag, bevor Sie mit dem Modell synchronisieren.

Edit: Hinweis, Sie könnten dies auch in der Methode, die das Passwort verschlüsselt; Sie müssen diese Daten nicht intern zwischen den Schritten weitergeben.

+0

Ich verschlüsselte direkt die Daten von params, arbeitete wie ein Charme :) –

Verwandte Themen