post

Return additional info to the client using OAuth bearer tokens generation and Owin in WebApi

I am currently implementing token based authentication using ASP.Net Web Api 2, Owin and Identity. The client is implemented using ExtJS framework, and the login form itself (Ext.form.Panel) is requesting additional info in order to recognize if the action was successful. The additional info is consisted of one property named “success” whose value (true/false) is used to fire a proper event handler (success or failure);

In order to accomplish this task, one must adjust his OAuthAuthorizationServerProvider implementations GrantResourceOwnerCredentials method by creating additional AuthenticationProperties.

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{

context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

using (AuthRepository _repo = new AuthRepository())
{
IdentityUser user = await _repo.FindUser(context.UserName, context.Password);

if (user == null)
{
context.SetError("Invalid grant", "The user name or password is incorrect.");
return;
}
}

var identity = new ClaimsIdentity(context.Options.AuthenticationType);
identity.AddClaim(new Claim("sub", context.UserName));
identity.AddClaim(new Claim("role", "user"));

//added success parameter so that Ext.JS form can recognize action as successful
var props = new AuthenticationProperties(new Dictionary<string, string>
{
{
"success", "true"
}
});

var ticket = new AuthenticationTicket(identity, props);
context.Validated(ticket);

}

Additionally, you have to make sure that you override TokenEndPoint method to get those properties as a response when you obtain the token successfully. Without this end point the properties will not return in the response. Notice that i have removed all parameters with name that starts with dot so that “.expires” and “.issued” do not get added to the response (i do not need them).

public override Task TokenEndpoint(OAuthTokenEndpointContext context)
{
foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
{
//removed .issued and .expires parameter
if (!property.Key.StartsWith("."))
context.AdditionalResponseParameters.Add(property.Key, property.Value);
}

return Task.FromResult<object>(null);
}

That’s it. Hope it helps. Happy coding!

Create new Oracle user/schema

Let me first wish you a Happy New Year, this is my first post in 2016 so it would be rude from me not to mention this 🙂 Let the 2016 be prosperous for each and every one of you out there.

Now, back to business 🙂 We have migrated to the XE version of the Oracle database, as our needs do not request the full version anymore. Although the migration spared us some bucks as we are not paying the full licence anymore, it came with an additional cost – time needed to recreate everything. Since the XE version does not allow us multiple db instances, we have to create a new user/schema for each database we want to have. Additionally, i choose that we create separate tablespaces for every schema, just to keep it clean.

So first thing we need to do is login to the sqlplus with our system account (with the sysdba role), in order to add new tablespaces and create schema:

connect system/PASSWORD@XE as sysdba

Now, we can create new tablespaces with autoextend functionality. Please adjust the tablespace name and location to suit your needs:

CREATE TABLESPACE kuba2016_DATA DATAFILE 'C:\oraclexe\app\oracle\oradata\XE\kuba2016_data.dbf' SIZE 300M REUSE
DEFAULT STORAGE ( INITIAL 160K NEXT 160K MINEXTENTS 1 MAXEXTENTS 121 PCTINCREASE 1);
ALTER DATABASE DATAFILE 'C:\oraclexe\app\oracle\oradata\XE\kuba2016_data.dbf' AUTOEXTEND ON;

CREATE TABLESPACE kuba2016_INDX DATAFILE 'C:\oraclexe\app\oracle\oradata\XE\kuba2016_indx.dbf' SIZE 250M REUSE
DEFAULT STORAGE ( INITIAL 160K NEXT 160K MINEXTENTS 1 MAXEXTENTS 121 PCTINCREASE 1);
ALTER DATABASE DATAFILE 'C:\oraclexe\app\oracle\oradata\XE\kuba2016_indx.dbf' AUTOEXTEND ON;

One the tablespaces are created, we are ready to create new user/schema with needed privileges:

