Showing posts with label gabriel renom. Show all posts
Showing posts with label gabriel renom. Show all posts

Saturday, 7 March 2015

Azure AD Cloud silent Authentication with ADAL and TokenCache encryption

The ADAL library was launched a couple of years ago, luckily people from Microsoft like Vittorio Bertocci, have been working hard to have a library capable of doing authentication between native applications, web applications and web services (Web API). ADAL.js is in beta, it is a full working library but there are some issues need to be solved before we can have a robust library (This is when I am writing my article so March 2015) but Vittorio promised me we will have something working in this side by April 2015.
Unfortunately for me, and due to a project we are releasing before April, there is not choice, so I will have to write a wrapper around my Azure Web Api’s and skip Adal.js until we have v1.0. So you will be asking yourself “what is this guy talking about?”.
Ok, let’s go to start from a "simple" scenario, so you can have an  idea of what I am talking about. I have a Web Application (MVC 5) which is talking with few web services (Web API 2’s). All of them are register in Azure AD, so Azure AD acts as a Black Box, and manage the authentication. In this case Azure AD will take care of the MVC Web Application and the Web API’s Authentication.
So where is the problem? Well if I want to be sure that the Web Application and the Web APis share the same authentication, I will have to use refresh tokens, but because the hard work done by Vittorio’s team, now we can use Silent Tokens, so we don’t have to worry about building a whole system to refresh the tokens, but the only place where we need to worry it is about about where to store the Tokens.
It is quite common to store the tokens in Sessions, but there is a small problem with this, you lose the multi-farm factor plus WebApi’s don’t have sessions, so when you have to talk to them becomes an impossible job.
So what is the solution? store the tokens in a persistent area. If we have a native application we could store the token’s in the file system, but if we have a Web Application we could store them in Blob Storage or Databases.
Let’s go to a scenario, when someone, which is not really a user, and it is trying to get our token to access to our farm or MVC application, manage to access to the database or file system. Well, I think we will be in big trouble here. That person will have at least 20 minutes (Time when our token expires) to hack our system.
So… let’s go to make the things more difficult for this person, let’s go to inject encryption in the tokens, with double key encryption, String and Byte Array.
The following example it is a simple call from a MVC Application to a Web API 2 using silent Authentication.
...//## GETTING THE TOKEN TO BE AUTHORISE string userObjectID = ClaimsPrincipal.Current.FindFirst(userSchema).Value; AuthenticationContext authContext = new AuthenticationContext(Startup.Authority, new TokenEncryptedDatabaseCache(userObjectID, "Iamakey"); ClientCredential credential = new ClientCredential(clientId, appKey); AuthenticationResult result = authContext.AcquireTokenSilent(resourceId, credential, new UserIdentifier(userObjectID, UserIdentifierType.UniqueId));string authnHeader = "Authorization: Bearer " + result.AccessToken; ...


Now… check the parameter we are passing on  AcquireTokenSilent , it is a TokenCache.

This is the model we use to store the data in the database:


public class PerUserWebCache { [Key] public int EntryId { get; set; } public string WebUserUniqueId { get; set; } public byte[] CacheBits { get; set; } public DateTime LastWrite { get; set; } }
And finally this is the beauty! TokenEncryptedDatabaseCache, which encapsulates the encryption. You will need to create a dbcontext to store the model with the data…which I am going to add as well, so you can save some time.

