Rhino Mocks Assert Property Setter was called with correct object type - rhino-mocks

I have a method that sets a property
public void SetNetworkCredential(string userName, string password, string domain)
{
_reportExecutionService.Credentials = new NetworkCredential(userName, password, domain);
}
how do I verify that Credentials was called with a valid NetworkCredential?
I tried this TestMethod but it fails because the NetworkCredential objects are different references
[TestMethod]
public void TestTest()
{
const string userName = "userName";
const string password = "password";
const string domain = "domain";
var mock = MockRepository.GenerateMock<IReportExecutionService>();
var rptService= new ReportService(mock);
rptService.SetNetworkCredential(userName, password, domain);
mock.AssertWasCalled(x => x.Credentials = new System.Net.NetworkCredential(userName, password, domain));
}
Is there a way to validate that the setter was called with an object of type NetworkCredential and with the correct parameters?

I fixed it by making the ReportService accept a Network Credential instead of the username, password, domain
public void SetNetworkCredential(NetworkCredential networkCredential)
{
_reportExecutionService.Credentials = networkCredential;
}
so my test was much easier
[TestMethod]
public void TestTest()
{
const string userName = "userName";
const string password = "password";
const string domain = "domain";
var mock = MockRepository.GenerateMock<IReportExecutionService>();
var rptService= new ReportService(mock);
var networkCredential = new System.Net.NetworkCredential(userName, password, domain);
rptService.SetNetworkCredential(networkCredential);
mock.AssertWasCalled(x => x.Credentials = networkCredential);
}

Edit: Rethinking this problem, my previous suggested answer would probably not work. Here's why:
Essentially, you are attempting to verify that the dependency of a dependency has been set up correctly. That is probably why you are having problems writing a unit test for this. You probably want to consider whether it would make sense for you to move the SetNetworkCredential method into the class that implements IReportExecutionService instead.
And if you do, the unit test for that method would be simple enough:
[Test]
public void TestSetNetworkCredential()
{
const string userName = "userName";
const string password = "password";
const string domain = "domain";
var rptService= new ReportExecutionService();
rptService.SetNetworkCredential(userName, password, domain);
Assert.AreEqual(userName, rptService.Credentials.UserName);
Assert.AreEqual(password, rptService.Credentials.Password);
Assert.AreEqual(domain, rptService.Credentials.Domain);
}

Related

Proxy with CefSharp

