Lock out users after three unsuccessful attempts without using a database - asp.net

I want to lock out my users after three unsuccessfull attempts without using a database.
I was trying:
public int loginAttempts()
{
if (!(ViewData["loginAttempts"] == null))
{
ViewData["loginAttempts"] = int.Parse(ViewData["loginAttempts"].ToString()) + 1;
return int.Parse(ViewData["loginAttempts"].ToString());
}
else
{
ViewData["loginAttempts"] = 1;
return 1;
}
}
But it always returns 1. What modifications do I need to make?

You'd need to store this in the session, not view data. View data is sent to the view and is not persisted between requests.
public int loginAttempts()
{
if (!(Session["loginAttempts"] == null))
{
Session["loginAttempts"] = int.Parse(Session["loginAttempts"].ToString()) + 1;
return int.Parse(Session["loginAttempts"].ToString());
}
else
{
Session["loginAttempts"] = 1;
return 1;
}
}

Use Session state variables.

Related

How to enable Security Logging AX2012 (SecurityTasks to SecurityRoles)

I want to log SecurityRole - SecurityTask changes, and since the EeUserRoleChangeLog logs User – SecurityRole changes (for Estonia, but commenting out language detection, it logs also for us here in Holland perfectly). I think that basis can be used to log those changes.
So I first created the table:
EeRoleTaskChangeLog with the following fields:
AddRemove EnumType: AddRemove
ChangedBy EDT: UserID
SecurityRole EDT: RefRecID
SecurityTask EDT: RefRecId
I then noticed that within the class SysSecRole, User-Role changes logging is triggered within method removeFromSelectedUser. So whenever someone changes something from the AOT or the front-end, all these changes are then logged within the EeUserRoleChangeLog.
So I extended SysSecTask with the method removeFromSelectedRole:
public void removeFromSelectedRole()
{
RefRecId SecurityRole;
SysSecTreeTasks taskTree;
SecurityRoleTaskGrant SecurityRoleTaskGrant;
taskTree = tree as SysSecTreeTasks;
securityRole = taskTree.getSecurityRole();
ttsbegin;
EePersonalDataAccessLogging::logRoleTaskChange(recId, 0, securityRole, AddRemove::Remove);
delete_from securityRoleTaskGrant where securityRoleTaskGrant.SecurityRole == securityRole && securityRoleTaskGrant.SecurityTask == recId;
ttscommit;
if (treeControl)
{
tree.deleteTreeItem(treeControl, idx);
}
}
However, it somehow doesn’t recognize the triggers and so it does not fill my table.
I hoped to add a delete/insert trigger to the SecuryRoleTaskGrant systemtable, but this is completely closed, so I have no idea how or where this method can be triggered.
So then I thought as a ‘semi-working’ work around, let’s only log changes made in the front-end, since that already fixes the problem for the regular workers. So I decided to find a similar trigger within Forms, and I found the form SysSecUserAddRoles with method assignRolesToSelectedUser. This method has the following trigger:
if (added)
{
EePersonalDataAccessLogging::logUserRoleChange(secRole.RecId,0, userId, AddRemove::Add);
}
I decided to add this trigger to a Form that allows workers to change Task-Roles: SysSecRoleAddTasks method addTasksFromRole, and somehow this also does not seem to fix the problem. It doesn’t fill the table. I use the following code, and front-end changes are still not logged within my created EeRoleTaskChangeLog table.
public int addTasksFromRole(SecurityRole _role, boolean _recursive = false)
{
SecurityRole childRole;
SecuritySubRole subRole;
SecurityTask task;
SecurityRoleTaskGrant srtGrant;
int nAdded = 0;
RefRecId securityRole;
boolean added;
if (_role.RecId == targetRoleId)
{
return 0;
}
startLengthyOperation();
while select task
join SecurityRole, SecurityTask from srtGrant
where srtGrant.SecurityRole == _role.RecId
&& srtGrant.SecurityTask == task.RecId
{
nAdded += this.addTask(task);
}
if (_recursive)
{
while select childRole
where childRole.RecId != targetRoleId
join SecurityRole, SecuritySubRole from subRole
where subRole.SecuritySubRole == childRole.RecId
&& subRole.SecurityRole == _role.RecId
{
this.addTasksFromRole(childRole, true);
}
}
endLengthyOperation();
if (added) //Added
{
EePersonalDataAccessLogging::logRoleTaskChange(securityTask.RecId,0, securityRole, AddRemove::Add);
}
return nAdded;
}
Why doesn’t this trigger the logging?
Do I need to provide any more information?
The SysSecRoleAddTasks Form has also the addTask method, I tried it here as well, but this again doesn’t trigger the logtable to be filled.
public int addTask(SecurityTask _task, boolean _trialAdd = false)
{
SecurityRoleTaskGrant srtGrant;
int nAdded = 0;
boolean added; //Added
RefRecId securityRole; //Added
select targetRole
where targetRole.RecId == targetRoleId; // make sure in sync
select forupdate srtGrant
where srtGrant.SecurityTask == _task.RecId
&& srtGrant.SecurityRole == targetRoleId;
if (!srtGrant)
{
if (!_trialAdd)
{
ttsbegin;
srtGrant.SecurityTask = _task.RecId;
srtGrant.SecurityRole = targetRoleId;
srtGrant.insert();
nAdded++;
myObjects.insert(_task.RecId, true);
if (added) //Added
{
EePersonalDataAccessLogging::logRoleTaskChange(securityTask.RecId,0, securityRole, AddRemove::Add);
}
ttscommit;
}
else if (targetRoleId != 0)
{
nAdded++;
}
//info('Added task "' + _task.Name + '" (' + int2str(appl.ttsLevel()) + ')');
}
/*
else
{
info('Not adding task "' + _task.Name + '"');
} */
return nAdded;
}
Any suggestions?
This question requires a lot of hands-on debugging I would think to solve, which I'm not sure many posters are going to do unfortunately. Have you tried just using the system's database log?
SecurityRole and SecurityTask are system tables, stored under \System Documentation\Tables\SecurityRole, so I didn't know where to find them in the DB log wizard, but I wrote a manual job that I think should work.
I've only tested it with UserInfo, which is another system table and it appears to have logged changes correctly.
static void AddTablesToDBLog(Args _args)
{
void logTable(TableId _tableId, DatabaseLogType _logType)
{
DatabaseLog dblog;
dblog.logTable = _tableId;
dblog.logField = 0;
dblog.logType = _logType;
dblog.insert();
}
ttsBegin;
logTable(tableNum(SecurityRole), DatabaseLogType::Insert);
logTable(tableNum(SecurityRole), DatabaseLogType::Update);
logTable(tableNum(SecurityRole), DatabaseLogType::Delete);
logTable(tableNum(SecurityTask), DatabaseLogType::Insert);
logTable(tableNum(SecurityTask), DatabaseLogType::Update);
logTable(tableNum(SecurityTask), DatabaseLogType::Delete);
ttsCommit;
SysFlushDatabaseLogSetup::main();
new MenuFunction(menuitemDisplayStr(SysDatabaseLogSetup), MenuItemType::Display).run(null);
info("Done");
}