using System;using System.Collections.Generic;using System.Data.Entity;using System.Linq;using System.Web;using System.Web.Caching;using Microsoft.IdentityModel.Clients.ActiveDirectory;using System.Security.Cryptography;using System.IO; public class TokenEncryptedDatabaseCache : TokenCache { private TokenCacheDataContext db = new TokenCacheDataContext(); string User; private PerUserWebCache Cache; private string Key; /// <summary> /// Contsructor for the TokenEncryptedDatabaseCache class /// </summary> /// <param name="user">Current User</param> /// <param name="key">Key for the encription</param> public TokenEncryptedDatabaseCache(string user, string key) { Key = key; User = user; this.AfterAccess = AfterAccessNotification; this.BeforeAccess = BeforeAccessNotification; this.BeforeWrite = BeforeWriteNotification; //## We check if the user is in our database Cache = db.PerUserCacheList.FirstOrDefault(c => c.WebUserUniqueId == User); //## If that is the case we keep it in memory //## We decrypt the token this.Deserialize((Cache == null) ? null : Cache.CacheBits!=null?Decrypt(Cache.CacheBits):null); } /// <summary> /// Method to clean the database /// </summary> public override void Clear() { base.Clear(); foreach (var cacheEntry in db.PerUserCacheList) db.PerUserCacheList.Remove(cacheEntry); db.SaveChanges(); } /// <summary> /// ADAL raise a notification before acces to the cache. /// Notification raised before ADAL accesses the cache. /// This is your chance to update the in-memory copy from the DB, /// if the in-memory version is stale. The token is decrypted. /// </summary> /// <param name="args"></param> void BeforeAccessNotification(TokenCacheNotificationArgs args) { if (Cache == null) { // first time access Cache = db.PerUserCacheList.FirstOrDefault(c => c.WebUserUniqueId == User); } else { // retrieve last write from the DB var status = from e in db.PerUserCacheList where (e.WebUserUniqueId == User) select new { LastWrite = e.LastWrite }; // if the in-memory copy is older than the persistent copy if (status.First().LastWrite > Cache.LastWrite) //// read from from storage, update in-memory copy { Cache = db.PerUserCacheList.FirstOrDefault(c => c.WebUserUniqueId == User); } } this.Deserialize((Cache == null) ? null : Cache.CacheBits!=null?Decrypt(Cache.CacheBits):null); } /// <summary> ///Notification raised after ADAL accessed the cache. ///If the HasStateChanged flag is set, ADAL changed the content of the cache, ///At this time we encrypt the token and save it. /// </summary> /// <param name="args"></param> void AfterAccessNotification(TokenCacheNotificationArgs args) { // if state changed if (this.HasStateChanged) { Cache = new PerUserWebCache { WebUserUniqueId = User, CacheBits = Encrypt(this.Serialize()), LastWrite = DateTime.Now }; //// update the DB and the lastwrite db.Entry(Cache).State = Cache.EntryId == 0 ? EntityState.Added : EntityState.Modified; db.SaveChanges(); this.HasStateChanged = false; } } void BeforeWriteNotification(TokenCacheNotificationArgs args) { // if you want to ensure that no concurrent write take place, use this notification to place a lock on the entry } /// <summary> /// Encription of the token. /// </summary> /// <param name="DataToEncrypt">Data to be encrypted</param> /// <returns>Data encrypted.</returns> private byte[] Encrypt(byte[] DataToEncrypt) { PasswordDeriveBytes passwordDeriveBytes = new PasswordDeriveBytes(Key, new byte[] { 0x43, 0x87, 0x23, 0x72 }); MemoryStream memoryStream = new MemoryStream(); Aes aes = new AesManaged(); aes.Key = passwordDeriveBytes.GetBytes(aes.KeySize / 8); aes.IV = passwordDeriveBytes.GetBytes(aes.BlockSize / 8); CryptoStream cryptoStream = new CryptoStream(memoryStream,aes.CreateEncryptor(), CryptoStreamMode.Write); cryptoStream.Write(DataToEncrypt, 0, DataToEncrypt.Length); cryptoStream.Close(); return memoryStream.ToArray(); } /// <summary> /// Decryption of the token. /// </summary> /// <param name="DataToDecrypt">Data to be decrypted</param> /// <returns>Data decrypted</returns> private byte[] Decrypt(byte[] DataToDecrypt) { PasswordDeriveBytes passwordDeriveBytes = new PasswordDeriveBytes(Key, new byte[] { 0x43, 0x87, 0x23, 0x72 }); MemoryStream memoryStream = new MemoryStream(); Aes aes = new AesManaged(); aes.Key = passwordDeriveBytes.GetBytes(aes.KeySize / 8); aes.IV = passwordDeriveBytes.GetBytes(aes.BlockSize / 8); CryptoStream cryptoStream = new CryptoStream(memoryStream, aes.CreateDecryptor(), CryptoStreamMode.Write); cryptoStream.Write(DataToDecrypt, 0, DataToDecrypt.Length); cryptoStream.Close(); return memoryStream.ToArray(); } }

This is the class where we have our DBContext


using System;using System.Collections.Generic;using System.ComponentModel.DataAnnotations;using System.Data.Entity;using System.Data.Entity.ModelConfiguration.Conventions;using System.Linq;using System.Text;using System.Threading.Tasks; public class TokenCacheDataContext : DbContext { public TokenCacheDataContext() : base("TokenCacheDataContext") { } public DbSet<PerUserWebCache> PerUserCacheList { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); } }


Initializer…

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; public class TokenCacheInitializer : System.Data.Entity.DropCreateDatabaseIfModelChanges<TokenCacheDataContext> { }

Well, I hope you enjoy, any questions let me know.

Monday, 5 August 2013

Verify that the service account has permissions to the following registry key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Forefront Identity Manager\2010\Synchronization Service on Sharepoint 2010 & Sharepoint 2013