how can I set up a proxy that has username and password in CefSharp browser in visual basic?
I tried with this code but doesn't work:
Dim proxy = "IP:PORT#USERNAME:PASSWORD"
Dim settings As New CefSettings()
settings.CefCommandLineArgs.Add("proxy-server", proxy)
Thanks
Your browser implement a IBrowser interface with GetHost method that allow you get RequestContext. You can set the proxy:
var requestContext = browser.GetHost().RequestContext;
var values = new Dictionary<string, object>
{
["mode"] = "fixed_servers",
["server"] = $"{proxyScheme}://{proxyHost}:{proxyPort}"
};
string error;
bool success = requestContext.SetPreference("proxy", values, out error);
To set user/password, you need to implement an IRequestHandler interface and implement this method:
public bool GetAuthCredentials(
IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
{
if (isProxy)
{
var browser2 = browserControl as IChromeRequestHandler;
var proxyOptions = browser2?.ProxySettings;
if (proxyOptions != null)
{
callback.Continue(proxyOptions.UserName, proxyOptions.Password);
return true;
}
}
callback.Dispose();
return false;
}
Then, you must set the RequestHandler property of your browser:
browser.RequestHandler = new YourIRequestHandlerImplementation();
Sorry for the C# implementation, but I think may be useful to you.

How to pass values to DataAccess Layer for storing into database in asp.net MVC5 API?

In my API application, I field values coming from registration view which I want to store into the database. On AccountController.cs, I have collected these values using the following code.
[Route("Register")]
public async Task<object> Register(UserDetails data)
{
var userRegister = new IdentityUser
{
FirstName = data.FirstName,
LastName = data.LastName,
UserName = data.Email,
Email = data.Email,
PhoneNumber = data.PhoneNumber,
PasswordHash = data.Password
};
UserManager<IdentityUser> _manager = new UserManager<IdentityUser>(new UserStore<IdentityUser>(new TachusApi.DBContext.AuthDbContext()));
string pHash = _manager.PasswordHasher.HashPassword(data.Password);
DBAccess dbaccess = new DBAccess();
dbaccess.SaveAdmin(userRegister, pHash);
return data;
}
What I want to do is to pass these values to the SaveAdmin method in DBAccess.cs for storing into the database. Here is my SaveAdmin method:
#region Save Admin User
public void SaveAdmin(string userRegister, string hash)
{
SqlConnection conn = null;
SqlCommand command = null;
int retValue;
conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
conn.Open();
command = conn.CreateCommand();
command.CommandText = "RequestedServiceUserDataInsert";
command.CommandType = CommandType.StoredProcedure;
...
}
#endregion
I can't pass a valid format of the values to my SaveAdmin method where I can save them into the database. Is there anyone who may advise an effective way that can help me pass these values as an object for using them in my save method? Please advice
Since you define the userRegister object as an IdentityUser object
var userRegister = new IdentityUser
{
FirstName = data.FirstName,
LastName = data.LastName,
UserName = data.Email,
Email = data.Email,
PhoneNumber = data.PhoneNumber,
PasswordHash = data.Password
};
And then pass it to the SaveAdmin function of your dbaccess class
dbaccess.SaveAdmin(userRegister, pHash);
The SaveAdmin method needs to be set up to accept the userRegister of type IdentityUser. Right now it expects a plain string.
So, instead of having your SaveAdmin function declared as this:
public void SaveAdmin(string userRegister, string hash)
You need to have it declared like this:
public void SaveAdmin(IdentityUser userRegister, string hash)
That way the method gets the data it expects and you can access all properties of that object and insert them into SQL server.

MvvmCross HTTP DownloadCache with authentication

In my app, the user need to be authenticated on the server to download data using WebAPIs.
The MvvmCross DownloadCache plugin seems to handle only basic HTTP GET queries. I can't add my authentication token in the url as it's a big SAML token.
How can I add a HTTP header to queries done through DownloadCache plugin ?
With the current version I think I should inject my own IMvxHttpFileDownloader but I'm looking for an easier solution. Injecting my own MvxFileDownloadRequest would be better (not perfect) but it doesn't have an interface...
I'm able to do it registering a custom IWebRequestCreate for a custom scheme (http-auth://).
It's a bit ugly to transform urls from my datasource but it does the job.
public class AuthenticationWebRequestCreate : IWebRequestCreate
{
public const string HttpPrefix = "http-auth";
public const string HttpsPrefix = "https-auth";
private static string EncodeCredential(string userName, string password)
{
Encoding encoding = Encoding.GetEncoding("iso-8859-1");
string credential = userName + ":" + password;
return Convert.ToBase64String(encoding.GetBytes(credential));
}
public static void RegisterBasicAuthentication(string userName, string password)
{
var authenticateValue = "Basic " + EncodeCredential(userName, password);
AuthenticationWebRequestCreate requestCreate = new AuthenticationWebRequestCreate(authenticateValue);
Register(requestCreate);
}
public static void RegisterSamlAuthentication(string token)
{
var authenticateValue = "SAML2 " + token;
AuthenticationWebRequestCreate requestCreate = new AuthenticationWebRequestCreate(authenticateValue);
Register(requestCreate);
}
private static void Register(AuthenticationWebRequestCreate authenticationWebRequestCreate)
{
WebRequest.RegisterPrefix(HttpPrefix, authenticationWebRequestCreate);
WebRequest.RegisterPrefix(HttpsPrefix, authenticationWebRequestCreate);
}
private readonly string _authenticateValue;
public AuthenticationWebRequestCreate(string authenticateValue)
{
_authenticateValue = authenticateValue;
}
public WebRequest Create(System.Uri uri)
{
UriBuilder uriBuilder = new UriBuilder(uri);
switch (uriBuilder.Scheme)
{
case HttpPrefix:
uriBuilder.Scheme = "http";
break;
case HttpsPrefix:
uriBuilder.Scheme = "https";
break;
default:
break;
}
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uriBuilder.Uri);
request.Headers[HttpRequestHeader.Authorization] = _authenticateValue;
return request;
}
}

