#region License Information
/* HeuristicLab
* Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System;
using HeuristicLab.Clients.Common;
using HeuristicLab.Common;
using HeuristicLab.Core;
using System.ServiceModel;
using HeuristicLab.Clients.Hive.WebJobManager.ViewModels;
using System.Collections.Generic;
using System.ServiceModel.Security;
using HeuristicLab.Clients.Access;
namespace HeuristicLab.Clients.Hive.WebJobManager.Services.Imports
{
///
/// Controls everything User/Group/Role related
///
[Item("AccessAdministrationClient", "AccessAdministration client.")]
public class AccessAdministrationClient : IContent
{
private WebLoginService weblog;
private AccessServiceClient client;
public Guid userId { get; set; }
#region Properties
private ItemList users;
public ItemList Users
{
get
{
return users;
}
}
public ItemList Groups { get; set; }
public ItemList Roles { get; set; }
#endregion
public AccessAdministrationClient(Guid u) {
weblog = WebLoginService.Instance;
userId = u;
}
public bool checkAuthorised()
{
if (client != null)
{
try
{
client.GetAllUsers();
return true;
}
catch (Exception e)
{
if (e is MessageSecurityException || e is InvalidOperationException)
{
return false;
}
throw;
}
}
return false;
}
#region Refresh
public void RefreshUsers()
{
users = new ItemList();
users.AddRange(CallAccessService>(s => new ItemList(s.GetAllUsers())));
}
public void RefreshUsersAsync(Action exceptionCallback)
{
ExecuteActionAsync(RefreshUsers, exceptionCallback);
}
public void RefreshUserGroups()
{
Groups = new ItemList();
Groups.AddRange(CallAccessService>(s => new ItemList(s.GetAllUserGroups())));
}
public void RefreshUserGroupsAsync(Action exceptionCallback)
{
ExecuteActionAsync(RefreshUserGroups, exceptionCallback);
}
public void RefreshRoles()
{
Roles = new ItemList();
Roles.AddRange(CallAccessService>(s => new ItemList(s.GetRoles())));
}
public void RefreshRolesAsync(Action exceptionCallback)
{
ExecuteActionAsync(RefreshRoles, exceptionCallback);
}
#endregion
#region Store
public void StoreUsers()
{
foreach (User u in users)
{
if (u.Modified)
{
if (u.Id == Guid.Empty)
{
CallAccessService(s => u.Id = s.AddUser(u).Id);
}
else {
CallAccessService(s => s.UpdateUser(u));
}
u.SetUnmodified();
}
}
}
public void StoreUsersAsync(Action exceptionCallback)
{
ExecuteActionAsync(StoreUsers, exceptionCallback);
}
public void StoreUserGroups()
{
foreach (UserGroup g in Groups)
{
if (g.Modified)
{
if (g.Id == Guid.Empty)
{
CallAccessService(s => g.Id = s.AddUserGroup(g));
}
else {
CallAccessService(s => s.UpdateUserGroup(g));
}
g.SetUnmodified();
}
}
}
public void StoreUserGroupsAsync(Action exceptionCallback)
{
ExecuteActionAsync(StoreUserGroups, exceptionCallback);
}
public void StoreRoles()
{
foreach (Role g in Roles)
{
if (g.Modified)
{
CallAccessService(s => s.AddRole(g));
g.SetUnmodified();
}
}
}
public void StoreRolesAsync(Action exceptionCallback)
{
ExecuteActionAsync(StoreRoles, exceptionCallback);
}
#endregion
#region Delete
public void DeleteUser(User u)
{
CallAccessService(s => s.DeleteUser(u));
}
public void DeleteUserAsync(User u, Action exceptionCallback)
{
Action deleteUserAction = new Action(delegate { DeleteUser(u); });
ExecuteActionAsync(deleteUserAction, exceptionCallback);
}
/* BROKEN
public void DeleteUserGroup(UserGroup u)
{
CallAccessService(s => s.DeleteUserGroup(u));
}
public void DeleteUserGroupAsync(UserGroup u, Action exceptionCallback)
{
Action deleteUserGroupAction = new Action(delegate { DeleteUserGroup(u); });
ExecuteActionAsync(deleteUserGroupAction, exceptionCallback);
}
*/
public void DeleteRole(Role u)
{
CallAccessService(s => s.DeleteRole(u));
}
public void DeleteRoleAsync(Role u, Action exceptionCallback)
{
Action deleteRoleAction = new Action(delegate { DeleteRole(u); });
ExecuteActionAsync(deleteRoleAction, exceptionCallback);
}
#endregion
public void ExecuteActionAsync(Action action, Action exceptionCallback)
{
var call = new Func(delegate ()
{
try
{
OnRefreshing();
action();
}
catch (Exception ex)
{
return ex;
}
finally
{
OnRefreshed();
}
return null;
});
call.BeginInvoke(delegate (IAsyncResult result)
{
Exception ex = call.EndInvoke(result);
if (ex != null) exceptionCallback(ex);
}, null);
}
#region Events
public event EventHandler Refreshing;
private void OnRefreshing()
{
EventHandler handler = Refreshing;
if (handler != null) handler(this, EventArgs.Empty);
}
public event EventHandler Refreshed;
private void OnRefreshed()
{
EventHandler handler = Refreshed;
if (handler != null) handler(this, EventArgs.Empty);
}
#endregion
#region User
public string resetPassword(Guid id)
{
return CallAccessService(s => s.ResetPassword(id));
}
public Guid addUser(Access.User u)
{
return CallAccessService(s => s.AddUser(u).Id);
}
public void updateUser(Access.User u)
{
CallAccessService(s => s.UpdateUser(u));
}
public List getRoles(User u)
{
return CallAccessService(s => s.GetUserRoles(u));
}
public void addRoleToUser(User u, Role r)
{
CallAccessService(s => s.AddUserToRole(r, u));
}
public void deleteUserRole(User u, Role r)
{
CallAccessService(s => s.RemoveUserFromRole(r, u));
}
#endregion
#region Group
public Guid addGroup(Access.UserGroup g)
{
return CallAccessService(s => s.AddUserGroup(g));
}
public void updateGroup(UserGroup g)
{
CallAccessService(s => s.UpdateUserGroup(g));
}
public List getSubscribedGroups(Guid id)
{
var maps = CallAccessService(s => s.GetUserGroupMapping());
maps = maps.FindAll(x => x.Child == id);
RefreshUserGroups();
RefreshUsers();
List members = new List();
foreach (var map in maps)
{
UserGroup g = Groups.Find(x => x.Id == map.Parent);
if (g != null)
{
members.Add( g);
}
}
return members;
}
public List getGroupMembers(Guid id)
{
var maps = CallAccessService(s => s.GetUserGroupMapping());
maps = maps.FindAll(x => x.Parent == id);
RefreshUserGroups();
RefreshUsers();
List members = new List();
foreach (var map in maps)
{
User t = users.Find(x => x.Id == map.Child);
if (t == null)
{
UserGroup g = Groups.Find(x => x.Id == map.Child);
if (g != null)
{
members.Insert(0,g);//Groups always in the front
}
}
else
{
members.Add(t);//members in the back
}
}
return members;
}
public void deleteUserGroup(UserGroup group)
{
deleteAllMembers(group);
CallAccessService(s => s.DeleteUserGroup(group));
}
private void deleteAllMembers(UserGroup group)
{
var list = getGroupMembers(group.Id);
foreach (var member in list)
{//Empties all member connections
CallAccessService(s => s.RemoveUserGroupBaseFromGroup(member, group));
}
}
public void addMember(UserGroupBase member, UserGroup group)
{
CallAccessService(s => s.AddUserGroupBaseToGroup(member, group));
}
public void deleteMember(UserGroupBase member,UserGroup group)
{
CallAccessService(s => s.RemoveUserGroupBaseFromGroup(member, group));
}
#endregion
#region Roles
public Role addRole(Access.Role r)
{
return CallAccessService(s => s.AddRole(r));
}
public void deleteRole(string name)
{
Role r = Roles.Find(x => x.Name == name);
CallAccessService(s => s.DeleteRole(r));
}
public List getEnrolled(Role r)
{
var enroll = new List();
RefreshUsers();
foreach(var us in users)
{
var temp = CallAccessService(s => s.GetUserRoles(us));
if (temp.Contains(r))
enroll.Add(us);
}
return enroll;
}
#endregion
#region Helpers
private void getAccessClient()
{
//build config by code
WSHttpBinding binding = new WSHttpBinding();
binding.Name = "WSHttpBinding_IAccessService";
binding.CloseTimeout = TimeSpan.FromMinutes(1);
binding.OpenTimeout = TimeSpan.FromMinutes(1);
binding.ReceiveTimeout = TimeSpan.FromMinutes(10);
binding.SendTimeout = TimeSpan.FromMinutes(1);
binding.BypassProxyOnLocal = false;
binding.TransactionFlow = false;
binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
binding.MaxBufferPoolSize = 524288;
binding.MaxReceivedMessageSize = 65536;
binding.MessageEncoding = WSMessageEncoding.Text;
binding.TextEncoding = System.Text.Encoding.UTF8;
binding.UseDefaultWebProxy = true;
binding.AllowCookies = false;
binding.ReaderQuotas.MaxDepth = 32;
binding.ReaderQuotas.MaxStringContentLength = 8192;
binding.ReaderQuotas.MaxArrayLength = 16384;
binding.ReaderQuotas.MaxBytesPerRead = 4096;
binding.ReaderQuotas.MaxNameTableCharCount = 16384;
binding.ReliableSession.Ordered = true;
binding.ReliableSession.InactivityTimeout = TimeSpan.Parse("00:10:00");
binding.ReliableSession.Enabled = false;
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Message.NegotiateServiceCredential = true;
binding.Security.Message.AlgorithmSuite = System.ServiceModel.Security.SecurityAlgorithmSuite.Default;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
binding.Security.Transport.Realm = "";
var end = new EndpointAddress("http://services.heuristiclab.com/AccessService-3.3/AccessService.svc");
client = new AccessServiceClient(binding, end);
client.ClientCredentials.UserName.UserName = weblog.getLoginViewModel(userId).loginName;
//PASSWORD CANNOT BE ENCRYPTED
client.ClientCredentials.UserName.Password = weblog.getServiceLocator(userId).Password;
client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
}
public void CallAccessService(Action call)
{
getAccessClient();
try
{
call(client);
}
finally
{
try
{
client.Close();
}
catch (Exception)
{
client.Abort();
}
}
}
public T CallAccessService(Func call)
{
getAccessClient();
try
{
return call(client);
}
finally
{
try
{
client.Close();
}
catch (Exception)
{
client.Abort();
}
}
}
#endregion
internal bool CheckLogin()
{
try
{
this.RefreshUsers();
return true;
}
catch (SecurityAccessDeniedException e)
{
return false;
}
catch (MessageSecurityException e)
{
return false;
}
}
}
}