This has been one of my nightmares for days. This is one of the error messages (Verify that the service account has permissions to the following registry key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Forefront Identity Manager\2010\Synchronization Service) which I managed to fix, how?:

In order to make the User Profile Synchronization Service to work, it has taken me few days, the first thing you need to make sure, if you are working with a farm, it is you are working in the same machine where you are going to activate the service. In order to do that go to Central Administration->Manage Services on Server and select your server (yes! the one you are working on)
image

Then stop and start User Profile Synchronization Service and WAIT! yes! wait for 5 minutes it takes a while. Now start User Profile Service.

image

Ok we have both successfully started. Now it is time to see if our services, which will be running with our admin service account, starts. So go to “Services” on your server and check if Forefront Identity Manager Service and Forefront Identity Manager Synchronization Service have started, if not start first, Forefront Identity Manager Synchronization Service  and Forefront Identity Manager Service after:
image

If you still getting the same message, you will probably give rights to that particular key for your account.

Monday, 13 May 2013

“You are not allowed to respond again to this survey” error on Sharepoint 2010

If you are into surveys and get an error message like this ”You are not allowed to respond again to this survey” with a screenshot like this:
image

It is because you CAN’T answer the same question twice! to enable that, just go to “Settings –> Survey Settings –> Title, description and navigation –> Survey Options –> Allow multiple responses? –> Yes”

image

Tuesday, 30 April 2013

Calendar not showing on Sharepoint 2010

Sorry to post this in my blog (it is too newbie) , but I keep forgetting the name of the feature activates the calendar. Well, if you notice there is not a calendar in your list, it is probably because the “Group Work List” feature is not activate it. To do it, just follow these steps:

Step 1
Go to Site Actions –> Site Settings –> Site Actions –> Manage site features

Step 2
Activate the feature “Group Work List” (see the image below)
image

Step 3
Activate “Team Collaboration Lists” (see image below)
image

Thursday, 25 April 2013

Adding a hidden field to a Sharepoint 2010/2013 list.

Today I am celebrating 100,000 visits of my blog with this beautiful post.

The other day was trying to add some columns to a Survey list, and I noticed that every column was a particular question of the survey. I only want to keep extra data in the list without displaying it, so I add what it is called in Sharepoint a hidden field. A hidden field it is considered a system field for Sharepoint, something the user can’t see. The is a good way to find hidden fields, just open the list on Sharepoint Designer 2010 and you will be able to see them.

This code will allow you to add a hidden field called “myhiddencolumn”

using (SPSite _site = new SPSite(SPContext.Current.Web.Url))
{
  using (SPWeb _web = _site.OpenWeb())
  {
     String _sField= "<Field Hidden=\"TRUE\" Type=\"Text\" DisplayName=\"myhiddencolumn\" ResultType=\"Text\" ReadOnly=\"False\" Name=\"myhiddencolumn\"> </Field>";
     _web.AllowUnsafeUpdates = true;
     SPList _spList = _web.Lists["mysurveylist"];
     _spList.Fields.AddFieldAsXml(_sField);
     _spList.Update();
   }
}

Wednesday, 17 April 2013

Survey questions are not exported in the right order when you select “export to spreadsheet” to Excel on Sharepoint 2010.

Surveys in Sharepoint 2010 are quite limited, but I have to admit this limitation brings simplicity to the users. Some users become quite confuse when it comes to InfoPath, so why not giving them the option of developing surveys?.

If one of them it is causing trouble and needs extra functionality, we can always add it, at the end of the day a Survey is a custom list.

There is bug in Sharepoint 2010 where the survey questions are not exported in the right order when you select “export to spreadsheet”. Why is this happening?, because a file called Overview.aspx as well as AllItems.aspx and summary.aspx have been build gradually in LILO (Last In Last Out) order. To fix this issue we only need to edit these files, and I will advise to modify only Overview.aspx. This file has the option to “export to spreadsheet”.

Step 1
Click on your survey, and you will end in a screen like this:
image

 

Step 2
Copy the URL without “/overview.aspx” and open Sharepoint Designer, go to “Open Site” and click to open.
image

 

Step 3
Go to “Lists and Libraries” and select “mysurvey” (this is my survey, select yours). Select “Overview” on the right side and double click.
image

The page will be opened, select “Code” (bottom), to see the code of the page.
image

 

Step 4
Go to the section it says <ViewFields> and choose the order you want. The order of these fields will be the order of the output of your spreadsheet. You can add extra fields if you want.

