HasMany relation entry point unauthorized on Loopback - acl

New to Loopback, I tried to make a simple API with a user model and a todo model.
The user model, named Todoer,is based on the built-in User model. create a todoer, login, logout, etc. works like a charm.
The Todo model is based on PersistedModel with no special ACLs on it for the moment.
I made a Belongs To relation from Todo model to Todoer model to have an ownership.
I made also a HasMany relation from Todoer to Todo to be able to retrieve all the todos of a user through the endpoint GET /Todoer/{id}/todos
With a todoer logged in, with the good token and id, I can easily have responses from Todoer endpoints reserved for logged users, like GET /Todoer/{id} for example, so I'm sure the authentication mechanism is working well.
But each time I want to hit GET /Todoer/{id}/todos, I only obtain a error message telling I'm not authorized. I'm always sure I gave the good token and Todoer Id obtained at login.
Even if I make a big ACL telling OK to everything to all on the Todoer model, it happens the same.
What did I miss ? I can't figure it out...
Thank you for your help...

You need to take into account ACLs of a built-in Usermodel. You are actually running into its general DENY ACL rule. It takes priority over your general ALLOW ACL rule (docs on ACL rule precedence).
You can write more specific ACL rule to get pass it (docs on Accessing related models).
{
"accessType": "*",
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW",
"property": "__get__todos"
}
Another option, which might be in this case more convenient and safe, is to use a dynamic $owner role on Todo itself (docs on Dynamic roles).
{
"accessType": "*",
"principalType": "ROLE",
"principalId": "$owner",
"permission": "ALLOW"
}
If you want to understand what is happening regarding to ACLs in your application, it's very useful to set a DEBUG environment variable to loopback:security:* to enable quite extensive security logging.

Related

Unable to extend schema within a verified sub domain directory

I live in an enterprise environment where most of our production domains are currently non-routable (e.g. .local).
I tried extending the schema but since the non-routable cannot be verified and the default .onmicrosoft I don't think could either. My enterprise allows me to easily create subdomains so I attached it and verified for testing purposes and ran into the same verified domain error.
Per the documentation, I should be able to either us the ID of my domain name or just the scheme name and get 8 random-alpha-chars added. Neither approach works in this case.
POST: https://graph.microsoft.com/v1.0/schemaExtensions
{
"id": "idmdomain.sub.domain.net_Owners",
"description": "Owners of the group",
"targetTypes": [
"Group"
],
"properties": [{
"name": "PrimaryOwners",
"type": "String"
},
{
"name": "SecondaryOwners",
"type": "String"
}
]
}
Message Received:
{
"code": "BadRequest",
"message": "Your organization must own the namespace idmdomain.sub.domain.net as a part of one of the verified domains.",
"request-id": "1c7363f9-d54b-408a-8b29-2c0d2a94280a",
"date": "2018-03-22T21:47:22"
}
From the documentation:
If you already have a vanity .com,.net, .gov, .edu or a .org domain that you have verified with your tenant, you can use the domain name along with the schema name to define a unique name, in this format {domainName}_{schemaName}.
For example, if your vanity domain is contoso.com, you can define an id of, contoso_mySchema. This is the preferred option.
So in your example, idmdomain.sub.domain.net_Owners should simply be domain_Owners. It shouldn't include idmdomain, sub, net or any ..
Thank you Marc for pointing me in the correct direction. Even though my app had the correct delegated permissions (Directory.AccessAsUser.All) I now understand that I needed to execute this change in the user context instead of application as application is not supported.
For those that come behind me {domainName}_{schemaName} works if you validate your domain, if dont and you just leave schemename then the generated guid works as documented. I recommended reviewing the two links below as they were what finally unlocked the puzzle for me.
Helped me understand how this is working (authentication vs authorization)
https://developer.microsoft.com/en-us/graph/docs/concepts/rest
Helped me setup postman to quickly validate
https://blogs.msdn.microsoft.com/softwaresimian/2017/10/05/using-postman-to-call-the-graph-api-using-azure-active-directory-aad/
I should add for the postman route, a few changes...
Auth URL
https://login.microsoftonline.com/yourtennantid/oauth2/authorize?resource=https%3A%2F%2Fgraph.microsoft.com
Access Token URL
https://login.microsoftonline.com/yourtennantid/oauth2/token
Scope = Directory.AccessAsUser.All

AccessDenied: Required claim values are not provided when accessing education/users endpoint

