IronPython Linq Lambda Issue - c#

I am using Linq in a simple IronPython script to perform a lookup against an entity framework database context:
import clr
import System
clr.AddReference('Common')
clr.AddReference('System.Core')
clr.ImportExtensions(System.Linq)
from Common import Message
db = Lib.Data.db #Lib passed into environment
#RequestMessage passed into environment
username = RequestMessage.Data.Username
password = RequestMessage.Data.Password
#outputs the username as expected
System.Console.WriteLine(username)
#always returns null
users = db.Users.FirstOrDefault(lambda x: x.Username == username)
#returns expected data
users = db.Users.FirstOrDefault(lambda x: x.Username == 'someuser')
The above code works just fine if I substitute username for a hardcoded string containing an actual username in the database. When i use the variable itself, the expression always evaluates to null/None.

Related

Some properties from database are null when they have value

I'm trying to make works a login functionality but for some users Linq return some values as null when they have a correct value in database. For other users everything works ok.
This is my linq
public Clientes Login(string username)
{
DataClasses1DataContext db = new DataClasses1DataContext();
var query = from c in db.Clientes
where c.NroDocumento == username
select c;
return query.FirstOrDefault();
}
Then in the service layer I have the following:
Clientes o = userData.Login(username);
return (o != null && password == o.Password)
? new UserEntity(o.CodCliente, o.Email, o.Empresa)
: null;
But when I debug, for some users I can see that the property o.Password has a value, and for others it appears as null.
The users are being created by other systems, so I don't know if that can impact, but when I run the Select directly in SQL Server, both users has a Password, so I don't understand which is the difference that makes Linq return null.
This is the image of the model (sorry for the spanish)
As per the comments it looks like there are duplicates, but some of them don't have a password. As you're using 'FirstOrDefault' in some cases it's picking up the one without a password.

How to use parameters in Linq FromSQL Query

I am trying to get a list from Locations table and exclude the Locations already assigned to a user. I am trying to using Linq FromSQL. If I hard code the user.Id parameter the query works, when I use the user.Id variable it does not work. Query returns all records. When I run the debugger, the user.Id variable is correct. Here is my code...
ApplicationUser user = await _userManager.FindByNameAsync(Id);
var unassignedLocations = await _context.Location
.FromSql($"SELECT * FROM Locations WHERE Id NOT IN (SELECT LocationId FROM UserLocations WHERE UserID='{user.Id}')")
.OrderBy(l => l.Name)
.ToListAsync();
Locations = new SelectList(unassignedLocations, "Id", "Name");
The problem are the enclosing quotes around the value
UserID='{user.Id}'
When using FromSql method overload with interpolated SQL string, rather than embedding the value inside the SQL string (which would allow SQL injection attacks), EF Core will bind a parameter for every placeholder inside the string - in this case, single parameter with value = user.Id.
Hence you have to access the value directly w/o enclosing it with quotes like constant:
WHERE UserID={user.Id}

Change user password for Oracle database using sql statement in C#