<XmlDefinition>
	<View Name="{E82854CC-2572-4FD2-A2B1-4BD74EE111D6}" DefaultView="TRUE" Type="HTML" TabularView="FALSE" ReadOnly="TRUE" FreeForm="TRUE" DisplayName="Overview" Url="/extranetpresentation/Lists/mysurvey/overview.aspx" Level="1" BaseViewID="3" ContentTypeID="0x" ImageUrl="/_layouts/images/survey.png" CssStyleSheet="survey.css">
		<ViewFields>
			<FieldRef Name="Author"/>
			<FieldRef Name="my_x0020_0_x0020_question"/>
			<FieldRef Name="_x0031__x0020_My_x0020_first_x00"/>
			<FieldRef Name="my_x0020_second_x0020_qestion"/>
			<FieldRef Name="my_x0020_third_x0020_question"/>
			<FieldRef Name="Type_x0020_your_x0020_question_x"/>
		</ViewFields>
		<Toolbar Type="Standard"/>
	</View>
</XmlDefinition>


 


Conclusion: All Responses, Graphical Summary and Overview are the files which control the out of the box survey. We just need to access to these files to customise our “out of the box” surveys.

Tuesday, 9 April 2013

Setting default data in a List Definition on Sharepoint 2013

This is a handy trick. When you create a list definition, sometimes you want to set default values, as easy as using the element <Default> and insert the default data between <Default> (ie: <Default>#FFEBCD</Default> ).

Have a look to this example coming from my Schema.xml:

<Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B99}" Name="alphatop" DisplayName="alphatop" Type="Text"  Required="FALSE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE">
 <Default>1.0</Default>
</Field>
<Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B00}" Name="alphabottom" DisplayName="alphabottom" Type="Text"  Required="FALSE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE">
 <Default>1.0</Default>
</Field>
<Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B01}" Name="overlayimagebottomenabled" DisplayName="overlayimagebottomenabled" Type="Boolean"  Required="FALSE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>      
<Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B02}" Name="overlaycolorbottom" DisplayName="overlaycolorbottom" Type="Text"  Required="FALSE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>
<Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B03}" Name="bordercolor" DisplayName="bordercolor" Type="Text"  Required="FALSE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE">
 <Default>#FFEBCD</Default>
</Field>      
I have introduced “#FFEBCD” as default value for the border color, I have also set the “alphabottom” value to 1.0.


A attach a full copy of a working lint definition:

