Activeldap: add a value to a multivalued attribute in the active directory - ruby

i have a users and groups in my AD.
ou=users, dc=MLT, dc=local
ou=groups, dc=MLT, dc=local
i want to associate the users with the groups using activeldap.
i do that through adding the users distinguish name (user.dn) to an attribute in the groups called "member" which is multivalued attribute.
you can hier read the description of "member"
https://learn.microsoft.com/en-us/windows/win32/ad/group-objects
This is the Ruby code that I wrote :
config = {
host: 'c',
base: 'dc= MLT,dc=local',
bind_dn: ENV['AD_SERVICE_USER'],
password: ENV['AD_SERVICE_PASSWORD']
}
# Connect to LDAP server
ActiveLdap::Base.setup_connection config
class Group < ActiveLdap::Base
query = {
dn_attribute: 'cn',
prefix: 'ou=groups',
classes: %w[top group]
}
ldap_mapping query
end
class User < ActiveLdap::Base
query = {
dn_attribute: 'cn',
prefix: 'ou=users'
}
ldap_mapping query
end
# associate "Joe" to the "employee" group
group = Group.find(:first, attribute: 'cn', value: 'employee')
user = User.find(:first, attribute:'cn', value:'Joe')
# I used push to add the new user.dn because "member" should be a list of distinguished names.
group.member.push(user.dn)
begin
group.save
rescue ActiveLdap::SaveError
puts 'Could not save group!'
puts new_group.errors.full_messages
end
I became this error message:
undefined method `push' for #<ActiveLdap::DistinguishedName:0x00007f8d2054cb58>
can anyone tell me how can I add more than one value to member ????

Related

how to return both error and data in graphql

There are user and notes fields.
If the notes field exceeds the limit, I want to get an error with the data
But I don't know what to do. (Currently only an error is returned.)
Is it possible to return both the error and the data?
as it
errors = {xx}
to be
data = {user: { notes: []}}
errors = {xx}
my code is as follows
app/graphql/types/object_types/user.rb
module Types
module ObjectTypes
class User < Types::ObjectTypes::BaseObject
graphql_name 'User'
implements GraphQL::Types::Relay::Node
field :notes, [Types::ObjectTypes::Note], null: true do
description ''
argument :date_from, GraphQL::Types::ISO8601Date, required: true
argument :date_to, GraphQL::Types::ISO8601Date, required: true
end
def notes(date_from:, date_to:)
object.notes.date_between(date_from, date_to).tap { |array| raise AppError if array.size > 1000 }
end

FactoryBot creates records even when a record is provided

I use factorybot to create records in development sometimes. However, it's creating a bunch of extra data that I wasn't expecting.
I have two factories:
FactoryBot.define do
factory :user do
first_name { Faker::Name.first_name }
last_name { Faker::Name.last_name }
email { "#{first_name}.#{last_name}#example.com" }
end
factory :post do
user { create(:user) }
title { Faker::Lorem.sentence }
end
end
If I run FactoryBot.create(:post) in the rails console, it will create a new post with a new user. What I didn't expect is that if I do FactoryBot.create(:post, user: User.first), it would create a post associated with the first user, but still create a new record. So, I get this:
irb(main):001:0> User.count
=> 1
irb(main:002:0> FactoryBot.create(:post, user: User.first)
=> #<Post id: 1, title: 'Lorem Ipsum', host_id: 1>
irb(main:003:0> User.count
=> 2
Everything works, it just creates a new user record that isn't attached to anything. Is there anyway to stop that from happening?
You don't need to tell FactoryBot to create(:user). Just remove it.
factory :post do
user
title { Faker::Lorem.sentence }
end
https://devhints.io/factory_bot

How do I accept field arguments for a nested query in Graphql Ruby?

I'm getting this error in GraphQl (Apollo JS/ Graphql Ruby):
Error Error: GraphQL error: Field 'pagination' doesn't accept argument 'pagination' GraphQL error: Variable $pagination is declared by Clients but not used. Reload the page and try again.
I have this query:
query Clients($pagination: PaginationInput) {
clients {
data {
....Fragment
}
pagination(pagination: $pagination) {
....Fragment
}
}
}
And I have this as my input type:
class PaginatedClientsType < Types::BaseObject
field :data, ...
field :pagination, PaginationType ... do
argument :pagination, PaginationInput, required: false
end
end
And this in my query_type.rb file:
field :clients, ::Types::Paginated::ClientsType, null: false do
argument :pagination, PaginationInput, required: false
end
def clients(pagination:)
...
end
// and i've added to no avail:
field :pagination ... do
argument :pagination, PaginationInput, required: false
end
def pagination(pagination:)
...
end
Any ideas on how I can pass the argument to something other than this top level client?
I've read docs here but can't figure it out.
Thanks!

passing arguments in graphQL queries

I'm just starting to learn GraphQL and I'm currently trying to create a clone of twitter. In the code below, is there a way I can pass the 81 from the id argument (e.g. user(id: 81)) automatically to the userId argument (e.g. tweets(userId: 81))?
I've copied my code below
{
user(id: 81) {
username
email
tweets(userId: 81) {
content
}
}
}
user_type.rb
module Types
class UserType < Types::BaseObject
field :username, String, null: false
field :email, String, null: false
field :bio, String, null: true
field :tweets, [Types::TweetType], null: true do
argument :user_id, ID, required: true
end
def tweets(user_id:)
Tweet.where(user_id: user_id)
end
end
end
tweet_type.rb
module Types
class TweetType < Types::BaseObject
field :id, ID, null: false
field :content, String, null: false
field :userId, ID, null: false
field :createdAt, GraphQL::Types::ISO8601DateTime, null: false
field :user, Types::UserType, null: false
end
end
query_type.rb
module Types
class QueryType < Types::BaseObject
field :tweets,
[Types::TweetType],
null: false,
description: "Returns a list of all tweets"
field :user,
Types::UserType,
null: false,
description: "Returns a list of all users" do
argument :id, ID, required: true
end
def tweets
Tweet.all
end
def user(id:)
User.find(id)
end
end
end
GraphQL has a first-class way to factor dynamic values out of the query, and pass them as a separate dictionary (variables). You would use syntax similar to that below, and can read more about it here.
query User($id: Int) {
user(id: $id) {
username
email
tweets(userId: $id) {
content
}
}
}

How to stop DataMapper from double query when limiting columns/fields?

I'm not sure if I'm at fault here or if my approach is wrong with this.
I want to fetch a user (limiting columns/fields only to name, email, id):
#user = User.first(:api_key => request.env["HTTP_API_KEY"], :fields => [:id, :name, :email])
The output in the command line is correct as follows:
SELECT "id", "name", "email" FROM "users" WHERE "api_key" = '90e20c4838ba3e1772ace705c2f51d4146656cc5' ORDER BY "id" LIMIT 1
Directly after the above query, I have this code:
render_json({
:success => true,
:code => 200,
:user => #user
})
render_json() looks like this, nothing special:
def render_json(p)
status p[:code] if p.has_key?(:code)
p.to_json
end
The problem at this point is that the #user variable contains the full user object (all other fields included) and DataMapper has made an additional query to the database to fetch the fields not included in the :fields constraint, from the logs:
SELECT "id", "password", "api_key", "premium", "timezone", "verified", "notify_me", "company", "updated_at" FROM "users" WHERE "id" = 1 ORDER BY "id"
My question is this: how do I stop DM from performing the additional query? I know it has to do with it's lazy loading architecture and that returning the #user variable in JSON assumes that I want the whole user object. I particularly don't want the password field to be visible in any output representation of the user object.
The same behaviour can be seen when using DM's own serialisation module.
I think you should use an intermediate object for json rendering.
First, query the user from database :
db_user = User.first(:api_key => request.env["HTTP_API_KEY"], :fields => [:id, :name, :email])
Then, create a "json object" to manipulate this user :
#user = { id: db_user.id, name: db_user.name, email: db_user.email }

Resources