Is it possible to restrict user to access a list but the list is accessible via Code.+ sharepoint 2007 - sharepoint-2007

I want to restrict users from accessing a list.
I have a custom webpart that accesses that list. But if I restrict the access, the code also cannot access it and throws exception.
So is there any way out so that user cannot access the list through browser but the Webpart accessed by the user can?

Yes, the best way is to open the containing site-collection with the system account:
SPWeb ctxWeb = SPContext.Current.Web;
using (SPSite adminSite= new SPSite(ctxWeb.Site.ID, SPUserToken.SystemAccount))
{
using (SPWeb adminWeb = adminSite.OpenWeb(ctxWeb.ID))
{
SPList adminList = adminWeb.Lists["TheRestrictedList"];
}
}
Every object retrieved from a site collection opened with a certain user token behaves as the given user is directly accessing the element.
Since we are opening the SPSite with the system account token, we have full control on the objects regardless the logged-in user.

Related

Dynamic redirect url from google console - oAuth

I have created a MVC/API project to enable external authentication and worked fine for my local host url. However, I need to achieve the below.
I am supporting multi tenancy (same app service and different DB), so each tenant has to connect different DB based on the custom param in the MVC url
Ex: https://localhost/tenant1, .../tenant2, .../tenant3 etc (not going with separate subdomain at this point)
I am not sure if the Google Console supports the wildcard url as a return ur and not sure how to achieve that in MVC code (Ex:http://localhost/* OR {0} .. something like that. (So dynamic input parameter will be returned back from google)
I am reading and attempting some solutions. Will update the answer here once i get the complete solution. In the meantime if anyone has any suggestions, please help me.
UPDATE 1:
I have updated my source code as follows:
Create session object before redirecting to the external login
System.Web.HttpContext.Current.Session["Tenant"] = "tenantname";
After callback read the tenant details and save in the session for subsequent DB calls based on the tenant name
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
return RedirectToAction("Login");
}
if (System.Web.HttpContext.Current.Session["Tenant"] != null)
{
string sessionObj = System.Web.HttpContext.Current.Session["Tenant"] as String;
}
This is a common requirement, and is easily solved. There are two components.
Firstly, regardless of which of your many URLs your application lives at (myapp.com/tenant1, /tenant2, etc) you have a single redirect URL (eg myapp.com/oauthredirect).
Secondly, when starting the OAuth dance (https://developers.google.com/identity/protocols/OAuth2WebServer#redirecting), you can specify a state parameter which will be passed into your oauthredirect routine (eg. as state=tenant1). You can then use this to create a redirect back to the appropriate site URL once you have finished your user registration tasks.
Be careful when specifying your redirect URLs into the developer console. They must be a character-by-character match with the actual URL. So, foe example, you will need to specify both http://myapp.com/oauthredirect and https://myapp.com/oauthredirect. I've always found it quite useful to create a local entry in /etc/hosts (or the windows equivalent) so your localhost is also resolved by eg. http://test.myapp.com
Authorized redirect URIs For use with requests from a web server. This
is the path in your application that users are redirected to after
they have authenticated with Google. The path will be appended with
the authorization code for access. Must have a protocol. Cannot
contain URL fragments or relative paths. Cannot be a public IP
address.
http://localhost/google-api-php-client-samples/Analytics/Oauth2.php
http://localhost/authorize/
You can have as many of them as you want but the wild card is not going to work.

Deployd : Most secure, most elegant way to get all objects in a specific collection created by the logged-in user?

I think the title pretty much says it all... Brand new to Deployd, so any pointers about how best to go about this are appreciated.
To get the objects in a collection created by the user (I assume you're using the javascript library dpd.js):
// Get the current user:
var currentUser;
dpd.users.me(function(result, error) {
currentUser = result;
});
// query your collection with your currentUser id as parameter
dpd.yourcollection.get({creator:currentUser.id}, function(result) {
// Do something with the result
console.log(result);
});
Your collection should have a property "creator" that contains the id of the user who created the object (*).
Then, to secure your backend, go to the dashboard, in the ON_GET tab of your collection and secure it with this code:
cancelUnless(isMe(this.creator), "You have to be the creator to view this item", 401);
More info about cancellUnless() and isMe() here:
http://docs.deployd.com/docs/collections/reference/event-api.md#s-cancelIf%28%29,%20cancelUnless%28%29-764
The good practice to secure your collections is to allow queries only if user is logged:
cancelUnless(me,"You have to be connected to view this item", 401);
Users collections should be particularly well secured (allow ON_PUT only by admin or something like that).
*: to automatically store the currentUserId in the creator property, you could also add this in the ON_POST event in the dashboard:
this.creator = me.id;
More info here: http://docs.deployd.com/docs/collections/reference/event-api.md#s-me-764
As of version 0.8.9, event ONBEFOREREQUEST exists and you could just put this code in there:
cancelUnless(me);
query.creator = me.id;
This means that for every request sent to that endpoint, creator key would be queried to have the currently logged in user's id. If there's not currently logged in user, the request is canceled.

display view regarding to authentication?

When it comes to display a view regarding to authentication (view displayed depending to the visitor if he's a user or not). I face many choices. So I need your help to show me how i deal with such situation :
Using 2 views (one for the users and other for visitors), or just one view.
using 2 actions (one with authorize filter and the other without), or just one action.
And why the choices you suggest is better ?
You don't have to not use Authorize attribute. It's main function is to setup the User in the context, and then by default, it also checks that they are logged in. However, this last part can be overridden by using the AllowAnonymous attribute as well:
[Authorize]
[AllowAnonymous]
public ActionResult SomeView()
{
...
}
So, now your view will have a User to play with, and you can dynamically present different pieces of the view using that based on auth status:
#if (User.IsAuthenticated)
{
<p>Logged in</p>
}
else
{
<p>Anonymous</p>
}
EDIT (for clarification)
The Authorize attribute actually does two distinct things for you. First, it setups all the machinery for recognizing a user: reads the cookie or whatever, checks the authentication status, pulls in the user's info, if they are authenticated, etc. Second, it validates that the user is in fact logged in. Using AllowAnonymous skips this second part and allows anyone, logged in or not, to access the view, BUT and this is key, you still need the first part to know stuff like whether you have an authenticated user or not.
So, simply, using both the Authorize and AllowAnonymous attributes together means essentially, "see if the user is logged in, but don't require it to access this view". That allows anonymous users to still reach the page, but enables you to still deliver unique or different content to an actual logged in user.

Asp Net MVC Membership - Retrieving access rules for Roles. Is there how?

Is there a way to retrieve all access rules from a specific Role?
As roles are just flagged at the top of an action or on top of the whole class I canĀ“t find a way to retrieve this information unless I read and parse the whole file and after that find a way to link this [authorization] tag to a group.
Thanks
No there is no builtin way. Its even impossible, because you might check for Roles in your code (actions/views) as well.
And how should the list of access rules be returned?
For example, how should an algorithm return / name this access rule in a view:
#if(User.IsInRole("SomeRole") {
<div>
Show some html only visible for users in SomeRole
</div>
}
You have to administer the list of your application defined access rules by yourself - i list will be very specific for your app.
Of cause, when you just use the Authorize attribute, you could generate a list of action methods accessible for a given role by reflecting over all controller classes.

Where to store common action parameter data in asp.net mvc application

Our web application needs one common parameter in every action method.
In our case it is the customer account id and we need to support the following scenarios
a. A group of users might have the same account id which can be derived from the user profile.
b. Customer Support team should be able explicitly supply the account id of a customer and also should be able to switch the account on any page
We are trying to not to use asp.net session to store this kind of data.
Are there any other options to store and manage this kind of common parameter data?
Write it out as an ecrypted value to hidden field on your master page and supply the value to every view. When the user is in a a customer role, place a change account "control" on the page that is able to retrieve and update the account data -- via AJAX, perhaps -- to change the current account id. It might be easiest to do this with a custom base controller which gets the data via the ValueProvider directly and stores it as a property on the page rather than having it be a parameter to every method.
Use Routing for the value. So if you need to change the id you can use another URL or post it as a parameter.
Whenever you need the value just ask the ValueProvider for it.
In case it is blank - use the one from user profile.
Of course you'd better write small method that will do just that:
// Register route like:
route.MapRoute("ProvidesAccountId", "{controller}/{id}/account{accountId}/{action}.aspx")
// Property on the base controller
protected Account CurrentAccount {
get {
var accountId = ValueProvider.GetValue<int?>("accountId"); // GetValue is just a helper
if (accountId.HasValue)
return YourRepositor.GetAccountBy(accountId.Value);
return CurrentUser.Account;
}
}
Not to use current user's account hit the URL: Profile/123/account/Edit.aspx
To use another account you can hit the URL: Profile/123/account-456/Edit.aspx
You get the idea.
Cheers,
Dmitriy.

Resources