I would like to utilize some of the social collaboration features in Sharepoint 2010, such as the Noteboard webpart and tagging, but do not want to use the My Site profile pages.
I have already built a custom control that redirects from the userdisp.aspx page to a custom user profile page. I would like to continue to use that custom profile page. However, it seems like user profile links that are generated by the Noteboard webpart, for example, go directly to the /Sites/MySites/person.aspx page without being routed through the /_layouts/userdisp.aspx page. So my profile redirect control doesn't catch it.
In Sharepoint Central Admin, under Manage Service Applications > User Profile Service Application > Manage User Permissions, I have only checked the box for "Use Social Features", not "Create Personal Site," so I am not sure why the profile page is not linking to the old userdisp.aspx page.
Is it possible to redirect these links back to the userdisp.aspx page?
It appears to be hardcoded into the webpart.
I looked at Microsoft.SharePoint.Portal.WebControls.SocialCommentControl and the link comes from UserProfile.PublicUrl, which is defined as:
public override Uri PublicUrl
{
get
{
string userProfileUrl = UserProfileGlobal.GetUserProfileURL(
this.m_objManager.UserProfileApplicationProxy,
this.m_objManager.PartitionID,
"?accountname=",
this.m_UserProfileFields["AccountName"].ToString());
if (!string.IsNullOrEmpty(userProfileUrl))
return new Uri(userProfileUrl);
else
return (Uri) null;
}
}
which eventually calls:
internal static string GetUserProfileURL(string profileWebUrl, string strIdentifier, string strValue)
{
if (string.IsNullOrEmpty(profileWebUrl))
return (string) null;
else
return PersonalSpaceGlobal.EnsureTrailingSlash(profileWebUrl)
+ "Person.aspx"
+ strIdentifier
+ (strIdentifier.Equals("?accountname=", StringComparison.OrdinalIgnoreCase)
? SPHttpUtility.UrlKeyValueEncode(strValue).Replace(":", "%3A")
: SPHttpUtility.UrlKeyValueEncode(strValue));
}
I can think of two workarounds:
Add jQuery to your page to change the URL (selector = span.socialcomment-username > a)
Create your own webpart containing a custom control that inherits from SocialCommentControl, which overrides RenderComment.
Overriding RenderComment is probably going to be messy. You will need to copy the decompiled code for the method just to change the following into your own code:
SocialCommentControl._GetProperty(
comment,
SocialCommentControl.SocialCommentProperty.PublicPage)
Hopefully, there are no internal method calls within RenderComment's 67 lines of code. Otherwise, it is going to be a lot more difficult to implement. It would be a lot easier if you could simply override _GetProperty, but unfortunately, it is a static method.
All of that to say, I would probably recommend the jQuery option over extending SocialCommentControl.
Related
I have a solution based on the Visual Studio template that is successfully using IdentityServer4.
What think I understand is:
The IS4 integration implements endpoints at /authentication/{action}, e.g. authentication/login
IS4 routes that request to host/Identity/Account/Login.cshtml. I have scaffolded identity so I can see that .cshtml file in my project.
The code-behind Login.cshtml.cs takes care of speaking with SignInManager, etc.
In the client project the "LoginDisplay.razor" component redirects to /authentication/login when I click the login button. I presume that this is where step 1 above is invoked, which redirects to the location in step 2.
Fine. Now, I want to customise the whole login UI.
From instructions at: https://learn.microsoft.com/en-us/aspnet/core/blazor/security/webassembly/additional-scenarios?view=aspnetcore-5.0 I can see that:
I can configure authentication paths to be anything I want. For example:
builder.Services.AddApiAuthorization(options => {
options.AuthenticationPaths.LogInPath = "security/login";
})
So, I have created a razor component to handle security/login:
#page "/security/{action}"
#using Microsoft.AspNetCore.Components.WebAssembly.Authentication
<RemoteAuthenticatorView Action="#Action">
<LoggingIn>
This is the new login page
</LoggingIn>
</RemoteAuthenticatorView>
#code{
[Parameter] public string Action { get; set; }
}
My expectation was that after clicking "Login", I would be routed to the above and presented with a page that just said:
"This is the new login page"
and thought that from there, I would:
Customise the UI within the <LoggingIn> fragment.
Make a call to an API that would then replicate the logic in the scaffolded login.cshtml file that actually logs the user in.
That line of code from the login.cshtml.cs file looks like this:
var result = await _signInManager.PasswordSignInAsync(
Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
However, it seems that the razor component I created for /security/login is simply a 'transient' message that appears before being routed to the scaffolded login.csthml file.
So, to me, it seems that I am unable to actually change the physical page used to collect the user's credentials. I am only able to change the transient screen that appears before the originally scaffolded login page is shown.
Does this mean that if I want a customised UI for logging in I need to directly edit the scaffolded page as opposed to creating a whole new UI in the WebAssembly project that calls an APIController that I create to take care of using SignInManager?
It would actually be a lot less work to do that than to take the approach of creating a Client-side UI that calls an API that I create, etc. so, with hindsight, editing the scaffolded cshtml file is probably the best way to go. But am still confused as to what value is really being brought by being able to configure options.AuthenticationPaths.LogInPath.
I'm developing an extension that have both, a list of records (action show) and a form to send a new record (action new).
The list must be for public access, but the form must require a login form (I'm using the login form content type that comes with TYPO3).
I have tried using the Access Tab for the plugin selecting Show at any Login but it applies to the entire plugin not for each action.
Currently, this is how the page looks like:
How could I get to display the login form only when someone tries to create a new record?
Note: The extension is based on Extbase and Fluid. The target version is TYPO3 6.2.
The easiest would be to split the actions in different "views" with switchableControllerActions in your flexform. Then you would need to place separate plugins on two different pages, that way you can have different access configuration for the plugins. If you don't know how to adjust the flexform, you can post the content of it here.
The other way would be to make a check inside the controller, but i would only use it if you have a lot of different roles you need to check.
if ($this->loginUser === null && $GLOBALS['TSFE']->loginUser && !empty($GLOBALS['TSFE']->fe_user->user['uid'])) {
// the user is logged in
} else {
// return '' as action content
return '';
}
I use latest prestashop 1.6.1.4, I want to every customer firstly login on site and then they have access all over pages of website, without login user can't do anything on site.
So, I want know that there is any configuration at backoffice side and if Yes then how can do that?
There is no built in function to do this, but you can easily override the FrontController to achieve this behavior.
Put this code inside /override/classes/controller/FrontController.php:
<?php
class FrontController extends FrontControllerCore
{
public function init()
{
parent::init();
if (!$this->context->customer->isLogged() && $this->php_self != 'authentication' && $this->php_self != 'password')
{
Tools::redirect('index.php?controller=authentication?back=index');
}
}
}
If the user is not on an authentication page or a forgot password page he will be redirected to the authentication page. After log in he will be redirected to the home.
EDIT:
If the file FrontController.php doesn't exist, you will have to create it and delete the file /cache/class_index.php. class_index caches every classes path on your website. So if you create a new Class File, you need to delete it to let Prestashop search for newly created ones.
There is no such configuration for this in back office. You can only achieve this by developing a custom module for your store, that uses a hook that is called on all the pages (hookDisplayHeader or hookDisplayTop etc.)
If you don't want to create a module for this then you can also achieve the same by overriding FrontController.php as it is called on each and every page of PrestaShop.
I have an MVC 4 Razor intranet app using Windows credentials where a new user must register (existing users are automatically redirected to the main user page). This generates an approval request email to the admin and returns a view with an Exit button simply saying your application has been submitted. The user then closes the app.
The email is in HTML and presents the user's entered data and has Approved or Declined selections. It then has a button to invoke code to insert the user into the Members table (if accepted) and return an email to the user with the decision.
Since some time may transpire between the app mailing the admin and the admin making the decision, the session will originally terminate. I need to have the email invoke a method to persist the new user, email the decision, and then simply exit. It will not involve the browser in any way, so no Views are involved. I could write this as a background console app, but that would involve duplicating a lot of code in the MVC app - with referential integrity issues on bug fixes or updates.
How can I write a method in the Controller that can be invoked by a link in the email as if from a browser that does the work and then exits without returning anything to a browser?
If I make the method an ActionResult method and return new EmptyResult() or return(null) I assume it will try to return an empty page to nowhere.
Can I alternatively construct a method in my Controller, where it has access to all of the support code, like?
public void EnrollMember(Member member, bool decision)
{
if (decision == true)
{
// insert new user into Members table
// generate accepted email
}
else
{
// generate declined email
}
}
and then just link to it the same way I link to Index(), /MyController/EnrollMember(...)?
There is no main() in the app since it is an ASP.NET MVC app, and I don't know how to terminate the app from within a Controller method without trying to return something, instead of from a View in the browser.
I'm a long-time programmer, but a .NET newbie so this probably has a simple answer.
The "view" is just the response. You don't necessarily have to return a view, but you must return a response. There's no way around that. If the link opens in a browser, then something will be displayed, regardless. Even if you were to just return an empty ContentResult, at least a blank page will be displayed in the browser.
To achieve something akin to what you're looking for, your best bet would be to return an HTML document with just a simple bit of JavaScript that will act to close the window:
<html>
<body>
<script>
window.close();
</script>
</body>
</html>
VS2010 w/Ria Services & SL4.
I already have my SL app loaded in the browser.
User clicks around to different view pages and I would like to store their current location in a list of "recently visited pages".
To do that, I need to store the view page + any existing querystring key/values.
Ex: here is a real page in my sl app:
http://localhost:52878/Default.aspx#/DocSearchShell?CM-Origination
I don't care about anything before the # sign - there are a million ways on google to get the http: // localhost:52878/Default.aspx uri from sl.
What I DO want is the "DocSearchShell?CM-Origination" portion of the querystring - that is what I want to capture and store for the "recently visited pages"
How do I do this from sl4 (.NET 4) code-behind?
Thanks!
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// The answer is this:
// e.Uri.OriginalString;
}
You can access the part of query string after "#" symbol via System.Windows.Browser.HtmlPage.Window.CurrentBookmark.
It works from any part of SL application.