create user KUBA2016 identified by KUBA2016 default tablespace kuba2016_DATA;
GRANT create session to KUBA2016;
GRANT CREATE VIEW TO KUBA2016;
GRANT CREATE TABLE TO KUBA2016;
GRANT CREATE SESSION TO KUBA2016;
GRANT CREATE INDEXTYPE TO KUBA2016;
GRANT CREATE TRIGGER TO KUBA2016;
Grant CREATE DATABASE LINK to KUBA2016;
GRANT CREATE PROCEDURE TO KUBA2016;
GRANT EXECUTE ANY PROCEDURE TO KUBA2016;
GRANT CREATE ANY DIRECTORY TO KUBA2016;
COMMIT;
ALTER USER KUBA2016 quota unlimited on kuba2016_DATA;
ALTER USER KUBA2016 quota unlimited on kuba2016_INDX;

That is it, the new user/schema has been created and all we need to do now is import the oracle datapump. This can prove to be very tricky as we do not always know the name of the schema and tablespaces needed in order to import the datapump. If this is the case, I suggest that we extract DDL from the backup file using impdp:

impdp '/ as sysdba' dumpfile= logfile=import_log.txt sqlfile=ddl_dump.txt

If you examine the output file, you will realize if the schema needs to be remapped and/or additional tablespaces need to be created or remapped. I have to remap my schema and two tablespaces so my impdp command is probably more complicated than your. If you do not need to do this, just remove the last three parameters.
All you need to do now is import the datapump using impdp command:

impdp system/PASSWORD@XE directory=DATA_PUMP_DIR dumpfile=DPUMP.dmp logfile=log.log remap_schema=KUBA5_NOPIC:KUBA2016 remap_tablespace=KUBA_DATA:KUBA2016_DATA remap_tablespace=KUBA_INDX:KUBA2016_INDX

And that is it! Hope it helps

post

Download images from web using PowerShell script

So today I had to fetch some images from the certain website and save them in the dynamically generated folders. The image names were easily constructed from the ordinal number of the image so i thought i should create a small PowerShell script. I had to go with the PowerShell because the plain batch (.bat) script does not support wget command out of the box.

The image names were in the form 001s.jpg… 012s.jpg .. 123s.jpg so i had to build the filename first (with leading zeroes), and the other catch was that they had to be saved in the directory that is constructed using their ordinal number (and created before the fetch), and filename had to be “thumb.jpg”.

