Problem adding a dynamic field to a SPList in sharepoint - sharepoint-2007

We have the following code in a webpart:
using (SPSite site = new SPSite("http://localhost/"))
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.SiteUserInfoList;
if (!list.Fields.ContainsField("Office"))
{
list.Fields.Add("Office", SPFieldType.Text, false);
list.Update();
}
}
}
in the 4th line where we add a item to the list we get this error: "Updates are currently disallowed on GET requests. To allow updates on a GET, set the 'AllowUnsafeUpdates' property on SPWeb".
Then we added this line before adding the item to the list:
web.AllowUnsafeUpdates = true;
Now we are getting this error:
"You are currently signed in as: [domain]\username".
Sign in as a different user.
The account that we are using have administrative access too.
Any idea how we can get the following code executing:
web.AllowUnsafeUpdates = true;
list.Fields.Add("Office", SPFieldType.Text, false);
list.Update();

Got it working the following way:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(web.Site.ID))
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.SiteUserInfoList;
if (!list.Fields.ContainsField("Office"))
{
list.Fields.Add("Office", SPFieldType.Text, false);
list.Update();
}
}
}
});
Needed to run the codes with Full Control rights :)
But we shouldn't be writings all the cods this way.

Related

How to use SimpleProvider with my own MSAL C# code

I'm trying to use my own MSAL code to work together. Developed with .NET Core 5 MVC.
I have similar problem as I found in below link. But I just don't know how to make it work with the proposed answer. Or in other words, I'm still confuse how this integration is done.
[It is mandatory to use the login component in order to use the other components]It is mandatory to use the login component in order to use the other components
[Quickstart for MSAL JS]https://github.com/microsoftgraph/microsoft-graph-toolkit/blob/main/samples/examples/simple-provider.html
I also have read following article too:
[Simple Provider Example]https://github.com/microsoftgraph/microsoft-graph-toolkit/blob/main/samples/examples/simple-provider.html
[A lap around microsoft graph toolkit day 7]https://developer.microsoft.com/en-us/office/blogs/a-lap-around-microsoft-graph-toolkit-day-7-microsoft-graph-toolkit-providers/
is there someone can pointing to me more details explanation about how to archive this.
Can someone explains further below response further. How to do it. Where should I place the code and how to return AccessToken to SimpleProvider?
Edited:
Update my question to be more precise to what I want besides on top of the question. Below is the code I used in Startup.cs to automatically trigger pop up screen when user using the web app. When using the sample provided, it is always cannot get access token received or userid data. Question 2: How to save or store token received in memory or cache or cookies for later use by ProxyController and its classes.
//Sign in link under _layouts.aspx
<a class="nav-link" asp-area="MicrosoftIdentity" asp-controller="Account" asp-action="SignIn">Sign in</a>
// Use OpenId authentication in Startup.cs
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
// Specify this is a web app and needs auth code flow
.AddMicrosoftIdentityWebApp(options =>
{
Configuration.Bind("AzureAd", options);
options.Prompt = "select_account";
options.Events.OnTokenValidated = async context =>
{
var tokenAcquisition = context.HttpContext.RequestServices
.GetRequiredService<ITokenAcquisition>();
var graphClient = new GraphServiceClient(
new DelegateAuthenticationProvider(async (request) =>
{
var token = await tokenAcquisition
.GetAccessTokenForUserAsync(GraphConstants.Scopes, user: context.Principal);
request.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", token);
})
);
// Get user information from Graph
try
{
var user = await graphClient.Me.Request()
.Select(u => new
{
u.DisplayName,
u.Mail,
u.UserPrincipalName,
u.MailboxSettings
})
.GetAsync();
context.Principal.AddUserGraphInfo(user);
}
catch (ServiceException)
{
}
// Get the user's photo
// If the user doesn't have a photo, this throws
try
{
var photo = await graphClient.Me
.Photos["48x48"]
.Content
.Request()
.GetAsync();
context.Principal.AddUserGraphPhoto(photo);
}
catch (ServiceException ex)
{
if (ex.IsMatch("ErrorItemNotFound") ||
ex.IsMatch("ConsumerPhotoIsNotSupported"))
{
context.Principal.AddUserGraphPhoto(null);
}
}
};
options.Events.OnAuthenticationFailed = context =>
{
var error = WebUtility.UrlEncode(context.Exception.Message);
context.Response
.Redirect($"/Home/ErrorWithMessage?message=Authentication+error&debug={error}");
context.HandleResponse();
return Task.FromResult(0);
};
options.Events.OnRemoteFailure = context =>
{
if (context.Failure is OpenIdConnectProtocolException)
{
var error = WebUtility.UrlEncode(context.Failure.Message);
context.Response
.Redirect($"/Home/ErrorWithMessage?message=Sign+in+error&debug={error}");
context.HandleResponse();
}
return Task.FromResult(0);
};
})
// Add ability to call web API (Graph)
// and get access tokens
.EnableTokenAcquisitionToCallDownstreamApi(options =>
{
Configuration.Bind("AzureAd", options);
}, GraphConstants.Scopes)
// Add a GraphServiceClient via dependency injection
.AddMicrosoftGraph(options =>
{
options.Scopes = string.Join(' ', GraphConstants.Scopes);
})
// Use in-memory token cache
// See https://github.com/AzureAD/microsoft-identity-web/wiki/token-cache-serialization
.AddInMemoryTokenCaches();
Since you are using MVC, I recommend using the ProxyProvider over the Simple Provider.
SimpleProvider - useful when you have existing authentication on the client side (such as Msal.js)
ProxyProvider - useful when you are authenticating on the backend and all graph calls are proxied from the client to your backend.
This .NET core MVC sample might help - it is using the ProxyProvider with the components
Finally, I have discovered how to do my last mile bridging for these two technology.
Following are the lines of the code that I have made the changes. Since I'm using new development method as oppose by MSAL.NET, a lot of implementation has been simplified, so many of examples or article out there, may not really able to use it directly.
Besides using links shared by #Nikola and me above, you also can try to use below
https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/
to consolidate to become your very own solution. Below are the changes I have made to make it worked.
Change in Startup.cs class
// Add application services. services.AddSingleton<IGraphAuthProvider, GraphAuthProvider>(); //services.AddSingleton<IGraphServiceClientFactory, GraphServiceClientFactory>();
Change in ProxyController.cs class
private readonly GraphServiceClient _graphClient;
public ProxyController(IWebHostEnvironment hostingEnvironment, GraphServiceClient graphclient)
{
_env = hostingEnvironment;
//_graphServiceClientFactory = graphServiceClientFactory;
_graphClient = graphclient;
}
Change in ProcessRequestAsync method under ProxyController.cs
//var graphClient = _graphServiceClientFactory.GetAuthenticatedGraphClient((ClaimsIdentity)User.Identity);
var qs = HttpContext.Request.QueryString;
var url = $"{GetBaseUrlWithoutVersion(_graphClient)}/{all}{qs.ToUriComponent()}";
var request = new BaseRequest(url, _graphClient, null)
{
Method = method,
ContentType = HttpContext.Request.ContentType,
};

