not able to add proper rule for firebase custom claim - ruby-on-rails

I have created an auth token using Firebase documentation for ruby but then when I am trying to access the custom claim in the data security rules it does not work.
my JWT creation code looks something like this
$service_account_email = "service-account#my-project-abc123.iam.gserviceaccount.com"
$private_key = OpenSSL::PKey::RSA.new "-----BEGIN PRIVATE KEY-----\n..."
now_seconds = Time.now.to_i
payload = {:iss => $service_account_email,
:sub => $service_account_email,
:aud => "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
:iat => now_seconds,
:exp => now_seconds+(60*60), # Maximum expiration time is one hour
:uid => uid,
:claims => {:modify_vessels => true}}
jwt_token = JWT.encode payload, private_key, "RS256"
render json: { :status => "ok", :email => usr, :jwt_token => jwt_token, :uid => uid } and return
I have tried below rules for accessing claims object but none of them work
{
"rules": {
"vessels" : {
"$uid" : {
".read":"auth.token.modify_vessels === true",
".write":"auth.token.modify_vessels === true"
}
}
}
}
and
{
"rules": {
"vessels" : {
"$uid" : {
".read":"auth.claims.modify_vessels === true",
".write":"auth.claims.modify_vessels === true"
}
}
}
}
Please Note :- I can do auth.uid and it works
Any help on this will be helpful

Related

Rails + Google Calendar API events not created

I created rails web app. When user make some actions, my app must create new event in my Google Calendar. For my task I choose server-to-server authorization.
I wrote next ruby code:
client = Google::APIClient.new({:application_name => "Rails calendar",
:application_version => "1.0"})
keypath = Rails.root.join('config','google_secrets.p12').to_s
key = Google::APIClient::PKCS12.load_key(keypath, "notasecret")
# generate request body for authorization
client.authorization = Signet::OAuth2::Client.new(
:token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
:audience => 'https://accounts.google.com/o/oauth2/token',
:scope => 'https://www.googleapis.com/auth/calendar',
:issuer => '***',
:signing_key => key).tap{ |auth| auth.fetch_access_token! }
api_method = client.discovered_api('calendar','v3').events.insert
#meeting_data = {
guests: [{email: '***#gmail.com'}, {email: '***#gmail.com'}],
start_time: "2016-08-10T19:00:00+03:00",
end_time: "2016-08-10T20:00:00+03:00",
topic: "Test meeting",
messages_thread_id: 2
}
event = {
summary: #meeting_data[:topic],
start: {
dateTime: #meeting_data[:start_time],
time_zone: 'Asia/Jerusalem'
},
end: {
dateTime: #meeting_data[:end_time],
time_zone: 'Asia/Jerusalem'
},
attendees: #meeting_data[:guests],
visibility: 'private',
reminders: {
useDefault: true,
}
}
result = client.execute(:api_method => api_method,
:parameters => {calendarId: 'primary'},
:body => JSON.dump(event),
:headers => {'Content-Type' => 'application/json'})
puts result.data.as_json
But when i try to use that code and server return me result as JSON, if I go on url of "created" event, google show me message that event does not exist.
{"kind"=>"calendar#event", "etag"=>"***", "id"=>"***", "status"=>"confirmed", "htmlLink"=>"https://www.google.com/calendar/event?eid=***", "created"=>"2016-08-04T11:54:46.000Z", "updated"=>"2016-08-04T11:54:46.327Z", "summary"=>"Test meeting", "creator"=>{"email"=>"***", "self"=>true}, "organizer"=>{"email"=>"***", "self"=>true}, "start"=>{"dateTime"=>"2016-08-10T16:00:00Z", "timeZone"=>"Asia/Jerusalem"}, "end"=>{"dateTime"=>"2016-08-10T17:00:00Z", "timeZone"=>"Asia/Jerusalem"}, "visibility"=>"private", "iCalUID"=>"***", "sequence"=>0, "attendees"=>[{"email"=>"***#gmail.com", "displayName"=>"***", "responseStatus"=>"needsAction"}, {"email"=>"***#gmail.com", "displayName"=>"***", "responseStatus"=>"needsAction"}], "reminders"=>{"useDefault"=>true}}
I faced with same problem. Needed give write rules to "client_email" for calendar.
You use organization calendar. Thats why only organization admin can do it.

Logstash twitter config - search only people i follow?

Does anyone know how i can modify this logstash so that it only watches feeds of those my twitter account follows?
input {
twitter {
# add your data
consumer_key => ""
consumer_secret => ""
oauth_token => ""
oauth_token_secret => ""
full_tweet => true
keywords => ["pizza"]
}
}
output {
elasticsearch_http {
host => "localhost"
index => "twitter"
index_type => "tweet"
}
}

Invalid authorization name/value {x-li-auth-token}/{NAME_SEARCH:tdLy}

