declaring global variables in vb - vb.net

The user clicks a button, a new form is generated where the user enters his/her password? How can I keep an in-memory copy of the username?
For instance in web forms, I can just use Session ("User"). How can I replicate this with winforms?
Thanks

You could use a static (Shared in VB .NET) object
Example
Public Class SessionInformation
Public Shared Property UserPassword As String
End Class
You can then access this by calling
SessionInformation.UserPassword
Since there seems to be some concerns revolving around whether or not this is a valid implementation I will explain why this is not the best idea.
This creates a single instance of SessionInformation which means that if it is changed anywhere in the program it affects the rest of the program.
Maintaining object persistence can be difficult if you aren't using a database (SQL, Access, a file, etc...) to maintain an out of memory copy of the object that you want to retrieve at a later date. The easiest way to implement this would be to use a SQLCE database that live in your application folder and using standard T-SQL to store the information that you need. However in the case of a password this may be non-ideal due to security issues.
Or the better way for logging in and out user would be to make use of the System.Security.Principal Namespace to create a user for your application.

You don’t need an equivalent to the Session object in web applications. Sessions are only needed because web applications actually have to access variables across process boundaries (= a session in a web application encompasses multiple requests of a user to a web server, and historically each request started a new application!).
In a “normal” application, this isn’t the case – any non-local variable will do. In your particular case, it would make sense for the password form to have a property that contains the username. The user then enters their username and password and the caller of this password form can retrieve the username:
' The caller looks something like this:
Dim pw As New PasswordForm()
pw.ShowDialog() ' Display the dialog, and wait until the user has dismissed it.
Dim theUsername = pw.Username
Inside the PasswordForm, there is something like this:
Public ReadOnly Property Username() As String
Get
' Return the value of the username textbox field.
Return UsernameInput.Text
End Get
End Property
We could get more sophisticated but this will do.
If you need to reuse the username across the application, chances are that you also need to share other information about the user (what are they working on? …). This, in short, is the state of the application and there is usually an object which represents that state. This would be the right place to store the username as well.
If your application only has one other form (the “main dialog”), then just use a private variable inside that form to store the username. No need for a global variable.

Just have a public variable on the forms, never unload the form, and get the data from that form using formname.variablename (define it as public at form level).
This even can be achieved with controls if you set them to public.
BEFORE THE FLAMES: this solves OP problems, whenever if this is optimal, good or anything else, is another problem.

Related

Change RZ11 Profile parameters programmatically

I was asked by the IT Department to write an ABAP program that switches the profile parameter login/server_logon_restriction from 0 to 1 and back automatically triggered (time etc) on all of our SAP servers.
I am not very familiar in the SAP environment yet and until now I managed to get the wanted parameter by using:
RSAN_SYSTEM_PARAMETERS_GET
and
RSAN_SYSTEM_PARAMETERS_READ
But I cannot find anything to change and save them dynamically. Is this even possible?
Cheers, Nils
login/server_logon_restriction parameter dynamic so you can change it via cl_spfl_profile_parameter=>change_value class method.
You can configure background job for automatically trigger it in t-code SM36.
The method don't save the given value to profile file, so the parameter turn back profile value after system restart.
Current logged-in users can continue to use system. May be you can want to inform them with TH_POPUP function then kick from the system.

VBA Access security question: Detect if the instance of access is from Access.Application?

My file (c:\mydb.accbe) has protection against the shift bypass, hidden access object window protection, disabled ctrl-g, hotkey bypass protection, etc. Project is also password protected, then compiled, and encrypted.
The problem is any user with read access to that accde file can create a new access project and create an instance of the protected file of that project using this code:
Dim appAccess As Access.Application
Set appAccess = CreateObject("Access.Application")
appAccess.OpenCurrentDatabase = "c:\mydb.accbe"
Now they can call any public function of that instance, for example:
call appAccess.run("thisIsPublicFunctionIn_mydb")
I can see two potential ways to mitigate this:
1# Any potentially sensitive function would get an extra parameter that contains the 'security' code.
2# Add some security by obscurity by renaming all the functions to random numbers at the end.
Other then using a real programming language (sadly not an option), got any suggestions on how I can detect this or protect against it?
When the app is opened through automation the UserControl property is updateable, so that is not really an option.
You cannot prevent that from happening. Best you can do is use a SQL server backend, where you tightly control permissions on tables, and use procs (with permissions) to update sensitive data.
I believe that application.UserControl does something around this. I've just tried, and seems to be ok for opening via access.application

Deep level access control in DataMapper ORM

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.

Apache Shiro - issue with isPermitted() method and wrong Authorizer class

We have implemented a class called AuthorizerImpl that contains two objects: an AuthorizingRealm and a Subject. We have implemented an isPermitted() method which subsequently calls the isPermitted() method on the subject. Our code looks something like this:
// UserContext object uc is passed in here
AuthorizerImpl auth = new AuthorizerImpl(uc.getUser());
auth.isPermitted("winnebago:drive:eagle5");
We initially log in and authenticate a user's permissions using the above code. The first time a user logs in, it is a a "base user" so to speak. There are certain screens that are specific to certain users, so we call the above code again with a different uc.getUser() to verify the new users permissions. What I am seeing though is that the backend Shiro code is using the previous user to check the permissions, not the new user that I passed into the isPermitted() method. Each time we are calling "new AuthorizerImpl(uc.getUser())" we are creating a new Subject and AuthorizingRealm that are instance variables inside the AuthorizingRealm object. It was my impression that when I create a new AuthorizerImpl, it should use the new subject and realm that we are creating in the constructor. However, it seems that Shiro is caching the previous realm object that was used and is using that? We are using the DefaultSecurityManager. After doing some debugging, I noticed that the DefaultSecurityManager has an authorizer instance variable. It appears to be using the first authorizer object and not the new one that should be created with the new user, which leads me to believe it is is being cached. Is there a way to turn off this caching? Is this what is happening or is it something else? The permissions are being retrieved correctly from the database if the correct user is used to check. How can I resolve this?
Thank you in advance.

How should one class request info from another one?

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