Using OAuthWebSecurity with Salesforce

I'm trying to get an ASP.NET MVC site to accept Salesforce as an authentication provider, but I am not having any luck. I'll start out with the IAuthenticationClient I have so far:
public class SalesForceOAuth2Client : OAuth2Client
{
private readonly String consumerKey;
private readonly String consumerSecret;
#if DEBUG
private const String BaseEndpoint = #"https://test.salesforce.com";
#else
private const String BaseEndpoint = #"https://login.salesforce.com";
#endif
private const String AuthorizeEndpoint = BaseEndpoint + #"/services/oauth2/authorize";
private const String TokenEndpoint = BaseEndpoint + #"/services/oauth2/token";
private const String RevokeEndpoint = BaseEndpoint + #"/services/oauth2/revoke";
public SalesForceOAuth2Client(String consumerKey, String consumerSecret)
: base("SalesForce")
{
if (String.IsNullOrWhiteSpace(consumerKey))
{
throw new ArgumentNullException("consumerKey");
}
if (String.IsNullOrWhiteSpace(consumerSecret))
{
throw new ArgumentNullException("consumerSecret");
}
this.consumerKey = consumerKey;
this.consumerSecret = consumerSecret;
}
protected override Uri GetServiceLoginUrl(Uri returnUrl)
{
String redirect_url = returnUrl.AbsoluteUri;
// Hack to work-around the __provider__ & __sid__ query parameters,
// but it is ultimately useless.
/*String state = String.Empty;
Int32 q = redirect_url.IndexOf('?');
if (q != -1)
{
state = redirect_url.Substring(q + 1);
redirect_url = redirect_url.Substring(0, q);
}*/
var builder = new UriBuilder(AuthorizeEndpoint);
builder.Query = "response_type=code"
+ "&client_id=" + HttpUtility.UrlEncode(this.consumerKey)
+ "&scope=full"
+ "&redirect_uri=" + HttpUtility.UrlEncode(redirect_url)
// Part of the above hack (tried to use `state` parameter)
/*+ (!String.IsNullOrWhiteSpace(state) ? "&state=" + HttpUtility.UrlEncode(state) : String.Empty)*/;
return builder.Uri;
}
protected override IDictionary<String, String> GetUserData(String accessToken)
{
// I am not sure how to get this yet as everything concrete I've
// seen uses the service's getUserInfo call (but this service relies
// heavily on a username, password, token combination. The whole point
// of using oatuh is to avoid asking the user for his/her credentials)
// more information about the original call:
// http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_calls_getuserinfo.htm
// Return static information for now
//TODO: Get information dynamically
return new Dictionary<String, String>
{
{ "username", "BradChristie" },
{ "name", "Brad Christie" }
};
}
protected override String QueryAccessToken(Uri returnUrl, String authorizationCode)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(TokenEndpoint);
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "POST";
using (StreamWriter streamWriter = new StreamWriter(webRequest.GetRequestStream()))
{
streamWriter.Write("grant_type=authorization_code");
streamWriter.Write("&client_id=" + HttpUtility.UrlEncode(this.consumerKey));
streamWriter.Write("&client_secret=" + HttpUtility.UrlEncode(this.consumerSecret));
streamWriter.Write("&redirect_uri=" + HttpUtility.UrlEncode(returnUrl.AbsoluteUri));
streamWriter.Write("&code=" + HttpUtility.UrlEncode(authorizationCode));
streamWriter.Flush();
}
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
if (webResponse.StatusCode == HttpStatusCode.OK)
{
using (StreamReader streamReader = new StreamReader(webResponse.GetResponseStream()))
{
String response = streamReader.ReadToEnd();
var queryString = HttpUtility.ParseQueryString(response);
return queryString["access_token"];
}
}
return String.Empty;
}
}
The primary problem is that redirect_uri != Callback Url.
Salesforce enforces the callback URL you supply in the application configuration to match exactly to the value provided in redirect_uri of QueryAccessToken. Unfortunately OAuthWebSecurity relies on DotNetOpenAuth.AspNet, and that library appends two query parameters: __provider__ and __sid__. If I try to remove those (see the hack in GetServiceLoginUrl), obviously the login fails because the hand-back doesn't know how to continue on with the request without knowing which provider to use.
To work around this I did notice that the request call accepts an optional state parameter which is (essentially) there for passing things back and forth across the request/callback. However, with the dependence on __provider__ and __sid__ being their own keys having data=__provider__%3DSalesForce%26__sid__%3D1234567890 is useless.
Is there a work-around without having to fork/recompile the Microsoft.Web.WebPages.OAuth library and modify the OAuthWebSecurity.VerifyAuthenticationCore(HttpContextBase, String) method to look at data first, then continue on to OpenAuthSecurityMananer.GetProviderName?
Also, in case the registration mattered (AuthConfig.cs):
OAuthWebSecurity.RegisterClient(
new SalesForceOAuth2Client(/*consumerKey*/, /*consumerSecret*/),
"SalesForce",
new Dictionary<String, Object>()
);
Update (11.01.2013)
I just got a response back from Salesforce. It looks like they don't know how to implement 3.1.2 of the RFC which means that any query parameters you send in with the return_uri are not only ignored, but prohibited (at least when dynamic in nature). So, it looks like I can't use a library that works on every other platform and follows the standard--i have to create my own.
Sigh.