I'm unable to access the education/users endpoint but I am able to access other endpoints (education/classes, education/schools).
Whenever I try to get a list of all users, I get the following error:
{
"error": {
"code": "AccessDenied",
"message": "Required claim values are not provided.",
"innerError": {
"request-id": "58c42204-440a-482c-b1e9-4c65bb413ed1",
"date": "2018-03-21T20:23:24"
}
}
}
When I try to make the call using the Graph Explorer, I'm given the following notice:
Failure - Status Code - Looks like you may not have the permissions for this call. Please modify your permissions.
Unfortunately, I get the same error after modifying my permissions.
If anyone has any idea why this might be happening, I would be very grateful for the help.
For app+user (delegate) permissions, the only supported scope for the /education/users collection on MSGraph is EduRoster.ReadBasic.
This supports getting an individual user's information, or information on lists of users within classes of which you are a member, but does NOT support browsing the entire set of users in a tenant, as it is deliberately a restricted scope.
If you need more than this, you would need to use app-only permissions, and sync the users into your own data store with EduRoster.Read.All, which would allow you to get all of the users.

Modify device - IoTAgentUL

I need to modify a registered device in IoTAgent UltraLight. With modify I mean add some attributes and delete others.
I also want to update the entity in Orion CB.
Is it possible to do that? How can I do that?
IoTAs (and the IoTA library in general), expose a north provisioning interface for device creation. The core idea is when you provision a device in the IoTA (directly, or through the IoTA Manager), an entity is automatically created in Context Broker. Such nothr provisioning interface allows for retrieval, removal and update, too.
Being said that, the south interface of the IoTAs is designed to only accept measures and command execution results from the devices. Thus, if a new attribute comes into play, and you provide values for that new attribute via an IoTA, a new attribute will not be appended at Context Broker; simply, this information will be droped.
In order to accept data regarding new attributes, first you'll have to use the above mentioned provisioning interface of the IoTAs, in particular the update device operation, in order to provision such new attribute; that will automatically append a new attribute to the entity at Context Broker level. From here on, values for the new attribute sent to the IoTA will be updated in Context Broker.
Such an update request looks like:
PUT http://iota_host:iota_port/iot/devices/<dev_id>?protocol=<protocol_type>
Fiware-Service: <service>
Fiware-ServicePath: <subservice>
{
"entity_type": <entity_type>,
"attributes": [ <new_active_attrs_if_any> ],
"lazy": [ <new_lazy_attrs_if_any> ],
"commands": [ <new_commands_if_any> ],
"statis_attributes": [ <new_static_attrs_if_any> ]
}
Sadly, already existent attributes cannot be removed, for the time being.

Consul 0.8 ACL migration - how to migrate

TLTR
How to migrate the pre 0.8 ACL permissions to 0.7.3?
Current setup
I am currently running an ACL enabled Consul 0.7.3 stack.
With Consul 0.8 ACLs will finally also include services and nodes, so that nodes / service (Consul) are not longer shown to anonymous users. This is exactly what I need. Today I tried to enable the new ACL "pre 0.8" using https://www.consul.io/docs/agent/options.html#acl_enforce_version_8
After doing so, my nodes could no longer authenticate against the master ( if authentication is the problem at all ).
I run the consul-network with gossip enabled, I have configured a acl_master_token:
"{acl_master_token":"<token>}"
and a token for the agents:
"{acl_token":"<token>}"
which all agents use / are configured with.
I have these ACL defaults:
{
"acl_datacenter": "stable",
"acl_default_policy": "deny",
"acl_down_policy": "deny"
}
and my Consul config looks like this:
{
"datacenter": "stable",
"data_dir": "/consul/data",
"ui": true,
"dns_config": {
"allow_stale": false
},
"log_level": "INFO",
"node_name": "dwconsul",
"client_addr" : "0.0.0.0",
"server": true,
"bootstrap": true,
"acl_enforce_version_8": true
}
What happens
When I boot, I cannot see my nodes/services using my token at all, neither the nodes/agents can register at the master,
Question
What is exactly needed to get the following:
All agents can see all nodes and all services and all KVs
Anonymous sees nothing, not KV, services or nodes (thats what is possible with 0.8 )
I looked at https://www.consul.io/docs/internals/acl.html "ACL Changes Coming in Consul 0.8" but I could not wrap my head around it. Should I now use https://www.consul.io/docs/agent/options.html#acl_agent_master_token instead of acl_token?
Thank you for any help. I guess I will not be the only one on this migration path and this particular interest, a lot of people are interested in this. You help all of them :)
It looks like the new node policy is preventing the nodes from registering properly. This should fix things:
On your Consul servers configure them with an acl_agent_token that has a policy that can write to any node, like this: node "" { policy = "write" }.
On your Consul agents, configure them with a similar one to the servers to keep things open, or you can give them a token with a more specific policy that only lets them write to some allowed prefix.
Note this gets set as the acl_agent_token which is used for internal registration operations. The acl_agent_master_token is used as kind of an emergency token to use the /v1/agent APIs if there's something wrong with the Consul servers, but it only applies to the /v1/agent APIs.
For "all agents can see all nodes and all services and all KVs" you'd add node read privileges to whatever token you are giving to your agents via the acl_token, so you'd add a policy like:
node "" { policy = "read" }
service "" { policy = "read" }
key "" { policy = "read" }
Note that this allows anyone with access to the agent's client interface to read all these things, so you want to be careful with what you bind to (usually only loopback). Or don't set acl_token at all and make callers pass in a token with each request.