SharePoint 2010 "save conflict" message when editing list item with attachment

I have been trying to address an error generated in SharePoint 2010 that occurs when I update a list item that has a Microsoft Office document attached. If I make changes to the attached document (by clicking its link in the list item) and then attempt to save the list item I get the error message below.
save_conflict_error
I am trying to capture and deal with this error using the ItemUpdating event receiver
The receiver never catches the save conflict exception in the try catch.
I have tried everything that has been suggested in about 4 pages of google searches and I have run out of things to try. This is a last desperate attempt to find a solution (if there IS one).
Below is my code for the ItemUpdating event receiver.
public override void ItemUpdating(SPItemEventProperties properties)
{
try
{
base.ItemUpdating(properties);
using (SPSite site = properties.OpenSite())
{
using (SPWeb web = site.OpenWeb())
{
//determine list
if (properties.List.Title.ToLower() == "mytestlist")
{
web.AllowUnsafeUpdates = true;
this.EventFiringEnabled = false;
properties.List.Update();
} //endif
} //end using
} //end using
}
catch (Exception ex) {
{
//abort the update
properties.Status = SPEventReceiverStatus.CancelWithError;
properties.ErrorMessage = ex.Message;
properties.Cancel = true;
} //end try
}
} //end function
Here is my Elements.xml file also.
elements_xml
Thank you in advance.
:)

Whats happens with GET Video Adwords Campaigns

recently i started a project to get campaigns from google adwords api and make analytics reports about that info.
I have that issue:
I launch this piece of code to get all campaigns:
public function testGetCampaigns()
{
$user = new \AdWordsUser();
$user->LogAll();
$campaignService = $user->GetService('CampaignService', 'v201603');
// Create selector.go
$selector = new \Selector();
$selector->fields = array('Id', 'Name');
$selector->ordering[] = new \OrderBy('Name', 'ASCENDING');
// Create paging controls.
$selector->paging = new \Paging(0, \AdWordsConstants::RECOMMENDED_PAGE_SIZE);
do {
$page = $campaignService->get($selector);
if (isset($page->entries)) {
foreach ($page->entries as $campaign) {
printf("Campaign with name '%s' and ID '%s' was found.\n",
$campaign->name, $campaign->id);
}
} else {
print "No campaigns were found.\n";
}
$selector->paging->startIndex += \AdWordsConstants::RECOMMENDED_PAGE_SIZE;
} while ($page->totalNumEntries > $selector->paging->startIndex);
}
But the result is not the two campaigns that i created, is just only one.
I have to say that the one that the api dont give to me, is a Video Campaigns, and not a search campaign.
RESULT OF THE CODE:
1 / 1 (100%)Campaign with name 'Testingalot' and ID '469071928' was found.
It is correct because CampaignService does not show video campaigns in listings. See e.g. https://groups.google.com/forum/#!topic/adwords-api/SH7lk_y4GTw