I'm working on a requirement where I have to change the oracle connection password of the current user from my application.
I have found that I can use the following statement to achieve this task using SQL:
ALTER USER *username* IDENTIFIED BY *password*
However because the username and password aren't sent to the database as quoted strings, I can't use bind parameters. (Which is also stated by this answer)
I have a working solution when I concatenate a string and sent it as a regular sql query over my Entity Framework DbContext instance like this:
using (var context = _dbContextFactory.CreateContext())
{
await context.Database.ExecuteSqlCommandAsync(
$"ALTER USER {username} IDENTIFIED BY \"{newPassword}\"");
}
The downsides of this approach is that by concatinating the password in the string I have SQL injection vulnerabilities and the user can't use some reserved characters in their passwords, like e.g. ; and "
I'm not concerned about the username parameter because this is managed within the backend code, however the password is directly from user input.
Is there any way to change the current users password in the Oracle database from C# using a safe approach? I'm also open to other approaches like a diffrent method or creating a stored procedure in the database, as long as it can be implemented in a C# client application.
We are using Oracle version 12+, so I can't use the IDENTIFIED BY VALUES '' syntax
For username we have to provide Oracle Identifier (in case we keep the original query) which is
Up to 30 characters in length
Must start with a letter
Can include $ (dollar sign), _ (underscore), and # (hash sign)
we can validate provided value via regular expressions:
if (!Regex.IsMatch(username, #"^[A-Za-z][A-Za-z0-9_#\$]{0,29}$")) {
// username is invalid
}
For the password we can
Double all quotations: my"password -> my""password
Ensure that the password contains valid characters only (e.g. let's exclude unicode control characters like back space and other)
So the code will be something like this
if (!Regex.IsMatch(username, #"^[A-Za-z][A-Za-z0-9_#\$]$")) {
// username is invalid
}
if (string.IsNullOrEmpty(newPassword) || newPassword.Any(c => char.IsControl(c))) {
// password is invalid
}
using (var context = _dbContextFactory.CreateContext()) {
await context.Database.ExecuteSqlCommandAsync(
$"ALTER USER {username} IDENTIFIED BY \"{newPassword.Replace("\"", "\"\"")}\"");
}
This seems to be working on my local Oracle test db (from ODP.net driver). The important bit seemed to be BEGIN / END; (wouldn't work without it).
using (var con = (OracleConnection)db.Server.GetConnection())
{
con.Open();
//string pw = "'''';++";
string pw = "newpass";
var cmd = new OracleCommand(#"
BEGIN
EXECUTE IMMEDIATE CONCAT('ALTER USER B identified by ',:pw);
END;", con);
cmd.CommandType = CommandType.Text;
var p2 = cmd.CreateParameter();
p2.ParameterName = "pw";
p2.Value = pw;
p2.DbType = DbType.String;
cmd.Parameters.Add(p2);
cmd.ExecuteNonQuery();
}

How to retrieve a specific record using the entity framework

I have a table users which stores three values i.e username ,the password and the member type .I want to ensure that the username stored in the table is unique and hence there is a primary key on it.However I want to do the validation at the client side itself instead of sending a insert request to the database and then catching the error .
So how can I retrieve the single record from the database which would contain both username and password so that I can use it for the comparison purposes in the code and then throw a validation error if needed.
My manager wants me to use stored procedures so inputs along those lines would be great
public static bool IsUserExists(string userName, string hashedPassword)
{
bool result = false;
using (MyEntities entityContext = new MyEntities())
{
result = (entityContext.User.Count(u => u.username == userName &&
u.password == hashedPassword) == 1);
}
return result;
}

Quick way to detect if a DataContext table or view exists

Currently, I'm developing an application that depends on (and thus connects to) various databases via LINQ-to-SQL. For one of the databases, the connection string may vary and is thus configurable - however, the schema of this database is identical for all connection strings.
Because of the configurable connection string, I want to validate the DataContext during the startup of my application, to make sure that all tables and views my application uses, are available.
The Table<T> objects in the DataContext object are always initialized - even if the corresponding SQL table or view doesn't have any records.
So then. Currently, the validation check is performed as follows:
bool valid = _dataContext.Articles.Count() > 0
&& _dataContext.Customers.Count() > 0
&& _dataContext.Orders.Count() > 0;
While this does work, the determination of the value of valid takes quite some time (every record of each Table is touched), which ultimately results in a time out. So, is there a faster, more reliable way to determine whether or not a Table<T> of a certain DataContext really exists as a table in the corresponding database?
Here is an (untested) idea:
Grab the name of your table. You can hard code it in, or you can grab it programmatically via
TableAttribute attribute = (TableAttribute)typeof(MyTableObject)
.GetCustomAttributes(typeof(TableAttribute), true)
.Single();
string name = attribute.Name;
MyTableObject is the LINQ-to-SQL generated object contained in your Table, i.e., the generic parameter T in Table<T>.
(TableAttribute is in System.Data.Linq.Mapping.)
Use the DataContext.ExecuteQuery method as in
var db = new MyDataContext();
var results = db.ExecuteQuery<string>("SELECT name FROM dbo.sysobjects WHERE xtype = 'U'");
bool hasTable = results.Any(s => "dbo." + s == name);
A slight change on Jason's answer (I gave him an upvote :))
public bool TableExistsInDatabase<T>()
{
TableAttribute attribute = (TableAttribute)typeof(T)
.GetCustomAttributes(typeof(TableAttribute), true)
.Single();
var result = ExecuteQuery<bool>(
String.Format(
"IF OBJECT_ID('{0}', 'U') IS NOT NULL
SELECT CAST(1 AS BIT) ELSE
SELECT CAST(0 AS BIT)", attribute.Name));
return result.First();
}

Categories