Why does DocumentFile.getParentFile() return null after it is created with a Uri? - storage-access-framework

Code:
DocumentFile dfNew = dfDirectory.createFile("video/mp4", "foo.mp4");
//dfNew.getParentFile() is NOT null.
DocumentFile dfNewCopy = DocumentFile.fromSingleUri(activity, dfNew.getUri());
//dfNewCopy.getParentFile() IS null. Otherwise, dfNewCopy works fine
Why is a DocumentFile created from a DocumentFile's Uri different from the original in this regard?

Storage Access Framework has been designed in days of API 16 for a very narrow use case (implementing the first official Android file picker). DocumentsProvider lacked a lot of useful functionality back then. Many more methods were added in following versions of platform.
The method, required to check whether one Uri is parent of another Uri (isChildDocument) has been added in API 21.
The method for getting parent of Uri (findDocumentPath) has been added in API 26 (Oreo).
DocumentFile can not return the parent Uri on older platforms, because the system itself does not provide it there.

Related

Get mediaId in Umbraco

In Umbraco 7, i am trying to get the Id of a Image on the page. I am using;
#Umbraco.Field("myImage")
But, it does not return the mediaId. Instead it returns;
Umbraco.Web.PublishedCache.XmlPublishedCache.PublishedMediaCache+DictionaryPublishedContent
What am i doing wrong?
There are basically 3 ways:
#CurrentPage.myImage
#Model.Content.GetPropertyValue<int>("myImage")
Using ModelsBuilders you can access it as #Model.myImage
The first method should be avoided because Umbraco will be dropping support for Dynamics (see https://our.umbraco.org/Documentation/Reference/Common-Pitfalls/#dynamics).
ModelsBuilder is my preferred way for accessing published content properties as it provides a strongly typed model based on your Document Type. But it requires some setup. See https://24days.in/umbraco-cms/2016/getting-started-with-modelsbuilder/ for a great intro.
The final option is accessing the properties from #Model.Content (IPublishedContent and unlike the Dyanamics method, will continue to be supported in the next version of Umbraco.
In Umbraco 7 you can use #CurrentPage. You just need to use:
#CurrentPage.myImage
instead of #Umbraco.Field("myImage") and it will return mediaId
I have just upgraded to version 7.6.12 and there are some updates with the media picker. To use it as you done you should select the obsolete mediapicker in the backoffice otherwise Model.Content.GetPropertyValue<IPublishedContent>("myImage").Url should work. If you using the UmbracoHelper, you could write UmbracoHelper.AssignedContentItem.GetPropertyValue<IPublishedContent>(propertyName, recursive).Url
https://our.umbraco.org/documentation/getting-started/backoffice/property-editors/built-in-property-editors/

Missing property in resourceVisualization in Trending endpoint

The documentation for resourceVisualization resource type (Trending endpoint) says that one of the properties that gets returned as part of the object is type.
However, when I use Graph Explorer to test the endpoint I don't see this property. Is it going to be added soon?
We have that identified and we are working on updating the API schema to have that property available by the end of next week.
Mario

ADALiOS - how to refresh accessToken silently?

I'm using ADALiOS v3.0.0-pre.2 to connect to Azure AD B2C and authorize a given user. I successfully obtain an accessToken for the user, who gets prompted with UI to login in the process. I use the acquireTokenWithScopes method on ADAuthenticationContext instance to do so.
Somewhere down the line, I want to make sure that the accessToken I obtained earlier is still valid and hasn't been revoked. So, I use acquireTokenSilentWithScopes to check. However, I get an immediate error back saying:
Error raised: 10. Additional Information: Domain: ADAuthenticationErrorDomain Details: The user credentials are need to obtain access token. Please call the non-silent acquireTokenWithResource methods.
What's the right usage of this API such that the token gets silently refreshed or throws an error only when it has been revoked on the server side?
I've managed to beat acquireTokenSilentWithScopes into submission by making the following changes to ADALiOS v3.0.0-pre.2.
Change #1:
ADUserIdentifier has the following class method:
+(BOOL) identifier:(ADUserIdentifier*)identifier matchesInfo:(ADProfileInfo*)info
In it, there are the following lines of code:
NSString* matchString = [identifier userIdMatchString:info];
if (!matchString || [matchString isEqualToString:identifier.userId])
{
return YES;
}
For one reason or another, matchString can sometimes come back as NSNull and calling isEqualToString: method on it will throw. I changed it thusly:
id matchString = [identifier userIdMatchString:info];
if (!matchString || ![matchString isKindOfClass:[NSString class]] || [matchString isEqualToString:identifier.userId])
{
return YES;
}
This seems like a legit bug in the framework that's worth fixing.
Change #2:
When a token is received from AD, ADALiOS tries to store that value in the cache. At some point, it calls ADTokenCacheStoreItem's userCacheKey property, which is defined as follows:
-(NSString*)userCacheKey
{
switch (_identifierType)
{
case OptionalDisplayableId:
case RequiredDisplayableId:
return _profileInfo.username;
case UniqueId:
return _profileInfo.subject;
}
}
In my case, I use RequiredDisplayableId to identify users. In the switch statement above, that translates to _profileInfo.username, which, in turn, returns the preferred_username value from the user profile dictionary. For me that value is not set. So, userCacheKey returns NSNull and the caching mechanism fails.
The values that are set in the user profile dictionary are name and tid. This could be a server misconfiguration, but I worked around the issue by changing the return value of this method to _profileInfo.friendlyName (which maps to name in the user profile dictionary).
Change #3:
The ADKeychainTokenCacheStore, which I use as the concrete ADTokenCacheStoring cache of choice, exposes a sharedGroup property that allows multiple applications to share common keychain secrets. By default, sharedGroup is set to com.microsoft.adalcache. However, since the class is currently private, there is no way to override this value. Also, having that value set requires the iOS app to declare the shared group name in its entitlements. Without these entitlements properly configured, setting values into the keychain fails. So, to work around this issue, I manually set the default sharedGroup value to nil in the ADKeychainTokenCacheStore class itself. I suspect eventually this class will be exposed by the framework as public, but currently that's not the case so I had to hack into it.
Change #4
When I request an auth token from the AD server via the ADALiOS framework, I do so using a policy and a set of scopes. The framework code uses this policy/scope pair to create a lookup key and see if any tokens for that key have already been cached. If none are found, the code contacts the server as expected. Once the server returns an auth token, the framework attempts to cache the value. It constructs a brand new policy/scope key object. However, this time, it uses the policy and scope values that are returned by the server, not the ones I passed in. And, for some reason, the server returns those values to nil. As a result, the new policy/scope key that gets constructed for storage is valid but different from the one I used to look up the cached token initially. So, while the caching operation succeeds, next time I try to look up the auth token using my valid policy/scope pair, the lookup fails.
This may, once again, be a server misconfiguration issue.
Regardless, to fix the problem, I now reset the policy and scope values in the response from the server to the original values I used to generate the server request in the first place. This happens in the following method in ADAuthenticationContext(TokenCaching):
- (void)updateCacheToResult:(ADAuthenticationResult*)result
cacheInstance:(id<ADTokenCacheStoring>)tokenCacheStoreInstance
cacheItem:(ADTokenCacheStoreItem*)cacheItem
withRefreshToken:(NSString*)refreshToken
After all these changes, getting the AD auth token and refreshing it silently seems to work as expected. I'm a little worried about how much I needed to hack into the codebase to make it work. It would be helpful if some MS folks could direct me as to whether these changes were warranted or whether there is a more straight-forward solution.
UPDATE:
It turns out that you don't need to hack into ADKeychainTokenCacheStore directly (change #3 above). The ADAutheticationSettings class exposes a method for you to do so thusly:
[[ADAuthenticationSettings sharedInstance] setSharedCacheKeychainGroup:nil];
I'm Brandon Werner from the Azure Active Directory team. I answered this question here: https://stackoverflow.com/a/44170226/1232116 for the specific question asked.

What is available for limiting the use of extend when using Breezejs, such users cant get access to sensitive data

Basically this comes up as one of the related posts:
Isn't it dangerous to have query information in javascript using breezejs?
It was someone what my first question was about, but accepting the asnwers there, i really would appreciate if someone had examples or tutorials on how to limit the scope of whats visible to the client.
I started out with the Knockout/Breeze template and changed it for what i am doing. Sitting with a almost finished project with one concern. Security.
I have authentication fixed and is working on authorization and trying to figure out how make sure people cant get something that was not intended for them to see.
I got the first layer fixed on the root model that a member can only see stuff he created or that is public. But a user may hax together a query using extend to fetch Object.Member.Identities. Meaning he get all the identities for public objects.
Are there any tutorials out there that could help me out limiting what the user may query.?
Should i wrap the returned objects with a ObjectDto and when creating that i can verify that it do not include sensitive information?
Its nice that its up to me how i do it, but some tutorials would be nice with some pointers.
Code
controller
public IQueryable<Project> Projects()
{
//var q = Request.GetQueryNameValuePairs().FirstOrDefault(k=>k.Key.ToLower()=="$expand").Value;
// if (!ClaimsAuthorization.CheckAccess("Projects", q))
// throw new WebException("HET");// UnauthorizedAccessException("You requested something you do not have permission too");// HttpResponseException(HttpStatusCode.MethodNotAllowed);
return _repository.Projects;
}
_repository
public DbQuery<Project> Projects
{
get
{
var memberid = User.FindFirst("MemberId");
if (memberid == null)
return (DbQuery<Project>)(Context.Projects.Where(p=>p.IsPublic));
var id = int.Parse(memberid.Value);
return ((DbQuery<Project>)Context.Projects.Where(p => p.CreatedByMemberId == id || p.IsPublic));
}
}
Look at applying the Web API's [Queryable(AllowedQueryOptions=...)] attribute to the method or doing some equivalent restrictive operation. If you do this a lot, you can subclass QueryableAttribute to suit your needs. See the Web API documentation covering these scenarios.
It's pretty easy to close down the options available on one or all of your controller's query methods.
Remember also that you have access to the request query string from inside your action method. You can check quickly for "$expand" and "$select" and throw your own exception. It's not that much more difficult to block an expand for known navigation paths (you can create white and black lists). Finally, as a last line of defense, you can filter for types, properties, and values with a Web API action filter or by customizing the JSON formatter.
The larger question of using authorization in data hiding/filtering is something we'll be talking about soon. The short of it is: "Where you're really worried, use DTOs".

Jira issues in JSON format (Need to know thw classes and functions called by I am trying to use the REST API "api/2.0.alpha1/issue/{issueKey}"

I am trying to use the REST API api/2.0.alpha1/issue/{issueKey} .
Reference: http://docs.atlassian.com/jira/REST/4.4.3/#id2413591
I would get all issue id's from rest/api/2.0.alpha1/search
Using these issue IDs get all issues in JSON format.
But as I am using localhost (local Machine) I do not want to make network calls and increase network traffic. Hence I wanted to know which class in JAVA does these URIs call so that I can directly call these classes to get the issues in JSON format.
Basically I want all the issues in JSON format without network calls.
OR
I also have all the issue retrieved in issues object but not in JSON format. How can I convert that into JSON format?
I have found the following code from JIRA:
#GET
#Path ("/{issueKey}")
public Response getIssue(#PathParam ("issueKey") final String issueKey)
{
final Issue issue = getIssueObject(issueKey);
final IssueBean bean = createIssue(issue);
return Response.ok(bean).cacheControl(never()).build();
}
You could search the source code for the #GET references or use the REST API browser (https://developer.atlassian.com/display/RAB/Overview+of+the+Atlassian+REST+API+Browser)
but accessing the classes from Java probably means that you need to be running in the same class loader as JIRA or using a plugin.
Have you measured the overhead of the calls to make sure that you are not optimizing prematurely?

Resources