API Issue While Adding Device Access to a User in SoftLayer via addBulkVirtualGuestAccess

I'm attempting assign a test user access to a device using the SoftLayer API. (Any referenced functions below are provided by the "SoftLayer_User_Customer" service)
When calling "addBulkVirtualGuestAccess" & "removeBulkVirtualGuestAccess" I am returned true in both cases.
When using "getAllowedVirtualGuestIds" I am returned an empty array, before and after execution of either the previously referenced functions. The test user does not contain any server access initially, so this is expected, however it is not expected after executing the "addBulkVirtualGuestAccess" call.
According to the documentation, true should only be returned in the case that this user already has access to that device, or for the removal function, when the user cannot use that device. There is a possibility perhaps the JSON body I am providing is not appropriate, if this is the case, please let me know.
Equivalent curl command:
echo '{"parameters":[[X,Y]]}' | curl -X POST -u $USERNAME:$KEY --data #- https://api.softlayer.com/rest/v3/SoftLayer_User_Customer/Z/addBulkVirtualGuestAccess.json
Where X & Y are device integer ID values and Z is the SoftLayer users ID of which the user is to be added to.
Any assistance would be appreciated.
=========================================================================
UPDATE
It appears I cannot create a comment to meet my reply length requirements, so I shall edit my answer instead.
Thanks for your reply, mcruz.
Your suggestion seemed to work, it appears that a user requires the permission "VIRTUAL_GUEST_VIEW" to be added a device via the addBulkVirtualGuestAccess function.
However it should be noted that similar methods of the same service User_Customer, have unexpected behaviours:
addBulkVirtualGuestAccess
Returns true when no device has been added to due users permissions. This is misleading and I would expect a user permission exception to be returned.
addVirtualGuestAccess
Can be used to add VMs individually to a user without the "VIRTUAL_GUEST_VIEW" permission. getAllowedVirtualGuestIds Will return no ID's when this is done, however getVirtualGuests will return the full image JSON data of the VM's added individually, the IDs can be extrapolated from there.
I've spent quite a bit of time debugging the above, I'm glad its finally resolved.
To aid future users of this service:
Can some of the unexpected behaviour outlined aboved of the
addVirtualGuestAccess method can be explained?
Can the addBulkVirtualGuestAccess method be updated to return an
exception if the user truely hasn't been added a device due to a
user permissions issue?
The SoftLayer API reference page makes no reference to the users
required permissions to apply a certain device, perhaps this should
be updated to display this?
Regards,
Paul Connolly
Please, verify if the user that you want to add the server access has the following ”permissions”: ”View Virtual Server Details”
To add this permission, please execute:
https://[username]:[apikey]#api.softlayer.com/rest/v3/SoftLayer_User_Customer/[user_id]/addPortalPermission
Method: POST
{
"parameters": [
{
"keyName": "VIRTUAL_GUEST_VIEW"
}
]
}
To get all available permissions, please review: SoftLayer_User_Customer_CustomerPermission_Permission::getAllObjects
Now, after reviewing the above permission available, please execute:
https://[username]:[apikey]#api.softlayer.com/rest/v3/SoftLayer_User_Customer/[user_id]/addBulkVirtualGuestAccess
Method: POST
Json Payload:
{
"parameters": [
[
18131945,
17071523
]
]
}
You can see the devices will be displayed when executing:
https://[username]:[apikey]#api.softlayer.com/rest/v3/SoftLayer_User_Customer/[user_id]/getAllowedVirtualGuestIds