for($i=1; $i -le 143;$i++){
 $url = ("{0}{1}{2}" -f "https://www.youwebsitepath.com/Pics/", $i.ToString("d3"), "s.jpg")
 $dirname = ("{0}{1}" -f "C:\Users\yourusername\thumbs\thumbfolder ",$i.ToString())
 $dest = ("{0}{1}{2}" -f $dirname,"\","thumb.jpg")
 mkdir $dirname
 wget $url -OutFile $dest
}

Hope it helps,

Regards

 

UTF-8 to UTF-16 (Unicode) File Converter

I’ve recently had a problem with importing UTF-8 CSV file into the MSSQL 2012 db using bulk insert, as MSSQL, in fact, does not support UTF-8.

The solution was simple, I needed to decode and re-encode the file using UTF-16 prior running the bulk insert command.
In order to optimize the conversion process, the conversion buffer size can be changed.

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/// <summary>
/// Converts UTF-8 encoded file to UTF-16 (Unicode)
/// </summary>
/// <param name="utf8FilePath">Path to the input file (UTF-8 encoded)</param>
/// <param name="unicodeFilePath">Path to the output file (UTF-16 encoded)</param>
/// <param name="bufferSize">Size of the buffer in Kb</param>
public static void ConvertUtfToUnicode(String utf8FilePath, String unicodeFilePath, int bufferSize)
{
    FileStream fs = new FileStream(utf8FilePath, FileMode.Open, FileAccess.Read, FileShare.None, 1, true);
    FileStream fs_out = new FileStream(unicodeFilePath, FileMode.Create, FileAccess.Write, FileShare.None,1,true);

    int total = (int)fs.Length;
    int cBytesOut = 0, cBytesIn = 0, cExtraBytes = 0, cLength = 0;
    int piece = bufferSize * 1024;

    byte[] bytes_in = new byte[piece+3];
    byte[] bytes_out = null;

    do
    {
        cLength = fs.Read(bytes_in, cExtraBytes, piece) + cExtraBytes;
        cExtraBytes = cntExtraBytes(bytes_in[cLength - 3], bytes_in[cLength - 2], bytes_in[cLength - 1]);
        bytes_out = Encoding.Convert(Encoding.UTF8, Encoding.Unicode, bytes_in, 0, cLength - cExtraBytes);

        if (cExtraBytes > 0)
        {
            Buffer.BlockCopy(bytes_in, cLength - cExtraBytes, bytes_in, 0, cExtraBytes);
        }

        fs_out.Write(bytes_out, 0, bytes_out.Count());

        cBytesOut += bytes_out.Count();
        cBytesIn += piece;
    }
    while (total > cBytesIn);

    fs.Close();
    fs_out.Close();
}

        
// UTF-8 is encoded in up to 4 bytes, need to make sure we don't chop a sequence in half
// 240+: First in a 4 byte sequence
// 224+: 3 byte sequence
// 194+: 2 byte sequence
// 128+: Part of a multi-byte sequence
// 128-: Not part of a multi-byte sequence
private static int cntExtraBytes(byte c3, byte c2, byte c1)
{
    if (c1 < 128) return 0;
    if (c1 >= 192) return 1;
    if (c2 >= 224) return 2;
    if (c2 >= 192) return 0;
    if (c3 >= 240) return 3;
    if (c3 >= 224) return 0;
    return 0;
}

btw, how do you like my code beautifier? 🙂 you can make you code beautiful too, just navigate to http://hilite.me/

Brush object serialization and Isolated Storage

You probably already know that you cant serialize Brush objects using Isolated storage default serialization engine, so there are a few ways you can overcome this simple problem. There are a few approaches to solving this problem and some of them include serialization of brushes Argb byte values, or brush Color values. I’m gonna show you how to create a simple serializable class in order to overcome this problem by serializing brushes Color.

using System.Windows.Media;
using System.Runtime.Serialization;

namespace TheTime.Model
{
    [DataContract]
    public class BindableBrush
    {
        private string _brushName;
        /// <summary>
        /// Initializes a new instance of the BindableBrush class.
        /// </summary>
        public BindableBrush(Color c, string name)
        {
            Color = c;
            _brushName = name;
           
        }

        [DataMember]
        public Color Color
        { get; set; }


        public SolidColorBrush Brush 
        {
            get
            {
                return new SolidColorBrush(Color);
            }
            set
            {
                Color = value.Color;
            }
        }

        [DataMember]
        public string BrushName
        {
            get
            {
                return _brushName;
            }
            set
            {
                _brushName = value;
            }
        }
    }
}

This simple solution serializes the Color object and creates a SolidColorBrush on request. Using this class you can bind to the Brush property without any problem…

Hope it helps!

Hiding the Windows Phone 7 keyboard (SIP) when enter key is typed

There is only one way to close the SIP (Soft Input Panel) by default in Windows Phone 7, and it is by changing focus from the TextBox that is being edited to something else on the screen. As an android user, I am used to close it by hitting the enter key once the text editing is done so I’m gonna show you how to do it and hope it will become a practice.
What we need to do here is change the focus to something other than the TextBox we are currently editing, and for that purpose the PhoneApplicationPage that contains this TextBox will do just fine. All we have to do first is make this page a TabStop so we can enable it to recieve the focus.

<phone:PhoneApplicationPage 
x:Class="PanoramaPivotControls.SettingsPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
IsTabStop="True">

...

</phone:PhoneApplicationPage>

Next thing to do is add the KeyUp event handler to the TextBox and implement it.

<TextBox KeyUp="TextBox_KeyUp">

 

private void TextBox_KeyUp(object sender, KeyEventArgs e)
{
     if (e.Key == Key.Enter)
     {
         this.Focus();
     }
}

 

And that’s it! The SIP is now closed when Enter key is typed in!

Hope you find it useful..