Firebase firestore document changes

I just want to ask how can I properly use the document changes in my app? Btw there are 3 types of that which is ADDED, MODIFIED and lastly REMOVED. TYPE.ADDED works perfectly fine, but in modified and removed it doesn't work well in modified it. I am using a recyclerview for that and here's my code. Am I wrong utilizing it? Also, I am using a instance oldindex and newindex to know the index which is affected by the action performed.
for (DocumentChange doc : documentSnapshots.getDocumentChanges()) {
if(doc.getType() == DocumentChange.Type.ADDED) {
PostsClass post = doc.getDocument().toObject(PostsClass.class).withId(doc.getDocument().getId());
postList.add(post);
Log.d(TAG, post.toString());
postsAdapter.notifyDataSetChanged();
}
else if (doc.getType() == DocumentChange.Type.MODIFIED) {
adoptList.clear();
AdoptClass adopt = doc.getDocument().toObject(AdoptClass.class).withId(doc.getDocument().getId());
adoptList.add(adopt);
adoptListAdapter.notifyItemChanged(oldIndex);
}
else if (doc.getType() == DocumentChange.Type.REMOVED) {
adoptList.remove(oldIndex);
adoptListAdapter.notifyItemRemoved(oldIndex);
}
}
below code worked for me in 3 conditions ADDED,MODIFIED,REMOVED (Android Firestore)
for (DocumentChange documentChange : queryDocumentSnapshots.getDocumentChanges()) {
if (documentChange.getType() == DocumentChange.Type.ADDED) {
String doc_id = documentChange.getDocument().getId();
PostModel postModel = documentChange.getDocument().toObject(PostModel.class).withDocId(doc_id);
postModelList.add(postModel);
} else if (documentChange.getType() == DocumentChange.Type.MODIFIED) {
// modifying
String docID = documentChange.getDocument().getId();
PostModel changedModel = documentChange.getDocument().toObject(PostModel.class).withDocId(docID);
if (documentChange.getOldIndex() == documentChange.getNewIndex()) {
// Item changed but remained in same position
postModelList.set(documentChange.getOldIndex(),changedModel);
postListAdapter.notifyItemChanged(documentChange.getOldIndex());
}else {
// Item changed and changed position
postModelList.remove(documentChange.getOldIndex());
postModelList.add(documentChange.getNewIndex(),changedModel);
postListAdapter.notifyItemMoved(documentChange.getOldIndex(),documentChange.getNewIndex());
}
postListAdapter.notifyDataSetChanged();
} else if (documentChange.getType() == DocumentChange.Type.REMOVED) {
// remove
postModelList.remove(documentChange.getOldIndex());
postListAdapter.notifyItemRemoved(documentChange.getOldIndex());
}
}

