Is it possible to consolidate code access security attribute (even if it means imperative method) so I can have something like this in my code?
void WriteToFileAndAccessNetwork()
{
EnterPermission(Perm.File | Perm.Network);
// Do file IO
// Do computation
// Do network operation
LeavePermission(Perm.File | Perm.Network);
}
My program will start with all permissions, but main function will start with zero permission.
I will Assert permission only when I need it in the functions that really need them. I am looking for a easy programmatic construct.
The problem I have is, the FileIOPermission.Assert() I make in EnterPermission() remains valid only within EnterPermission function call. As soon as I exit EnterPermission I lose the permission.
Any other ideas?
I dont want to have a long list of declarative attributes above every method and make my code unreadable.
Related
In Axon, Command Interceptors seem to intercept any and every command. For permission checking, I need to base my decision on the type of command to see whether it is allowed in the current context.
#Override
public BiFunction<Integer, CommandMessage<?>, CommandMessage<?>> handle(List<? extends CommandMessage<?>> messages) {
return (index, command) -> {
// Check permissions
return command;
};
}
Usually I would prefer to register an interceptor per command type and handle the permission checks in dedicated objects. How would I do it with Axon? Will I need to have a load of instanceof if-statements in a single interceptor? Does anyone have a good example of permission checking with Axon?
At this point (Axon 4.0) the framework does not allow you the option to register DispatchInterceptors per command payload type directly. So what you're suggesting to do, the if-blocks/switch-statements, is the best thing you could do at this point.
Although I am not certain how fine grained your permission checks are, what you could do is have some form of permission annotation on the commands, with a specific value/enum you need to set on it. That way you do not have to tie in your payload type into the dispatcher directly, but could just check if the annotation exists and if so, check it's value for the kind of permission check which should be performed on it.
That would very likely result in a far smaller if-block/switch-statement than checking per payload type.
I was wondering if it was possible to keep an RFC called via JCO opened in SAP memory so I can cache stuff, this is the scenario I have in mind:
Suppose a simple function increments a number. The function starts with 0, so the first time I call it with import parameter 1 it should return 1.
The second time I call it, it should return 2 and so on.
Is this possible with JCO?
If I have the function object and make two successive calls it always return 1.
Can I do what I'm depicting?
Designing an application around the stability of a certain connection is almost never a good idea (unless you're building a stability monitoring software). Build your software so that it just works, no matter how often the connection is closed and re-opened and no matter how often the session is initialized and destroyed on the server side. You may want to persist some state using the database, or you may need to (or want to) use the shared memory mechanisms provided by the system. All of this is inconsequential for the RFC handling itself.
Note, however, that you may need to ensure that a sequence of calls happen in a single context or "business transaction". See this question and my answer for an example. These contexts are short-lived and allow for what you probably intended to get in the first place - just be aware that you should not design your application so that it has to keep these contexts alive for minutes or hours.
The answer is yes. In order to make it work, you need to implement two tasks:
The ABAP code needs to store its variable in the ABAP session memory. A variable in the function group's global section will do that. Or alternatively you could use the standard ABAP technique "EXPORT TO MEMORY/IMPORT FROM MEMORY".
JCo needs to keep the user session between calls. By default, JCo resets the backend-side user session after every call, which of course destroys all data stored in that user session memory. In order to prevent it, you need to use JCoContext.begin() and JCoContext.end() to get a stateful RFC connection that keeps the user session alive on backend side.
Sample code:
JCoDestination dest = ...
JCoFunction func = ...
try{
JCoContext.begin(dest);
func.execute(dest); // Will return "1"
func.execute(dest); // Will return "2"
}
catch (JCoException e){
// Handle network problems, ABAP exceptions, SYSTEM_FAILUREs
}
finally{
// Make sure to release the stateful connection, otherwise you have
// a resource-leak in your program and on backend side!
JCoContext.end(dest);
}
In Meteor JS I want to perform a task before adding an object to my collection. So I created my own method, eg: addObject like so:
Meteor.methods({
...
addObject: function(obj) {
/*
// this is what i'm trying to figure out...
if ( !MyColl.allow('insert', Meteor.userId, obj) )
throw Meteor.Error(403, 'Sorry');
*/
MyColl.update({ ... }}, { 'multi': true });
MyColl.insert(obj);
},
...
});
But I noticed that .allow is no longer being called because it's "trusted" code. The thing is the method is on the server but being called from the client (through ObjectiveDDP) so I still need a way to validate that the client has permissions to call addObject - is there any way to manually call .allow() on a collection from my server code? I tried it but getting an internal server error, and not sure what the syntax should be... couldn't find anything in the Meteor docs.
Edit:
I just found out that this works:
var allowedToInsert = MyColl._validators.insert.allow[0];
if (!allowedToInsert)
throw new Meteor.Error(403, 'Invalid permissions.');
But that's probably a no-no calling private methods such as _validators. Does anyone know of a more 'best practices' way?
You can do validation in the addobject method. For example, if you only want logged in users to be able to add an object, you can write:
if (!Meteor.user()) throw new Meteor.Error();
at the beginning of the addobject method.
Personally I never use allow.
On a related note, the collection2 and simple-schema packages can often help a lot with validation.
The validation pattern you are using might not be the best way to do things.
If you assume that methods can be called from the client, you shouldn't 'hack' it into doing something it's not meant to do.
If you are calling a method that changes data in the database you should check within that method that the currently logged in user has permission to do so.
However, are you sure you want to do this? Meteor also has Collection.allow and Collection.deny methods that you can use to define read/write/update/delete permission with. That's the recommended way to handle permissions, so what you are doing is an anti-pattern. However, perhaps in your case it is strictly necessary? If not, you might want to rethink the use case.
Like another response suggests, using something like Collections or SimpleSchema to validate data structure is also a good idea.
Introduction
I'm currently building an access control system in my DataMapper ORM installation (with CodeIgniter 2.*). I have the initial injection of the User's rights (Root/Anonymous layers too) working perfectly. When a User logs in the DataMapper calls that are done in the system will automatically be marked with the Userrights the User has.
So until this point it works perfectly, but now I'm a bit in a bind. The problem is that I need some way to catch and filter each method-call on the Object that is instantiated.
I have two special calls so I can disable the Userrights-checks too. This is particularly handy at the exact moment I want to login a User and need to do initial checks;
DataMapper::disable_userrights();
$this->_user = new User($this->session->userdata('_user_id'));
$this->_userrights = ($this->_user ? $this->_user->userrights(TRUE) : NULL);
DataMapper::enable_userrights();
The above makes sure I can do the initial User (and it's Userrights) injection. Inside the DataMapper library I use the $CI =& get_instance(); to access the _ globals I use. The general rule in this installment I'm building is that $this->_ is reserved for a "globals" system that always gets loaded (or can sometimes be NULL/FALSE) so I can easily access information that's almost always required on each page/call.
Details
Ok, so image the above my logged-in User has the Userrights: Create/Read/Update on the User Entity. So now if I call a simple:
$test = new User();
$test->get_where('name', 'Allendar');
The $_rights Array inside the DataMapper instance will know that the current logged-in User is allowed to perform certain tasks on "this" instance;
protected $_rights = array(
'Create' => TRUE,
'Read' => TRUE,
'Update' => TRUE,
'Delete' => FALSE,
);
The issue
Now comes my problem. I want to control these Userrights by validating them over each action that is performed. I have the following ideas;
Super redundant; make a global validation method that is executed at the start of each other method in the DataMapper Class.
Problem 1: I have to spam the whole DataMapper Class with the same calls
Problem 2: I have no control over DataMapper extension methods
Problem 3: How to detect relational includes? They should be validated too
Low level binding on certain Core DataMapper calls where I can clearly detect what kind of action is executed on the database (C/R/U/D).
So I'm aiming for Option 2 (and 1.) Problem 2), as it will also solve 1.) Problem 2.
The problem is that DataMapper is so massive and it's pretty complex to discern what actually happens when on it's deepest calling level. Furthermore it looks like all methods are very scattered and hardly ever use each other ($this->get() is often not used to do an eventual call to get a dataset).
So my goal is:
User (logged-in, Anonymous, Root) makes a DataMapper istance
$user_test = new User;
User wants to get $user-test (Read)
$user_test->get(1);
DataMapper will validate the actual call that is done at the database
IF it is only SELECT; OK
IF something else than SELECT (or JOINs to other Model that the User doesn't have access to that/those Models, it will fail with a clear error message)
IF JOINed Models also validate; OK
Return the actual instance;
IF OK: continue DataMapper's normal workflow
IF not OK: inform the User and return the normal empty DataMapper instance of that Model
Furthermore, for this system I think I will need to add some customization for the raw_sql (etc.) SQL calls so that I have to inject the rights manually related to that SQL statement or only allow the Root User to do those things.
Recap
I'm curious if someone ever attempted something like this in DataMapper or has some hints how I can use/intercept those lowest level calls in DataMapper.
If I can get some clearance on the deepest level of DataMapper's actual final query-call I can probably get a long way myself too.
I would like to suggest not to do this in Datamapper itself (mainly due to the complexity of the code, as you have already noticed yourself).
Instead, use a base model, and have that extend Datamapper. Then add the code to the base model required for your ACL checks, and then overload every Datamapper method that needs an ACL check. Have it call your ACL, deal with an access denied, and if access is granted, simply return the result of parent::method();.
Instead of extending Datamapper, your application models should then extend this base model, so they will inherit the ACL features.
I am working on a VB.NET batch PDF exporting program for CAD drawings. The programs runs fine, but the architecture is a mess. Basically, one big function takes the entire process from start to finish. I would like to make a separate class, or several, to do the exporting work.
Here's the problem:
Sometimes the pdf file which will be created by my program already exists. In this case, I would like to ask the user if he/she would like to overwrite existing PDFs. I only want to do this if there is actually something which will be overwritten and I only want to do this once. In other words, "yes" = "yes to all." It seems wrong to have the form (which will be calling this new PDF exporting class) figure out what the PDF files will be called and whether there will be any overwrites. In fact, it would be best to have the names for the PDF files determined as the individual CAD drawings are processed (because I might want to use information which will only become available after loading the files in the CAD program in the background).
Here's the question:
How should I handle the process of prompting the user? I would like to keep all GUI logic (even something as simple as a dialog box) out of my PDF exporting class. I need a way for the PDF exporting class to say, "Hey, I need to know if I should overwrite or skip this file," and the form class (or any other class) to say, "Um, ok, I'll ask the user and get back to you."
It seems there ought to be some pattern to handle this situation. What is it?
Follow-ups:
Events: It seems like this is a good way to go. Is this about what the code should look like in the PDF exporting class?
Dim e As New FileExistsEventArgs(PDFFile)
RaiseEvent FileExists(Me, e)
If e.Overwrite Then
'Do stuff here
End If
A crazy idea: What about passing delegate functions to the export method of the PDF exporting class to handle the overwrite case?
You could use an Event, create a custom event argument class with a property on it that the application can call. Then when your app is handling the event prompt the user and then tell the exporter what to do. I'm a c# guy so let me give you a sample in there first:
void form_Load(object sender,EventArgs e)
{
//We are subscribing to the event here. In VB this is done differently
pdfExporter.FileExists+=new FileExistsEventHandler(pdfExporter_fileExists)
}
void pdfExporter_fileExists(object sender, FileExistsEventArgs e)
{
//prompUser takes the file and asks the user
if (promptUser(e.FileName))
{
}
}
Your PDF making class should raise an event. This event should have an eventargs object, which can have a boolean property called "Overwrite" which the GUI sets in whatever fashion you want. When the event returns in your PDF class you'll have the user's decision and can overwrite or not as needed. The Gui can handle the event anyway it likes.
Also, I commend you for working to keep the two seperate!
So the appropriate method on your class needs an optional parameter of
[OverwriteExisting as Boolean = False]
However your form will need to handle the logic of establishing whether or not a file exists. It seems to me that this would not be a function that you would want encapsulated within your PDF export class anyway. Assuming that your form or other function/class ascertains that an overwrite is required then the export methos is called passing True as a Boolean to your export class.
You could do a two phase commit type of thing.
The class has two interfaces, one for prepping the filenames and filesystem, and another for doing the actual work.
So the first phase, the GUI calls the initialization interface, and gets a quick answer as to whether or not anything needs over-writing. Possibly even a comprehensive list of the files that will get over-written. User answers, the boolean variable in the other responses is known, and then the exporter gets to the real work, and the user can go do something else.
There would be some duplication of computation, but it's probably worth it to get the user's part of the operation over with as soon as possible.
You can't keep the GUI stuff out of the PDF Exporting Code. but you can precisely define the minimum needed and not be tied to whatever framework you are using.
How I do it is that I have a Status class, and a Progress class. The two exist because Status is design to update a status message, and the Progress Bar is designed to work with a indicator of progress.
Both of them work with a object that has a class type of IStatusDisplay and IPrograssDisplay respectfully.
My GUI defines a object implementing IStatusDisplay (or IProgressDisplay) and registers as the current display with the DLL having Status and Progress. The DLL with Status and Progress also have two singleton called NullStatus and NullProgress that can be used when there is no UI feedback wanted.
With this scheme I can pepper my code with as many Status or Progress updates I want and I only worry about the implementations at the GUI Layer. If I want a silent process I can just use the Null objects. Also if I completely change my GUI Framework all the new GUI has to do is make the new object that implements the IStatusDisplay, IProgressDisplay.
A alternative is to raise events but I find that confusing and complicated to handle at the GUI level. Especially if you have multiple screen the user could switch between. By using a Interface you make the connection clearer and more maintainable in the longe.
EDIT
You can create a Prompt Class and a IPromptDisplay to handle situation like asking whether you want to overwrite files.
For example
Dim P as New Prompt(MyPromptDisplay,PromptEnum.YesNo)
'MyPromptDisplay is of IPromptDisplay and was registered by the GUI when the application was initialized
If PromptYesNo.Ask("Do you wish to overwrite files")= PromptReply.Yes Then
'Do stuff here
End If