Using the TFS Api, how can I retrieve a list of all the testers to whom test cases can be assigned to in a given plan?

Using the TFS Api, I am trying to get a list of all the testers for a given project.
The same list of testers appear in MTM when allocating the assigned-to field.
How can I get this list programmatically?
I solved this problem by using TFS identities, which is the same thing you will find in MTM.
Firstly get a list of all the allowed users like this:
var allowedItems = workItemStore.FieldDefinitions[CoreField.AssignedTo].AllowedValues;
Now I've created a dict object which I will use as the binding source for a combobox:
var dict = new Dictionary<TeamFoundationIdentity, string>();
Now I populate that dict object:
foreach (var allowedUser in allowedItems)
{
try
{
if (allowedUser.ToString() != "Administrator")
{
TeamFoundationIdentity userInfo = ims.ReadIdentity(IdentitySearchFactor.DisplayName,
allowedUser.ToString(), MembershipQuery.Direct, ReadIdentityOptions.None);
dict.Add(userInfo, allowedUser.ToString());
}
}
catch (Exception ex)
{
//error handling here
}
}
Next (optional) I bind the dict as datasource:
comboBoxWinTester.DataSource = new BindingSource(dict, null);
comboBoxWinTester.DisplayMember = "Value";
comboBoxWinTester.ValueMember = "Key";
Notice now I can assign test points using code like this, where identity = teamFoundationIdentity:
foreach (var tp in test.PointAssignments)
{
tp.AssignedTo = identity;
suite.AssignTestPoints(test.PointAssignments);
}

logging in with different user / resource owner

i am trying to write a tool that creates entries in the google calendar.
after following the google docs and creating an client-identifier/secret in the api console, i managed to put together a client that authenticates correctly and shows my registered google calendars. right now for me it looks like my google-account is somehow tied to my client-identifier/secret. what i want to know is: how can i change the auth process so that it is possible for an other user of this tool to enter his google-id and get access to his calendars?
EDIT: in other words (used in the RFC): I want make the resource owner-part editable while leaving the client-part unchanged. but my example, although working, ties together client and resource owner.
here is my app that works fine so far:
public void Connect()
{
var provider = new NativeApplicationClient(GoogleAuthenticationServer.Description);
provider.ClientIdentifier = "123456123456.apps.googleusercontent.com";
provider.ClientSecret = "nASdjKlhnaxEkasDhhdfLklr";
var auth = new OAuth2Authenticator<NativeApplicationClient>(provider, GetAuthorization);
var service = new CalendarService(auth);
//Events instances = service.Events.Instances("primary", "recurringEventId").Fetch();
var list = service.CalendarList.List().Fetch();
foreach (var itm in list.Items)
Console.WriteLine(itm.Summary);
}
private static readonly byte[] AditionalEntropy = { 1, 2, 3, 4, 5 };
private static IAuthorizationState GetAuthorization(NativeApplicationClient arg)
{
var state = new AuthorizationState(new[] { CalendarService.Scopes.Calendar.GetStringValue() });
state.Callback = new Uri(NativeApplicationClient.OutOfBandCallbackUrl);
var refreshToken = LoadRefreshToken();
if (!String.IsNullOrWhiteSpace(refreshToken))
{
state.RefreshToken = refreshToken;
if (arg.RefreshToken(state))
return state;
}
var authUri = arg.RequestUserAuthorization(state);
// Request authorization from the user (by opening a browser window):
Process.Start(authUri.ToString());
var frm = new FormAuthCodeInput();
frm.ShowDialog();
// Retrieve the access token by using the authorization code:
var auth = arg.ProcessUserAuthorization(frm.txtAuthCode.Text, state);
StoreRefreshToken(state);
return auth;
}
private static string LoadRefreshToken()
{
try
{
return Encoding.Unicode.GetString(ProtectedData.Unprotect(Convert.FromBase64String(Properties.Settings.Default.RefreshToken), AditionalEntropy, DataProtectionScope.CurrentUser));
}
catch
{
return null;
}
}
private static void StoreRefreshToken(IAuthorizationState state)
{
Properties.Settings.Default.RefreshToken = Convert.ToBase64String(ProtectedData.Protect(Encoding.Unicode.GetBytes(state.RefreshToken), AditionalEntropy, DataProtectionScope.CurrentUser));
Properties.Settings.Default.Save();
}
Prompt the user to enter their ClientIdentifier and ClientSecret, then pass these values to your Connect method.
i solved the problem myself.
the problem was, that i'm usually always connected to google and because i did't log out from google before my app redirected to google to get the access-token, google automatically generated the access-token for my account - skipping the part where an input-form appears where anyone could enter his/her user-credentials to let google generate an access-token for his/her account.

Resources