How do you pass different collections through the same parameter?

I am creating a method that will take a collection of different types (divs, spans..) and search it. I can't find a parameter to pass different collection types though. I tried IElementContainer and ElementCollections but I can't cast DivCollection to either. Is there another way?
The method that does the search:
private static ElementCollection searchCollections(IElementContainer ec, WACore.compStringInfo info)
{
if (info.componentIDName == WACore.componentIDs.Id.ToString())
{
return ec.Elements.Filter(Find.ById(info.componentIDValue));
}
else if (info.componentIDName == WACore.componentIDs.Name.ToString())
{
return ec.Elements.Filter(Find.ByName(info.componentIDValue));
}
else if (info.componentIDName == WACore.componentIDs.Title.ToString())
{
return ec.Elements.Filter(Find.ByTitle(info.componentIDValue));
}
else if (info.componentIDName == WACore.componentIDs.OuterText.ToString())
{
String str = info.componentIDValue.Substring(1, 6);
return ec.Elements.Filter(Find.ByText(new Regex(str)));
}
else
{
return null;
}
}
The caller(s):
return searchCollections((IElementContainer)doc.TextFields, info);
return searchCollections((IElementContainer)(doc.Divs), info);
return searchCollections((IElementContainer)doc.Spans, info);

In Producer/Consumer, why does switching the order of up(mutex) and up(fill) result in deadlock?

Let's use the code on the wikipedia page as the example.
semaphore mutex = 1;
semaphore fillCount = 0;
semaphore emptyCount = BUFFER_SIZE;
procedure producer() {
while (true) {
item = produceItem();
down(emptyCount);
down(mutex);
putItemIntoBuffer(item);
up(mutex);
up(fillCount);
}
}
procedure consumer() {
while (true) {
down(fillCount);
down(mutex);
item = removeItemFromBuffer();
up(mutex);
up(emptyCount);
consumeItem(item);
}
}
Why does swapping the position of up(mutex) and up(fillCount) in the producer function guarantee deadlock? I'm trying to come up with an instance, but can't seem to find any.

Read and write to ASP.NET cache from static method

I have a static method in a helper class named helper.getdiscount(). This class is ASP.NET frontend code and used by UI pages.
Inside this method I check if some data is in the ASP.NET cache then return it, otherwise it makes a service call and store the result in the cache and then returns that value.
Will this be a problem considering multiple threads might be accessing it at the same time?
if (HttpContext.Current.Cache["GenRebateDiscountPercentage"] == null)
{
IShoppingService service = ServiceFactory.Instance.GetService<IShoppingService>();
rebateDiscountPercentage= service.GetGenRebateDiscountPercentage().Result;
if (rebateDiscountPercentage > 0)
{
HttpContext.Current.Cache.Add("GenRebateDiscountPercentage", rebateDiscountPercentage, null, DateTime.Now.AddDays(1), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null);
}
}
else
{
decimal.TryParse(HttpContext.Current.Cache["GenRebateDiscountPercentage"].ToString(), out rebateDiscountPercentage);
}
Please advise if this is fine or any better approach could be used.
try something like this with lock object.
static readonly object objectToBeLocked= new object();
lock( objectToBeLocked)
{
if (HttpContext.Current.Cache["GenRebateDiscountPercentage"] == null)
{
IShoppingService service = ServiceFactory.Instance.GetService<IShoppingService>();
rebateDiscountPercentage= service.GetGenRebateDiscountPercentage().Result;
if (rebateDiscountPercentage > 0)
{
HttpContext.Current.Cache.Add("GenRebateDiscountPercentage", rebateDiscountPercentage, null, DateTime.Now.AddDays(1), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null);
}
}
else
{
decimal.TryParse(HttpContext.Current.Cache["GenRebateDiscountPercentage"].ToString(), out rebateDiscountPercentage);
}
}
Also you can look into following thread.
What is the best way to lock cache in asp.net?
Use these generic methods to use the cache for any type:
`public static void AddCache(string key, object Data, int minutesToLive = 1440)
{
if (Data == null)
return;
HttpContext.Current.Cache.Insert(key, Data, null, DateTime.Now.AddMinutes(minutesToLive), Cache.NoSlidingExpiration);
}
public static T GetCache<T>(string key)
{
return (T)HttpContext.Current.Cache.Get(key);
} `
Now to solve your problem:
`if(GetCache<decimal>("GenRebateDiscountPercentage") == null)
{
IShoppingService service = ServiceFactory.Instance.GetService<IShoppingService>();
rebateDiscountPercentage= service.GetGenRebateDiscountPercentage().Result;
if (rebateDiscountPercentage > 0)
{
AddCache("GetGenRebateDiscountPercentage", rebateDiscountPercentage);
}
}
else
{
rebateDiscountPercentage = GetCache<decimal>("GetGenRebateDiscountPercentage");
}
`

Resources