Im working on LinkedIn invitation API but I can't send the invitation to user, using people id from search result
Seached people result
**
"{\"people\":{\"total\":2,\"all\":[{\"api_standard_profile_request\":{\"headers\":{\"total\":1,\"all\":[{\"name\":\"x-li-auth-token\",\"value\":\"NAME_SEARCH:tdLy\"}]},\"url\":\"http://api.linkedin.com/v1/people/tp2Z82Xa_I\"},\"first_name\":\"Dev\",\"id\":\"tp2Z8sad2Xa_I\",\"last_name\":\"ruby\"},{\"api_standard_profile_request\":{\"headers\":{\"total\":1,\"all\":[{\"name\":\"x-li-auth-token\",\"value\":\"NAME_SEARCH:ZbY6\"}]},\"url\":\"http://api.linkedin.com/v1/people/TyaEtFbxzL\"},\"first_name\":\"dev\",\"id\":\"TyaEtFbsdsaxzL\",\"last_name\":\"ruby\"}]}}"**
And the invite methods following this
def send_invitation(options)
path = "/people/~/mailbox"
message = {
"recipients" => {
"values" => [
{
"person" => {
"_path" => "/people/id=#{options[:email]}",
"first-name" => options[:first_name],
"last-name" => options[:last_name]
}
}]
},
"subject" => "Invitation to connect.",
"body" => options[:body],
"item-content" => {
"invitation-request" => {
"connect-type" => "friend",
"authorization" => {"name" => "x-li-auth-token","value" => "NAME_SEARCH:tdLy"}
}
}
}
post(path, MultiJson.dump(message), "Content-Type" => "application/json")
end
So I am getting this error when I call client.send_invitation(options):
LinkedIn::Errors::GeneralError: (400): Invalid authorization name/value {x-li-auth-token}/{NAME_SEARCH:tdLy}
Working Fine
The name should be NAME_SEARCH and the value should be tdLy instead of what i have asked above. i have to split the value out of the oauth headers.
"authorization" => {:"name" => 'NAME_SEARCH',:"value" => 'tdLy'}

Play 2.0 Framework, using a BodyParser with an authenticated request

I'd like to be able to use a BodyParser on an authenticated request and I'm having trouble figuring out how to do that if my Authentication is set up like the ZenTasks example.
My authentication method,
def IsAuthenticated(f: => String => Request[AnyContent] => Result) = {
Security.Authenticated(username, onUnauthorized) { user =>
Action(request => f(user)(request))
}
}
def HasRole(role: List[String])
(f: => String => Request[AnyContent] => Result) = IsAuthenticated {
user => request => if (role.contains(getRole(user))) {
f(user)(request) // This function returns the result.
} else {
Results.Forbidden
}
}
My controller method,
def controller = HasRole(List("admin")) { user => _ => {
Action(parse.temporaryFile){ implicit request =>
request.body.moveTo(new File("/tmp/filepath"))
Redirect(routes.home)
}
}
This is the error I'm seeing,
[error] found : play.api.mvc.Action[play.api.libs.Files.TemporaryFile]
[error] required: play.api.mvc.Result
[error] Action(parse.temporaryFile){ implicit request =>
[error] ^
Here is a related question: parse.json of authenticated play request
This person found a workaround, and I believe there is one for the temporary file example as well, but I'd like to know how (or why) what I'm doing is not working.
I believe I've figured this out, mainly because I left some details out of the original question that I did not realize were important.
The problem was that I was wrapping an Action { Action { } } because the IsAuthenticated method already had a call to the Action function inside it. What I ended up doing was overloading the IsAuthenticated function with a method that took BodyParser as a parameter. Because I am using the TemporaryFile method, which is not a subclass of AnyContent, I also had to change the request type.
Now, this is what my Secured trait looks like:
def IsAuthenticated(f: => String => Request[Any] => Result) = {
Security.Authenticated(username, onUnauthorized) { user =>
Action(request => f(user)(request))
}
}
def IsAuthenticated(b: BodyParser[Any] = parse.anyContent)
(f: => String => Request[Any] => Result) = {
Security.Authenticated(username, onUnauthorized) { user =>
Action(b)(request => f(user)(request))
}
}
def HasRole(role: List[String])(b: BodyParser[Any] = parse.anyContent)
(f: => String => Request[Any] => Result) = IsAuthenticated(b) {
user => request => getRole(user) match {
case Some(r) if role.contains(r) => f(user)(request)
case _ => Results.Forbidden
}
}
And this is what my controller looks like:
def controller = HasRole(List("admin"))(parse.temporaryFile) { user => request =>
request.body match {
case b:TemporaryFile => b.moveTo(new File("/tmp/file"))
case _ => Status(404)
}
}
Hope this helps someone else!

How to "trasform" an array of hash so that you can customize logic to access its data?

I am using Ruby on Rails 3 and I would like to "trasform" the following array so that I can use my custom logic to access its data.
This is the original array from which I have to build a new one
[
{
"account" => {
"id" => 45,
"name" => "Test_name",
"..." => ..."
}
},
{
"other" => {
"sub_other" => {...}
}
}
]
I would like to trasform the above array so that I can do in my controller something like
array_name[45]
# => {
"name" => "Test_name",
"..." => ..."
}
but only for the account hashs. The other hash should remain untouched.
How can I proceed to build the new array?
If I understand your requirements correctly, I think you are better off constructing a hash from account id to account data. Perhaps something like this will work:
arr = [
{
"account" => {
"id" => 45,
"name" => "Test_name",
"..." => "..."
}
},
{
"other" => {
"sub_other" => "..."
}
}
]
account_hashes = arr.select {|item| item.keys.first == "account"}
answer = account_hashes.inject({}) do |acc, item|
acc[item["account"].delete("id")] = item["account"]
acc
end

Resources