reporting service network credentials

receiving the error:
"Property or indexer
'Microsoft.Reporting.WebForms.IReportServerCredentials.NetworkCredentials'
cannot be assigned to-- it is read only"
within this line:
reportviewer1.ServerReport.ReportServerCredentials.NetworkCredentials
= new System.Net.NetworkCredential("someaccount",
"somepassword");
When I hover the cursor on NetworkCredentials, it says: "Gets or sets the network credentials that are used for authentication with report server"..
what the heck is going on here?
thanks
this.rpv.ServerReport.ReportServerCredentials is not read-only. Read this post:
http://www.visualstudiodev.com/visual-studio-report-controls/reportviewerserverreportreportservercredentialsnetworkcredentials-readonly-24629.shtml
it is still read only, that ReportServerCredentials field is still read only, it has only getter but not a setter !
add this class to the same namespace:
public class CustomReportCredentials : IReportServerCredentials
{
private string _UserName;
private string _PassWord;
private string _DomainName;
public CustomReportCredentials(string UserName, string PassWord, string DomainName)
{
_UserName = UserName;
_PassWord = PassWord;
_DomainName = DomainName;
}
public System.Security.Principal.WindowsIdentity ImpersonationUser
{
get { return null; }
}
public ICredentials NetworkCredentials
{
get { return new NetworkCredential(_UserName, _PassWord, _DomainName); }
}
public bool GetFormsCredentials(out Cookie authCookie, out string user,
out string password, out string authority)
{
authCookie = null;
user = password = authority = null;
return false;
}
}
Then set your credentials like this:
IReportServerCredentials Creds = new CustomReportCredentials("Administrator", "password", "domain"); //to actual values
myReportViewer.ServerReport.ReportServerCredentials = Creds;
in .NET core as well in .NET 5.0 replace "reportViewer.ServerReport.ReportServerCredentials" with "reportViewer.ServerReport.ReportServerCredentials.NetworkCredentials = new System.Net.NetworkCredential(Username,Password,Domain);"
also you Should install "Microsoft.Reporting.WinForms" NuGet