How can i create a global variable in Symfony, but one that will never be cached?
I basically want to be able to get BaseForm token key anywhere in my app without the need to create a new instance of it every time..
Thanks!
You should create a static method and store the token you need in a static variable.
// /lib/form/BaseForm.class.php
protected static $token = null;
public static getToken(){
if(is_null(self::$token)){
$form = new BaseForm();
self::$token = $form->getCSRFToken();
}
return self::$token;
}
public static setToken($){
self::$token =
}
You use it then
BaseForm::getToken();
Related
I would like to use SpEL to handle method level security. I run into an issue where the data passed to the method is not enough to determine if a user has access. Here is an example
#RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
#ResponseStatus(HttpStatus.NO_CONTENT)
#PreAuthorize("#securityService.isAllowedAccessByCurrentUser(#.id)")
public void delete(#PathVariable("id") final Long id) {
service.delete(id);
}
Here, the id variable is the ID of some object. To get the owner ID of the object (which is what i want to pass in the spel expression), I would need to do something like:
service.findOne(id).getUser().getId();
How can I get that ID and use it in the SpEL expression?
Why need to so complicated? You can simply create another method to specifically check if the current user can delete an object given that object Id and make the #PreAuthorize refer to this method:
#Service
public class SecurityService{
#Autowired
private Service service
boolean isAllowToDeleteSomeObject(Long objectId){
SomeObject anObject = service.findOne(objectId);
//You should able to get the current user Id by SecurityContextHolder.getContext().getAuthentication().
//getCurrentUserId() simply encapsulate such codes for convenient.
Long currentUserId = getCurrentUserId();
if(anObject.getUser().getId().equals(currentUserId)){
return true;
}else{
return false;
}
}
}
Then you can refer to this method in SpEL:
#PreAuthorize("#securityService.isAllowToDeleteSomeObject(#.id)")
public void delete(#PathVariable("id") final Long id) {
}
One more follow up to Extract BearerToken from LinqToTwitter IAuthorizer
I am successfully using the Auth / Context / BearerToken with in my application however i wanted to now use the L2T library to Check on Rates. I need TwitterContext to do so, but I am now out of twitterCtx scope.
is it possible to set this up as a public class so I can access it from anywhere without the need to reauthorize?
Thank you in advance.
There are different ways to do this. Here are a couple where you can go the Singleton route or a factory method.
Note: There's debate on whether a Singleton is an appropriate pattern to use or whether a global reference to an object is even
appropriate at all, but that's isn't what you're asking.
public class TwitterContextService
{
static TwitterContext twitterCtx;
public static TwitterContext Instance
{
get
{
if (twitterCtx == null)
twitterCtx = CreateTwitterContext();
return twitterCtx;
}
}
public static TwitterContext CreateTwitterContext()
{
var auth = new ApplicationOnlyAuthorizer()
{
CredentialStore = new InMemoryCredentialStore
{
ConsumerKey = Environment.GetEnvironmentVariable(OAuthKeys.TwitterConsumerKey),
ConsumerSecret = Environment.GetEnvironmentVariable(OAuthKeys.TwitterConsumerSecret)
},
};
return new TwitterContext(auth);
}
}
Then there are two ways you can use this -
as a singleton:
TwitterContext twitterCtx = TwitterContextService.Instance;
or as a factory method:
TwitterContext twitterCtx = TwitterContextService.CreateTwitterContext();
Alternatively, you can use an IoC container (tons of information and available libraries on the Web) and pass the dependencies into the code that uses TwitterContext. I guess there are several different ways to do this.
I would like to save a variable in the controller to be able to use it for all methods so I declared 3 private strings
public class BankAccountController : Controller
{
private string dateF, dateT, accID;
//controller methods
}
Now this method changes their values:
[HttpPost]
public ActionResult Filter(string dateFrom, string dateTo, string accountid)
{
dateF = dateFrom;
dateT = dateTo;
accID = accountid;
//rest of the code
}
I used a breakpoint and the variables are being changed when I call that controller method, however when I call other controller methods such as these below the private strings are being reset to emtpy strings, how can I prevent it from happening?
public ActionResult Print()
{
return new ActionAsPdf(
"PrintFilter", new { dateFrom = dateF, dateTo = dateT, accountid = accID }) { FileName = "Account Transactions.pdf" };
}
public ActionResult PrintFilter(string dateFrom, string dateTo, string accountid)
{
CommonLayer.Account acc = BusinessLayer.AccountManager.Instance.getAccount(Convert.ToInt16(accID));
ViewBag.Account = BusinessLayer.AccountManager.Instance.getAccount(Convert.ToInt16(accountid));
ViewBag.SelectedAccount = Convert.ToInt16(accountid);
List<CommonLayer.Transaction> trans = BusinessLayer.AccountManager.Instance.filter(Convert.ToDateTime(dateFrom), Convert.ToDateTime(dateTo), Convert.ToInt16(accountid));
ViewBag.Transactions = trans;
return View(BusinessLayer.AccountManager.Instance.getAccount(Convert.ToInt16(accountid)));
}
Every request you make a new instance of the controller will be created, therefore you're data is not shared between requests. There's a few things you can do to save the data:
Session["dateF"] = new DateTime(); // save it in the session, (tied to user)
HttpContext.Application["dateF"] = new DateTime(); // save it in application (shared by all users)
You can retrieve the values in the same way. Of course, you could also save it somewhere else, bottom point is, controller-instances are not shared, you need to save it somewhere else.
The following method is very simple, and makes sure the variable is tied to the current user, instead of that it is used in your entire application. All you need to do is type the following code in the controller:
Session["dateF"] = dateFrom;
Session["dateT"] = dateTo;
Session["accID"] = accountid;
and whenever you want to use that variable, for instance you want to give it as an parameter to a method, you just type this:
MyMethod(Session["dateF"].ToString());
That is how you save and use a variable in ASP.NET MVC
You could use a static field in the controller so it's shared between all requests.
private static List<someObject> yourObjectList;
I have a method which looks like the one below
public List<Rajnikanth> GetRajnis()
{
string username = Utility.Helpers.GetLoggedInUserName();
return _service.GetRajni(username);
}
Utility.Helper is a static class,
public static class Helpers
{
public static String GetLoggedInUserName()
{
string username = "";
if (System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
{
username = ((System.Web.Security.FormsIdentity)HttpContext.Current.User.Identity).Ticket.Name;
}
return username;
}
}
I want to test : GetRajnis()
I want to mock : GetLoggedInUserName()
So my test method looks something like...
[TestMethod]
public void TestGetRajnis()
{
SomeController s = new SomeController(new SomeService());
var data = s.GetRajnis();
Assert.IsNotNull(data);
}
how do I mock the static method GetLoggedInUserName() ?
The Simplest Approach: Override the return value
If you are looking to mock a return value, then this is very simple. You can modify the Utility.Helper class to include a property called OverrideLoggedInUserName. When someone calls GetLogedInUserName(), if the override property is set, it is returned, otherwise the normal code to get the value from the HttpContext is used to get the return value.
public static class Helper
{
// Set this value to override the return value of GetLoggedInUserName().
public static string OverrideLoggedInUserName { get; set; };
public static string GetLoggedInUserName()
{
// Return mocked value if one is specified.
if ( !string.IsNullOrEmpty( OverrideLoggedInUserName ) )
return OverrideLoggedInUserName;
// Normal implementation.
string username = "";
if ( System.Web.HttpContext.Current.User.Identity.IsAuthenticated )
{
username = ( (System.Web.Security.FormsIdentity)HttpContext.Current.User.Identity ).Ticket.Name;
}
return username;
}
}
This will effectively allow you to override the return value, which technically isn't a mock--it's a stub (according to the excellent article Mocks Aren't Stubs by Martin Fowler). This allows you to stub a return value, but won't allow you to assert whether the method was called or not. Anyhow as long as you only want to manipulate the return value this works fine.
Here is how you would use this in a test.
[ TestMethod ]
public void TestGetRajnis()
{
// Set logged in user name to be "Bob".
Helper.OverrideLoggedInUserName = "Bob";
SomeController s = new SomeController( new SomeService() );
var data = s.GetRajnis();
// Any assertions...
}
This design does have one drawback. Because it's a static class, if you set the override value, it remains set until you un-set it. So you must remember to re-set it to null.
A Better Approach: Inject the dependency
A better approach may be to create a class that retrieves the logged in user name, and pass it into the constructor of SomeController. We call this dependency injection. This way, you can inject a mocked instance into it for testing, but pass the real instance (that gets the user from the HttpContext) when not testing. This is a much cleaner and clearer approach. Plus, you can leverage all the power of whatever mocking framework you are using, since they are designed specifically to handle this approach. Here is what that would look like.
// Define interface to get the logged in user name.
public interface ILoggedInUserInfo
{
string GetLoggedInUserName();
}
// Implementation that gets logged in user name from HttpContext.
// This class will be used in production code.
public class LoggedInUserInfo : ILoggedInUserInfo
{
public string GetLoggedInUserName()
{
// This is the same code you had in your example.
string username = "";
if ( System.Web.HttpContext.Current.User.Identity.IsAuthenticated )
{
username = ( (System.Web.Security.FormsIdentity)HttpContext.Current.User.Identity ).Ticket.Name;
}
return username;
}
}
// This controller uses the ILoggedInUserInfo interface
// to get the logged in user name.
public class SomeController
{
private SomeService _service;
private ILoggedInUserInfo _userInfo;
// Constructor allows you inject an object that tells it
// how to get the logged in user info.
public SomeController( SomeService service, ILoggedInUserInfo userInfo )
{
_service = service;
_userInfo = userInfo;
}
public List< Rajnikanth > GetRajnis()
{
// Use the injected object to get the logged in user name.
string username = _userInfo.GetLoggedInUserName();
return _service.GetRajni( username );
}
}
And here is a test using Rhino Mocks to inject a stub object into the controller.
[ TestMethod ]
public void TestGetRajnis()
{
// Create a stub that returns "Bob" as the current logged in user name.
// This code uses Rhino Mocks mocking framework...
var userInfo = MockRepository.GenerateStub< ILoggedInUserInfo >();
userInfo.Stub( x => x.GetLoggedInUserName() ).Return( "Bob" );
SomeController s = new SomeController( new SomeService(), userInfo );
var data = s.GetRajnis();
// Any assertions...
}
The disadvantage here is that you can't just call Helper.GetLoggedInUserName() from anywhere in your code, because it's no longer static. However, you no longer have the need to reset the stubbed username every time you finish a test. Because it's not static, it it automatically reset. You just recreate it for the next test and set a new return value.
I hope this helps.
Get rid of the static class if you are looking for testability. A simple fix for now would be to create a wrapper around the static class. Unless you use something like TypeMock or something equally as powerful, then you cannot alter the logic of a static class. Nor do I suggest it. If you have to stub a static class, it probably should not be a static class.
public class StaticWrapper
{
public virtual String GetLoggedInUserName()
{
Utility.Helpers.GetLoggedInUserName();
}
}
I need to create an application,that should contain two storage,one is persistent storage and another one is cache storage.After loading, the application should check the username and password with the cache storage data if it is empty then it should check with the persistent storage.How to accomplish this task?Is there any separate concept of cache or we have create the persistent as cache.please help me.
You can use RecordStore which is also persistent, or RuntimeStore which is shared between all apps but is non persistent.
Alternatively you can use some custom storage class to implement cache functionality,
storing, updating values in that class, sharing it as a field of Application class:
class Cache {
String mName = null;
String mPhone = null;
}
public class CacheApp extends UiApplication {
Cache mCache = null;
public static void main(String[] args) {
CacheApp app = new CacheApp();
app.enterEventDispatcher();
}
public CacheApp() {
initCache();
CacheScr scr = new CacheScr();
pushScreen(scr);
}
private void initCache() {
mCache = new Cache();
mCache.mName = "Name";
mCache.mPhone = "Phone";
}
}
class CacheScr extends MainScreen {
public CacheScr() {
CacheApp app = (CacheApp) UiApplication.getUiApplication();
String name = app.mCache.mName;
String phone = app.mCache.mPhone;
}
}
Coldice is correct, however I fail to see why one would use a store separate from PersistentStore (or RecordStore) for data that must endure and may be shared, and RuntimeStore for data which is shared but not durable. This just seems to be adding complexity to normal application transient storage.