<?xml version="1.0" encoding="utf-8"?>
<List xmlns:ows="Microsoft SharePoint" Title="PresentationLI" FolderCreation="FALSE" Direction="$Resources:Direction;" Url="Lists/PresentationLI" BaseType="0" xmlns="http://schemas.microsoft.com/sharepoint/">
  <MetaData>    
    <Fields>
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B81}" Name="topstartx" DisplayName="topstartx" Type="Integer" Required="TRUE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>                
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B82}" Name="topstarty" DisplayName="topstarty" Type="Integer" Required="TRUE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B83}" Name="topendx" DisplayName="topendx" Type="Integer" Required="TRUE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE" />       
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B84}" Name="topendy" DisplayName="topendy" Type="Integer"  Required="TRUE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B85}" Name="middlestartx" DisplayName="middlestartx" Type="Integer"  Required="TRUE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B86}" Name="middlestarty" DisplayName="middlestarty" Type="Integer"  Required="TRUE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B87}" Name="middleendx" DisplayName="middleendx" Type="Integer"  Required="TRUE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B88}" Name="middleendy" DisplayName="middleendy" Type="Integer"  Required="TRUE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B89}" Name="offsetx" DisplayName="offsetx" Type="Integer"  Required="FALSE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B90}" Name="offsety" DisplayName="offsety" Type="Integer"  Required="FALSE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B91}" Name="name" DisplayName="name" Type="Text"  Required="TRUE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B92}" Name="description" DisplayName="description" Type="Text"  Required="FALSE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B93}" Name="version" DisplayName="version" Type="Text"  Required="FALSE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B94}" Name="releasedate" DisplayName="releasedate" Type ="DateTime"  Required="FALSE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B95}" Name="audience" DisplayName="audience" Type="Text"  Required="FALSE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B96}" Name="features" DisplayName="features" Type="Note"  Required="FALSE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B97}" Name="overlayimagetop" DisplayName="overlayimagetop" Type="URL"  Required="TRUE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B98}" Name="overlayimagebottom" DisplayName="overlayimagebottom" Type="URL"  Required="FALSE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B99}" Name="alphatop" DisplayName="alphatop" Type="Text"  Required="FALSE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE">
        <Default>1.0</Default>
      </Field>
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B00}" Name="alphabottom" DisplayName="alphabottom" Type="Text"  Required="FALSE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE">
        <Default>1.0</Default>
      </Field>
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B01}" Name="overlayimagebottomenabled" DisplayName="overlayimagebottomenabled" Type="Boolean"  Required="FALSE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>      
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B02}" Name="overlaycolorbottom" DisplayName="overlaycolorbottom" Type="Text"  Required="FALSE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE"/>
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B03}" Name="bordercolor" DisplayName="bordercolor" Type="Text"  Required="FALSE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE">
        <Default>#FFEBCD</Default>
      </Field>      
      <Field ID="{24B3F6C1-B75B-4821-A466-C1E979B87B04}" Name="borderwidth" DisplayName="borderwidth" Type="Text"  Required="FALSE" ShowInEditForm="TRUE" ShowInDisplayForm="TRUE" ShowInNewForm="TRUE">
        <Default>5px</Default>
      </Field>
    </Fields>
    <Views>
      <View BaseViewID="0" Type="HTML" MobileView="TRUE" TabularView="FALSE">
        <Toolbar Type="Standard" />
        <XslLink Default="TRUE">main.xsl</XslLink>
        <RowLimit Paged="TRUE">30</RowLimit>
        <ViewFields>
          <FieldRef Name="LinkTitleNoMenu"></FieldRef>
        </ViewFields>
        <Query>
          <OrderBy>
            <FieldRef Name="Modified" Ascending="FALSE"></FieldRef>
          </OrderBy>
        </Query>
        <ParameterBindings>
          <ParameterBinding Name="AddNewAnnouncement" Location="Resource(wss,addnewitem)" />
          <ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" />
          <ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_ONET_HOME)" />
        </ParameterBindings>
      </View>
      <View BaseViewID="1" Type="HTML" WebPartZoneID="Main" DisplayName="$Resources:core,objectiv_schema_mwsidcamlidC24;" DefaultView="TRUE" MobileView="TRUE" MobileDefaultView="TRUE" SetupPath="pages\viewpage.aspx" ImageUrl="/_layouts/images/generic.png" Url="AllItems.aspx">
        <Toolbar Type="Standard" />
        <XslLink Default="TRUE">main.xsl</XslLink>
        <RowLimit Paged="TRUE">30</RowLimit>
        <ViewFields>
          <FieldRef Name="Attachments"></FieldRef>
          <FieldRef Name="LinkTitle"></FieldRef>
          
          <FieldRef Name="topstartx"> </FieldRef>
          <FieldRef Name="topstarty"></FieldRef>
          <FieldRef Name="topendx"></FieldRef>
          <FieldRef Name="topendy"></FieldRef>
          
          <FieldRef Name="middlestartx"></FieldRef>
          <FieldRef Name="middlestarty"></FieldRef>
          <FieldRef Name="middleendx"></FieldRef>
          <FieldRef Name="middleendy"></FieldRef>
          <FieldRef Name="offsetx"></FieldRef>
          <FieldRef Name="offsety"></FieldRef>
          
          <FieldRef Name="name"></FieldRef>
          <FieldRef Name="description"></FieldRef>
          <FieldRef Name="version"></FieldRef>
          <FieldRef Name="releasedate"></FieldRef>
          <FieldRef Name="audience"></FieldRef>
          <FieldRef Name="features"></FieldRef>
          <FieldRef Name="overlayimagetop"></FieldRef>
          <FieldRef Name="overlayimagebottom"></FieldRef>
          <FieldRef Name="overlayimagebottomenabled"></FieldRef>
          <FieldRef Name="overlaycolorbottom"></FieldRef>
          <FieldRef Name="alphatop"></FieldRef>
          <FieldRef Name="alphabottom"></FieldRef>
          <FieldRef Name="bordercolor"></FieldRef>
          <FieldRef Name="borderwidth"></FieldRef>
          </ViewFields>
        <Query>
          <OrderBy>
            <FieldRef Name="ID"></FieldRef>
          </OrderBy>
        </Query>
        <ParameterBindings>
          <ParameterBinding Name="NoAnnouncements" Location="Resource(wss,noXinviewofY_LIST)" />
          <ParameterBinding Name="NoAnnouncementsHowTo" Location="Resource(wss,noXinviewofY_DEFAULT)" />
        </ParameterBindings>
      </View>
    </Views>
    <Forms>
      <Form Type="DisplayForm" Url="DispForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
      <Form Type="EditForm" Url="EditForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
      <Form Type="NewForm" Url="NewForm.aspx" SetupPath="pages\form.aspx" WebPartZoneID="Main" />
    </Forms>
  </MetaData>
</List>