Tuesday, February 18, 2014

AeroGear iOS lib - 1.4.0 Release

Today, we are happy to announce the immediate availability of 1.4.0 of the AeroGear iOS library. The highlights of this release is the introduction of an Encrypted SQLite store in par with our encrypted In-Memory and Plist based stores, multipart upload API has been enhanced to support more data types apart from the regular NSURL object, and last but not least, an initial preview of our Oauth2 authorization adapter.

Let's dive in..

Encrypted SQLite store

If you have used the encrypted variants of plist and memory stores in our previous versions, you can easily switch to the encrypted SQLite variant by just setting the store type to ENCRYPTED_SQLITE. You can then use the regular Store protocol to read and write data, but this time the data are stored encrypted in an SQLite database. Let's see an example:

NSData *salt = [AGRandomGenerator randomBytes];
 
// set up crypto params configuration object
AGPassphraseCryptoConfig *config = [[AGPassphraseCryptoConfig alloc] init];
[config setSalt:salt];
[config setPassphrase:self.password.text];
 
// initialize the encryption service passing the config
id<AGEncryptionService> encService = [[AGKeyManager manager] keyService:config];
 
// access Store Manager
AGDataManager *manager = [AGDataManager manager];
 
// create store
store = [manager store:^(id<AGStoreConfig> config) {
    [config setName:@"CredentialsStorage"];
    [config setType:@"ENCRYPTED_SQLITE"];
    [config setEncryptionService:encService];
}];
 
// ok time to attempt reading..
NSArray *data = [store readAll])
 
if (data)
    // decryption succeeded!

If you are not familiar with the security API, you can find detailed description in our Cryptography support guide. Further, you can also try our Crypto Cookbook demo that stores your passwords encrypted using either a plist or an sqlite backend.

Enhanced Multipart upload

In the previous version of the library, multipart upload was supported by the mean of attaching an NSURL object on the request that pointed to a local file. Although this method is still supported, we deprecated in favour of being more flexible on the data types that can be attached. Let's see an example usage:

// a multipart that contains a file
NSURL *file1 = [NSURL fileURLWithPath:@"path-to-the-a-local-file"];
AGFilePart *filePart = [[AGFilePart alloc]initWithFileURL:file1 name:@"myfile"];

// a multipart that contains an NSData object
NSData *data1 = [@"Lorem ipsum dolor sit amet.." dataUsingEncoding:NSUTF8StringEncoding];
AGFileDataPart *dataPart = [[AGFileDataPart alloc] initWithFileData:data1 
                                                               name:@"data1"
                                                            fileName:@"data1.txt" mimeType:@"text/plain"];

// set up payload
NSDictionary *dict = @{@"somekey": @"somevalue", 
                       @"another_key": @"some_other_key",
                       @"file1":filePart,
                       @"file2":dataPart};

// set an (optional) progress block
[[apiClient uploadPipe] setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
    NSLog(@"UPLOADPIPE Sent bytesWritten=%d totalBytesWritten=%qi of totalBytesExpectedToWrite=%qi bytes", bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
}];

// upload data
[[apiClient uploadPipe] save:dict success:^(id responseObject) {
    NSLog(@"Successfully uploaded!");

} failure:^(NSError *error) {
    NSLog(@"An error has occured during upload! \n%@", error);
}];

As you can see from the example, we introduced new classes to encapsulate the different data types that can be attached on the request. An AGFilePart that can point to local NSURL objects, an AGFileDataPart that can be initialized from an NSData object directly and (not shown) an AGStreamPart that can be initialized from an NSInputStream.

OAuth2 Authorization

New to this release is the introduction of an OAuth2 adapter that will allow you to authorize against OAuth2 protected providers. Let's see an example usage that fetches the list of files residing in your Google Drive:

NSURL* serverURL = [NSURL URLWithString:"@"https://www.googleapis.com/drive/v2"];  
AGPipeline* googleFiles = [AGPipeline pipelineWithBaseURL:serverURL];  

AGAuthorizer* authorizer = [AGAuthorizer authorizer];  

_restAuthzModule = [authorizer authz:^(id<AGAuthzConfig> config) {              
    config.name = @"restAuthMod";  
    config.baseURL = [[NSURL alloc] initWithString:@"https://accounts.google.com"];  
    config.authzEndpoint = @"/o/oauth2/auth";  
    config.accessTokenEndpoint = @"/o/oauth2/token";  
    config.clientId = @"XXXXX";  
    config.redirectURL = @"org.aerogear.GoogleDrive:/oauth2Callback";  
    config.scopes = @[@"https://www.googleapis.com/auth/drive"];  
}];  

[_restAuthzModule requestAccessSuccess:^(id object) {                           
    
    id<AGPipe> files = [googleFiles pipe:^(id<AGPipeConfig> config) {       
        [config setName:@"files"];  
        [config setAuthzModule:authzModule];                                        
    }];  
  
    [files read:^(id responseObject) {                                          
        // responseObject contains the list of files
    } failure:^(NSError *error) {  
        // when an error occurs... at least log it to the console..  
        NSLog(@"Read: An error occured! \n%@", error);  
    }];  

} failure:^(NSError *error) {  
}];

My friend Corinne has already written an excellent two-part (Part1 | Part2) series about the usage of the OAuth2 adapter and I strongly suggest you to visit her blog to learn more. You can also try our Cookbook demos, GoogleDrive and Shoot that go against Google Drive to fetch and store files.


As a final note, this release marks the end of the support of iOS 5/6 versions. Work is under-way to remove any hooks that were made to cater for bugs on those versions and we will focus our efforts exclusively on iOS 7 going forward.

So go ahead and give the release a spin. Download and explore our Cookbook demos, install the Xcode template on your IDE to easily get started, play and have fun!  We will be happy to hear your thoughts, suggestions and ways to improve it better. Join our mailing list, hangout on our #aerogear IRC channel and better, file us bugs!

Wednesday, November 27, 2013

AeroGear iOS lib - 1.3.0 Release

Today, we are happy to announce the immediate availability of 1.3.0 of the AeroGear iOS library. As with our JS and Android supported platforms, main focus of this release was enabling local data encryption. Further, welcome additions such as multipart upload support and new SQLite adapter for our DataManager interface made onto this release.
Let's dive in..

aerogear-crypto-ios
"Crypto for Humans"

Applying cryptographic techniques is hard. iOS platform makes it even harder, firstly by having the functionality dispersed across different frameworks and secondly (and most important), interacting with those frameworks is not the most easy task in the world.  This became clear evidence, as we started to build local data encryption support for our DataManager.  So, we decided to spin off a new iOS library, aerogear-crypto-ios. As stated in the project's web site, main aim is to provide useful and easy to use API interfaces for performing advanced cryptographic techniques in the iOS platform.

Let's see an example on how you can encrypt/decrypt a simple String object:

NSString *stringToEncrypt = @"I want to keep it secret";
// encode string into data
NSData *dataToEncrypt = [stringToEncrypt dataUsingEncoding:NSUTF8StringEncoding];

// set up crypto params..
// generate symmetric key
NSData *encryptionKey = [pbkdf2 deriveKey:@"password4me" salt:[AGRandomGenerator randomBytes]];
// ..and a random Initialisation Vector (IV)
NSData *IV = [AGRandomGenerator randomBytes;

// init the crypto engine
AGCryptoBox *cryptoBox = [[AGCryptoBox alloc] initWithKey:encryptionKey];

// encrypt
NSData *encryptedData = [cryptoBox encrypt:dataToEncrypt IV:IV];

// decrypt
NSData *decryptedData = [cryptoBox decrypt:encryptedData IV:IV];
 

You will appreciate the 'cleanness' of the code. In four lines (excluding the declarations), we derived a PBKDF2 based encryption key, initialised our encryption engine for Symmetric Encryption, and use it to encrypt/decrypt our data.

That is our major aim for our next items to come. Provide as much as possible cleaner interfaces to the underlying crypto functionality offered by the platform (but not limited to), so the developer can stay focus on what is important, an easy-to-easy API to add crypto in their own applications. If you are interested in Crypto and got frustrated by the number of hoops you needed to jump to implement it in your own iOS applications, that's the perfect time to jump in. We love to hear your ideas and suggestions to help shape the project and move forward.

For detailed information on the API, check our iOS cookbook guide. Further, since Christmas is coming, we built a demo application that utilises the crypto library to encrypt your present wishes! My colleague Corinne has already blogged about it, so head to her blog post for more information.

DataManager

Encrypted Plist/Memory

Built on the security foundation provided by the crypto library, this release adds encrypted variants of the existing in-memory and plist based data stores (with an sqlite variant coming next release).  If you have been using the existing data stores to persist your data, you will be happy to know that you can easily switch to an encrypted variant by simple changing the type and some small (really!) amount of code to provide the necessary crypto params.

Let's see a example of using an encrypted plist:

// randomly generate salt
NSData *salt = [AGRandomGenerator randomBytes];

// set up crypto params configuration object
AGPassphraseCryptoConfig *config = [[AGPassphraseCryptoConfig alloc] init];
[config setSalt:salt];
[config setPassphrase:self.password.text];

// initialize the encryption service passing the config
id<AGEncryptionService> encService = [[AGKeyManager manager] keyService:config];

// access Store Manager
AGDataManager *manager = [AGDataManager manager];

// create store
store = [manager store:^(id<AGStoreConfig> config) {
    [config setName:@"CredentialsStorage"];
    [config setType:@"ENCRYPTED_PLIST"];
    [config setEncryptionService:encService];
}];

// ok time to attempt reading..
NSArray *data = [store readAll])

if (data)
    // decryption succeeded!
 

Detailed description of the API can be found on our iOS cookbook guide. In a nutshell, we introduced a new configuration parameter in the store that accepts an encryption service. The store will then use the service to transparently encrypt/decrypt data as they pass in. Currently a default symmetric encryption service based on PBKDF2 is implemented, but we have more plans in the future so stay tuned!

To showcase the crypto store, we built a "Password Manager" that allows a user to store passwords encrypted. Head over to the demo page to try it out yourself or watch a small video demonstrating it in action!


SQLite Adapter

A new adapter has been added on our DataManager that utilises an SQLite database as its backend. Simply specify 'SQLite' when creating a store and you can start using it immediately:

// create the datamanager
AGDataManager* dm = [AGDataManager manager];
// add a new SQLite store object
id<AGStore> = [dm store:^(id<AGStoreConfig> config) {
   [config setName:@"tasks"];
   [config setType:@"SQLITE"];
}];

The read, reset or remove API behave the same, as on our other store types, but this time objects are persisted in the sqlite database.

Don't forget to checkout our 'Recipe' application on our ios-cookbook, for example usage of the SQLite to store your favourite recipes!


Pipeline

Multipart upload

Support has been added on the Pipe interface to perform a multipart upload. No new API has been introduced, but instead we utilise the existing 'save' operation checking if the dictionary passed in contains instances of NSURL objects that point to local files. If that is the case, we kickstart the upload process.

Here is an example snippet, which uploads two images files on a server:

 // the files to be uploaded
 NSURL *file1 = [[NSBundle mainBundle] URLForResource:@"picture1" withExtension:@"jpg"];
 NSURL *file2 = [[NSBundle mainBundle] URLForResource:@"picture2" withExtension:@"jpg"];

 // construct the data to sent with the files added
 NSDictionary *dict = @{@"somekey": @"somevalue", @"jboss.jpg":file1, @"jboss2.jpg":file2 };

 // set an (optional) progress block
 [pipe setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
    NSLog(@"Sent bytesWritten=%d totalBytesWritten=%qi of totalBytesExpectedToWrite=%qi bytes", bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
 }];

// upload data
[[pipe save:dict success:^(id responseObject) {
    NSLog(@"Successfully uploaded!");

} failure:^(NSError *error) {
    NSLog(@"An error has occured during upload! \n%@", error);
}];

Note the ‘key’ in the dictionary is used as the ‘name’ field in the multipart request and is required. Further, you don’t need to specify the ‘Content-type’ or the ‘filename’ fields as they are automatically determined internally by the last path component of the NSURL object passed in. If the mime-type can’t be determined an ‘application-octet-stream’ would be sent instead.


To sum up, we think that you will enjoy this release. We have already laid our foundation for crypto, an area we are particularly interested in to moving forward as it adds significant value in the iOS community. So go ahead and give the libraries a spin. Download and explore our demos, play and have fun! We will be happy to hear your thoughts, suggestions and ways to improve it better. Join our mailing list, hangout on our #aerogear IRC channel and better, file us bugs!


Thursday, January 31, 2013

AeroGear iOS lib - Milestone 3

Today we are happy to announce the immediate availability of Milestone 3 of the AeroGear iOS library. Focus on this release was API overhaul cleanups as we prepare for the final release, but that didn't stop us to provide two neat new features that we hope our users will find them useful.

Pagination


The first feature is Pagination support of the result set returned by the server. You now have the ability to scroll either backwards or forward in the result set with the API trying to be flexible enough to support different pagination strategies supported by a server. Paging metadata located in the server response (either in the header or in the body) are used to identify the next or the previous result set. For example, in Twitter case, paging metadata are located in the body of the response, using next_page or previous_page JSON keys at the root level to identify the next or previous result set. The location of this metadata as well as naming, is fully configurable during the creation of the Pipe, thus enabling greater flexibility in supporting several different paging strategies. By default, if no configuration is applied, the library will choose to use Web Linking as it's paging strategy.

Here is an example of pagination that goes against the AeroGear Controller Server:

    NSURL* baseURL = [NSURL URLWithString:@"https://controller-aerogear.rhcloud.com/aerogear-controller-demo"];
    AGPipeline* pipeline = [AGPipeline pipelineWithBaseURL:baseURL];
    
    id<AGPipe> cars = [pipeline pipe:^(id<AGPipeConfig> config) {
        [config setName:@"cars-custom"];
        [config setNextIdentifier:@"AG-Links-Next"];
        [config setPreviousIdentifier:@"AG-Links-Previous"];
        [config setMetadataLocation:@"header"];
        // --optional config option--
        // you have the option to set default parameters that
        // will be passed along during pagination kickstart.
        // If not specified, a default query parameter provider
        // will be installed, that uses the names "offset" and
        // "limit" (two popular names found in pagination mechanisms)
        // initialized to 0 (first page) and 10 (ten items per page) respectively.
        [config setParameterProvider:@{@"color" : @"black", @"page" : @"2", @"per_page" : @10}];        
    }];     
First we create our pipeline. Notice that in the Pipe configuration object, we explicitely declare the name of the paging identifiers supported by the server, as well as the the location of these identifiers in the response. Here we used header to specify that the paging identifiers are to be found in the headers of the response. We can also specify body if the identifiers are to be found in the body of the response (like with Twitter's search), or webLinking (default) if your server follows the Web Linking standard.

To kick-start pagination, you use the method readWithParams of the underlying AGPipe, passing your desired query parameters to the server. You have the option not to specify query parameters (by passing nil), which in that case the pipe will use the default parameter provider set during the pipe creation (with the setParameterProvider config option). Upon successfully completion, the pagedResultSet (an enhanced category of NSMutableArray) will allow you to scroll through the result set:

 __block NSMutableArray *pagedResultSet;
 // fetch the first page
 [cars readWithParams:@{@"color" : @"black", @"offset" : @"0", @"limit" : @1} success:^(id responseObject) {
     pagedResultSet = responseObject;

     // do something

 } failure:^(NSError *error) {
     //handle error
 }];

To move forward or backwards in the result set, you simple call next or previous on the pagedResultSet, passing on the familiar callbacks to handle the response:

 
    // go forward..
    [pagedResultSet next:^(id responseObject) {
        // do something

   // go backwards..
   [pagedResultSet previous:^(id responseObject) {
         // do something
         
     } failure:^(NSError *error) {
         // handle error
   }];
    } failure:^(NSError *error) {
        // handle error
    }];

Note that exception cases like moving beyond last or first page is left on the behaviour of the specific server implementation, that is the library will not try treat it differently. Some servers can throw an error (like Twitter or AeroGear Controller does) by responding with an http error response, or simply return an empty list. The user is responsible to cater for exception cases like this.

We suggest you have a look here and here, two examples that go against the two most popular servers Twitter and Github. Further, if you want a feel on how paging is implemented on the other platforms we support (Android and JS) here is a page that collectively describes the API under those platforms.


Property List Storage


Drived by the need to support long term storage of objects and as an exercise of the AGStore mechanism, a simple Property List based extension was implemented. Familiar methods of reading, saving and removing objects are provided, this time though persisting the changes on the filesystem. Here is a quick example, that stores an One Time Password (OTP) secret in the filesystem so that OTP tokens can be generated later (check AeroGear OTP iOS library and demo for more information on OTP).

    AGDataManager* manager = [AGDataManager manager];
    id<AGStore> plistStore = [manager store:^(id<AGStoreConfig> config) {
       [config setName:@"secrets"];
       [config setType:@"PLIST"];
    }];

Here we initialize the store using a PLIST as type to identify that we want a property list storage and giving up a name that will be also used as the filename.

Now we can simple call the familiar methods to read and save objects in the store:

    // the object to save (e.g. a dictionary)
    NSDictionary *saveOtp = [NSDictionary dictionaryWithObjectsAndKeys:@"19a01df0281afcdbe", @"otp", @"1", @"id", nil];

    // save it
    [plistStore save:saveOtp success:^(id object) {
        // the object has been saved
    } failure:^(NSError *error) {
        //handle error
    }];

    // read it back (note that we pass the ID)
    [plistStore read:@"1" success:^(id object) {
        id readOtp = object;
    } failure:^(NSError *error) {
        //handle error
    }];  

So go ahead and give them a try. We will be happy to hear your thoughts, suggestions and ways to improve it better. Join our mailing list, hangout on our #aerogear IRC channel and better, file us bugs!

Enjoy!

Thursday, December 20, 2012

AeroGear and OTP

If you happen to use online banking systems, certainly you will have come across small security devices that provide you with an extra password during your login process. That is, in addition to your standard username/password combination, you are asked to provide an extra password, the so called "One Time Password" (OTP).  That has two effects a) the bank can verify that you are the actual person making the transaction because of the possession of this device that only you can have, the so called possession factor in the two-factor authentication system and b) prevents replay attacks cause the password is only valid for a limited amount of time. This generation of the OTP password can either be done using a hardware device (hardware token) as we described earlier, or with the help of a mobile application running on a smartphone (software token).

In general, there are two approaches to OTP generation, either Mathematical-algorithm-based or Time-synchronized. The former, as the name suggests uses a complex mathematical algorithm, typically a cryptographic hash function in a hash chain mode, together with a secret key to generate the password.  The latter, takes also into consideration the time, which causes the password to change constantly over a period of time e.g. once per minute, greatly enhancing security. On example of such approach is the Time Based One Time Password (TOTP).

So how OTP is related to the AeroGear project? Well recently, with the amazing work of my fellow developer abstractj, library implementations for both iOS and Android (and soon Javascript) of the OTP standard were introduced to the project. Currently they support only TOTP with SHA1 but work is in progress to add additional support for the other standard OTP algorithm, the event-based HOTP, together with more cryptographic hash functions support SHA-256/512.

So how do you use it?

First, a shared secret needs to be obtained that will be used for the calculation of TOTP. Here we use a static string for the purpose of the tutorial and in our demo we transfer it from the network. In practice, a QRCode encoded image of the secret should be used, so the secret should not travel across the network! In the future we will use encoded images for it.

Here is a snippet of code in the iOS land:
 // the secret key
 NSString *secret = @"B2374TNIQ3HKC446";   
 // initialize OTP  
 AGTotp *generator = [[AGTotp alloc] initWithSecret:[AGBase32 base32Decode:secret]];                       
 // generate token  
 NSString *totp = [generator generateOTP];  

Here is a snippet of code in the Android land:
 // the secret key  
 String secret = "B2374TNIQ3HKC446";
 // initialize OTP  
 Totp generator = new Totp(secret);
 // generate token  
 String totp = generator.now();  

In both cases variable "totp" now holds our token which can be send to the remote authentication server to validate.

Worth noticing is that the Java implementation has the verifier component also implemented, so if you back-end is Java, you can also use the implementation in your server-side back-end to verify totp tokens.

If you are an iOS developer, you can find the library already in the coccoapods. Further a demo application has been created that demos the library in action, so I suggest you have a look. You can find it here.

If you are an Android developer, you can find the library already in maven. Just include it in your project.
<dependency>
    <groupId>org.jboss.aerogear</groupId>
    <artifactId>aerogear-otp-java</artifactId>
    <version>1.0.0.M1</version>
    <scope>compile</scope>
</dependency>
For more in-depth information about OTP and AeroGear, I suggest you to look at the official documentation page on the AeroGear web site here. The page includes nice diagrams showing the flow of the authentication process and will help you to better understand the concept.

So go ahead and give them a try. We will love your feedback and suggestions!

Enjoy!


Tuesday, December 18, 2012

Long Live Open Source!

It has bean a long time since I've last updated this blog. Now that this year will soon come to an end (hopefully the year and not the world!), I want to post a small update of all the things that happened to me this year.

My friends know already the passion I share for JBoss technologies for a long time. Since September, I was given the life opportunity to work for the open source company I love most. In the true OSS spirit, it all started from an open source project of mine. If you follow JBoss development closely, probably you have heard about JBoss Admin, an iOS application that will allow you to remotely manage a JBoss 7 application server.  After announcing it in the development forum, I immediately got an interest from the developers and I was offered the chance to work together.

And here I am. For the past three months, I have been working with an extremely talented group of people, building amazing new technologies that will shake (in a true JBoss spirit!), the land in the mobile space.

My small advice to you. Find an open source project that you love and care, get involved with the community, find areas of work to contribute, spread your passion!. You never know where it can take you..


Wednesday, March 17, 2010

JPA 2 with Hibernate 3.5.0-CR-2

Writing this down so maybe it can help someone that wants to get started with JPA 2 with Hibernate 3.5.0-CR-2 as the underlying persistence framework.

Because you can be lost (At least I did!) to write the plumber code (e.g. maven's pom.xml, log4j.properties, persistence.xml etc) I have prepared a small project that demonstrates just an @OneToOne relation between a Customer and Address. I used H2 as the underlying database(my preferred embedded db of choice) but you can easily change it to use your preferred one(by editing the persistence.xml file).

Unzip the file that you can find here, edit the persistence.xml and change the 'javax.persistence.jdbc.url" property (yeap no more vendor properties!) to point to a folder in your local machine.

And then type the usual commands
mvn clean
mvn compile
mvn exec:java -Dexec.mainClass="gr.forthnet.rd.casper.jpademos.jpademo1.Main"


I am thinking of starting a series of posts as I am getting familiar with JPA 2.

Hope that helps

Thursday, August 06, 2009

Αθλιοι

Για όσους δεν με ξέρουν, μένω σε τουριστική περιοχή και καθημερινά έρχομαι Ηράκλειο οπου βρίσκετε η δουλειά μου. Σήμερα λόγω εκτάκτου, δεν είχα αμάξι να μετακινηθώ.

Σηκώνομαι που λέτε πρωί πρωί και 8:15 βρίσκομαι στην στάση με σκοπό να πάρω το λεωφορείο των 8:30 για Ηράκλειο. Περιμένω μαζί με άλλο κόσμο και 8:35 περνάει το λεωφορείο. Ο οδηγός μας κάνει σήμα οταν μας πλησιάζε "Το άλλο...το άλλο έρχετε απο πίσω.." ΟΚ λέω ας περιμένουμε λίγο ακόμα.

Πάει 8:40:45:50:00:5:10:15 φρίκαρα. Και 20 νάτο το άλλο. Ειχαμε μαζευτεί καμια 15αριά νοματέοι και αρχίζουμε να μπαίνουμε. Και τι να δώ, όλλα τα καθίσματα πιασμένα και κόσμος ουρά στο κέντρο. Στριμωγνόμαστε, σπρωχνόμαστε, να έχω φρικάρει και σκάει μύτη ο ελεγκτής για εισιτήριο. Τα είχα δεί όλα, άρχιζα να φωνάζω ...περιμένετε να γεμίσει το λεωφορείο και αυτούς που θα πάρετε στο δρόμο τους γράφετε στα @@, αυτός τον 8:30 γιατί δεν σταμάτησε που ήταν άδειος.... αυτός να μου λεει παπαριές (τα παραπονά σας στην διοίκηση ....). Στο τσακ ειμουνα να πάρω την τροχαία (απο οτι μου είπε μια κυρία οτι δεν πρόκειτε να κερδίσεις τίποτα, ήταν η ήδια σε φάση που ήρθε η τρόχαια έγιναν συστάσεις αλλά πάλι τα ίδια)

Τελικά έφτασα 10:40 δουλεία απο της 8:00 που ξεκίνησα!

Τι να πώ, μας βλέπανε και οι τουρίστες τι κολοχανίο είμαστε!
Να τους χαιρόμαστε, τουρισμό θέλουμε κατα τα άλλα....ρε δεν πάτε να γα...

Κτέλ Ηρακλείου fail

Saturday, June 27, 2009

Meet Jeliot

For anyone interested in teaching introductory programming using a visual like interface, consider using Jeliot. As the help describes:

Jeliot is a program animation system intended for teaching introductory programming. Programs are animated automatically, requiring no modifications or annotations on the part of the instructor or student. Jeliot is written in Java for portability and animates programs that are written in Java.

The program usage is really simple. You load the code you want to visualize(it comes with already written examples you can pick of), click "Compile" and then "Run". As the program executes it displays the outcomes, assigning to variables, executing iterations etc.

For sure, I really had fun using it, and I would recommend to anyone that wants to teach introductory programming to use it. I hope to have some time to translate it to Greek language.

Check the web site for more details (you can easily start the program with Java Web Start)

Wednesday, May 27, 2009

URL Abuse Example

Today I received a mail from a well-respectful company that suggested me to update my profile and as a bonus I will have access to some report documents (and some ring-tones which is why I was interested in the first place! :)

I completed the on-line form and after clicking the "Submit" button, a new page appeared saying "Success" and some links to get access to the content. The weird thing though that I noticed is the URL part. It was too *big*! After copying and pasting the URL to a text editor I got this:

------------
https://*.com/dct/forms/success-v2-frame.jsp?resText=%3Cp%3E%3Cimg+src%3D%22http%3A%2F%2F.FOO.com%2Foffers%2Fdetails%2FBOO_guide%2Fimages%2Fmasthead.jpg%22+%2F%3E%3C%2Fp%3E%0A%3Ch4%3EThank+you+for+your+interest+in+FOO+and+BOO.%3Cbr+%2F%3E+Get+access+to+your+%0Aoffers+now+%3A%3C%2Fh4%3E%0A%3Cp%3E%3Cbr+%2F%3E%3Cspan+style%3D%22font-family%3A+arial%3B+color%3A+%23e2934d%3B%22%3E%3Cstrong%3E%26%23187%3B%3C%2Fstrong%3E%3C%2Fspan%3E%3Cstrong%3E+Click+below+for+the+blueprint+article%3A%3Cbr+%2F%3E%0A%3Ca+href%3D%22http%3A%2F%2Fwww.FOO.com%2Foffers%2Fdocs%2F820-7350.pdf%22+target%3D%22parent%22%3EBOO+Guide+for+FOO+BOO+7000+FOO+BOO+FOO%3C%2Fa%3E%3C%2Fstrong%3E%3C%2Fp%3E%0A%3Cp%3E%3Cspan+style%3D%22font-family%3A+arial%3B+color%3A+%23e2934d%3B%22%3E%3Cstrong%3E%26%23187%3B%3C%2Fstrong%3E%3C%2Fspan%3E%3Cstrong%3E+Click+below+to+watch+the+video%3A%3Cbr+%2F%3E%0A%3Ca+href%3D%22http%3A%2F%2FchannelFOO.FOO.com%2Fvideo%2FFOO%2BMachines%2Bfor%2BBOO%2Bbest%2Bopen%2Bweb%2Binfrastructure%2B%2F1900390530%22+target%3D%22parent%22%3EFOO+FOO+for+BOO+Best+FOO+Web+Infrastructure%3C%2Fa%3E%3C%2Fstrong%3E%3C%2Fp%3E%0A%3Cp%3E%3Cspan+style%3D%22font-family%3A+arial%3B+color%3A+%23e2934d%3B%22%3E%3Cstrong%3E%26%23187%3B%3C%2Fstrong%3E%3C%2Fspan%3E%3Cstrong%3E+Click+%3Ca+href%3D%22https%3A%2F%2Fcommunications.FOO.com%2FFOOSat%2Fc%2Femea_get_music.html%22+target%3D%22parent%22%3Ehere%3C%2Fa%3E+to+access+your+FOO+Music+Sampler+page+and+download+your+gifts!%3C%2Fstrong%3E%3C%2Fp%3E%0A%3Cp%3E%3Cspan+style%3D%22font-family%3A+arial%3B+color%3A+%23e2934d%3B%22%3E%3Cstrong%3E%26%23187%3B%3C%2Fstrong%3E%3C%2Fspan%3E+%3Cstrong%3ELast+but+not+least%3A+access+the+%3Ca+href%3D%22http%3A%2F%2Fuk.FOO.com%2Femrkt%2F20090518%2Fwhitepapers%2Findex.jsp%22+target%3D%22blank%22%3E10+MOST+POPULAR+FOO+resources%3C%2Fa%3E+right+now!%3C%2Fstrong%3E%3C%2Fp%3E%0A%3Cp%3EYou+will+also+receive+an+e-mail+in+a+few+moments+with+a+link+to+this%0Ablueprint+and+the+video+so+that+you+can+save+them+to+your+system+more%0Aeasily.%3C%2Fp%3E%0A%3Cp%3EClick+here+to+%3Ca+href%3D%22http%3A%2F%2Fwww.FOO.com%2FBOO%22+target%3D%22parent%22%3Elearn+more+about+BOO.%3C%2Fa%3E%3C%2Fp%3E%0A%3Cp%3ELooking+forward+to+keeping+in+touch+with+you!%3Cbr+%2F%3E%0AThank+you%2C%3Cbr+%2F%3E%0AFOO+BOOMachines+%3C%2Fp%3E

------------

Obviously they used the URL to encode the Success HTML page(!). I have removed the notices that point to the company name, its not the important thing here. The important thing is that the hell of abuse of the HTTP/URL protocol conventions!

And it is not the first or the last example. The list goes on and on...

Wednesday, February 11, 2009

JBoss Virtual Experience 2009

A quick reminder for those interested in JBoss technology. The JBoss Virtual Experience 2009 session starts today at 8:30am EST (3:30pm Greek Time). Use the WorldClock Converter to convert the time to your local one.

See you online! :)

Friday, February 06, 2009

Ajax me Baby!

Recently, I wanted to put some Ajax touch in a web application that I currently maintain. Besides the UI's enhancements, there is real world value doing so. For example, the user enters and ID, you check the ID asynchronously(don't need a full refresh), and if doesn't exist you don't let him continue or you want to retrieve the customers that satisfy a condition and fill up a combo box. Do you want to pre-load all of your customers and handle them with js at the client side. I don't think so!

Existing ajax js frameworks may require you to do a lot of plumbing or give you stuff that you may not need at the end, I present you a handy ajax js library(one file only!) that is easy to use. Check this:

AjaxRequest.get(
{
'url':'AjaxRequestHandlerServlet',
parameters':{ 'selection':'selectCustomer', 'id':id, 'group':group }
, 'onSuccess':function(req) { fill_Customers(req.responseText); }
}
);

Can't be more simple than this! :)

For legacy applications that you have to maintain, this library in my opinion can offer you a big value for money. To find out more visit the homepage. Kudos to Matt Kruse for providing this. I already use his table js library and it works great too(and best performance both in displaying and sorting of data).
I really have to persuade my company to donate him, really great stuff!

Catch you soon

Wednesday, January 07, 2009

NetBeans 6.5 and JBoss 5

The current release of NetBeans 6.5 doesn't support(yet) the newly released JBoss 5. Although the bug has already been reported in the dev team and the fix is on the development trunk (and the soon to be released patch2 pack for NetBeans 6.5), for those of you who don't want to install a daily build, you can do the following: (Thanks to Adrigan from the JBoss forum for giving us the tip!)

1. Append the following in the file "/home/YOURUSERNAME/.netbeans/6.5/config/J2EE/InstalledServers/.nbattrs".


<fileobject name="instance_X">
<attr name="deploy-dir" stringvalue="/opt/jboss-5.0.0.GA/server/default/deploy"/>
<attr name="displayName" stringvalue="JBoss Application Server 5.0.0.GA"/>
<attr name="host" stringvalue="localhost"/>
<attr name="password" stringvalue=""/>
<attr name="port" stringvalue="8080"/>
<attr name="registeredWithoutUI" stringvalue="false"/>
<attr name="root-dir" stringvalue="/opt/jboss-5.0.0.GA"/>
<attr name="server" stringvalue="default"/>
<attr name="server-dir" stringvalue="/opt/jboss-5.0.0.GA/server/default"/>
<attr name="url" stringvalue="jboss-deployer:localhost:8080#default&amp;/opt/jboss-5.0.0.GA"/>
<attr name="username" stringvalue=""/>
</fileobject>

Replace the appropriate entries with your environment, that is the deploy-dir to the path where you have installed the JBoss server, and so on.

2. In the same folder you will find files with names starting with instance_[1,2...]. Choose the maximum and create a new empty file. In my case the file will be instance_3 (touch instance_3). After that replace the "instance_X" from the previous XML with that name.

One advice though, be carefully with the editing of the XML, because a small XML error(forgotten / at the end!), will result of your existing server list to be wiped out by NetBeans. Make a backup of the file prior editing!

That's all, save, restart NetBeans and enjoy!

Wednesday, December 31, 2008

"JBoss in Action" ebook Released




Όσοι ήταν γραμμένοι στο Manning Early Access Program(MEAP) για την κυκλοφορία του βιβλίου "JBoss in Action", σήμερα θα είναι ιδιαίτερα χαρούμενου μιας και κυκλοφόρησε η τελική έκδοση. Προς το παρόν προσφέρετε ως ebook και στης 19 Ιαν. θα οδηγηθεί για επίσημη εκτύπωση (και θα διατεθεί λιγάκι αργότερα στα βιβλιοπωλεία).

Έχοντας κάποιες μέρες που είχα μπει στο πρόγραμμα είχα την ευκαιρία να διαβάσω λιγάκι το βιβλίο (όσο με άφησε βέβαια η Χριστουγεννιάτικη κραιπάλη!) και μπορώ να πω ότι πραγματικά έχουν κάνει πολλή καλή δουλειά. Στα πολλή θετικά στοιχεία του βιβλίου είναι ότι ασχολείται με την καινούργια έκδοση του JBoss 5 (έγινε release μόλις πρόσφατα). Όπως έχουν πει και οι συγγραφείς καθυστέρησαν την κυκλοφορία του βιβλίου μιας και ήθελαν να συμπέσουν και με την επίσημη κυκλοφορία της 5 έκδοσης του JBoss.

Το βιβλίο απευθύνετε τόσο σε administrators (δίνοντας αρκετά in-depth tips στην διαχείριση, πχ το ξέρατε ότι μπορεί να έχετε αλλo directory για το deploy των εφαρμογών (πχ "/home/cvasilak/my-jboss-apps") εκτός από το default "/opt/jboss-5.0.0.GA/server/default/deploy", εγώ πάντως δεν το ξέρα!) αλλά και για developers (δίνοντας in-depth tips για το deploy όλων των τύπων j2ee artifacts (war, ears, mdb etc) και το δρόμο που ακολουθούν εσωτερικά στο app server, χρήσιμο όταν θέλουμε να δούμε που είναι το πρόβλημα).

Σίγουρα όσοι ασχολείστε ή πρόκειται να ασχοληθείτε με τον JBoss application server (και δη με την καινούργια έκδοση του 5), θα βρείτε το βιβλίο αρκετά ενδιαφέρον και το προτείνω ανεπιφύλακτα.

Μιας και πρόκειται για το τελευταίο post για το 2008 σας εύχομαι
Καλή δημιουργική Χρονιά με Yγεία και Eυτυχία!

Τα λέμε του χρόνου λοιπόν!

Tuesday, December 16, 2008

Devoxx-08 Whiteboards

Eνα από το ενδιαφέροντα πράγματα του Devoxx συνεδρίου που παρακολούθησα είναι οι αναρτημένοι πίνακες όπου οι παρευρισκόμενοι μπορούσαν να ψηφίσουν τις τεχνολογίες που χρησιμοποιούν καθώς και να αφήσουν όποια σχόλια. Τράβηξα φωτογραφία τους περισσότερους πίνακες και μπορείτε να βρείτε το set εδώ.

Σίγουρα έχουν αρκετό ενδιαφέρον και μπορούν να γεμίσουν αρκετές flamewar συζητήσεις :)

PS. Εξαιρετικά posts για τις μέρες του συνεδρίου μπορείτε να διαβάσετε απο το blog του Πάνου(jhug) που είχα την τύχη και χαρά να τον γνωρίσω και από κοντά.

Wednesday, October 22, 2008

NetBeans Syntax Highlighting Settings Migration

Hi there,

Unfortunately till now, NetBeans doesn't provide a way to manual store and retrieve the syntax highlighting settings for the editor. This is painful if you decide to migrate the settings between two or more development machines cause you need to manual adjust the settings for each one. Further it causes problems if you would like to share the settings with a friend or back it up.

Fortunately enough though there is a solution, a manual one!. NetBeans stores all of its configuration data in the user's home directory(e.g /home//.netbeans). Inside that directory you will find a folder for each NetBeans release you might have installed. For example:

/home/username/.netbeans/6.1 (For the NetBeans 6.1 release)
/home/username/.netbeans/6.5rc1 (For the NetBeans 6.5 release candindate release)

That is under Linux though, please fellow window users help here (I think it may be somewhere around C:\Documents And Settings\\...)

If you have adjusted your syntax highlighting settings, then in the NetBeans directory you will find a folder named "Editors"

/home/username/.netbeans/6.1/config/Editors/ (For the 6.1 release)

If you now copy the "Editors" folder and paste into another NetBeans instance(in /home/username/.netbeans/6.5rc1/config/) for the NetBeans 6.5 rc1 release ,all of your syntax highlighting settings would migrate. Easy ee! :)

Note:

This tip is completely unofficial, I described a method that worked for me but I cannot make any guarantees that it will work for you. Try it with caution...

That's all for now, I would love to hear your comments.

Ξεκίνημα

Γεια χαρά,

μετά από μια μακρά περίοδο αποχής, (όπως θα έχετε ήδη καταλάβει από το τελευταίο post που έγινε το 2004 όταν ήμουν ακόμα φοιτητής!) αποφάσισα να ξεκινήσω σιγά σιγά αυτό το blog καταγράφοντας τις εμπειρίες μου και θέματα που με απασχολούν κατά καιρούς περιμένοντας και τις δικές σας απόψεις.
Η ύλη του blog θα περιέχει κατά ένα μεγάλο ποσοστό προγραμματιστικά tips-links που συναντάω κατά καιρούς (κάποια θα είναι στα αγγλικά ώστε να βοηθήσουμε και τους φίλους μας από το εξωτερικό) αλλά και θέματα που τα βρίσκω ενδιαφέρον.

Προχωράμε στο πρώτο μας θέμα σχετικά με την αποθήκευση των ρυθμίσεων syntax highlighting του NetBeans(ένα πολλή καλό περιβάλλον ανάπτυξης για Java και όχι μόνο) editor ώστε να μπορούμε να τις μεταφέρουμε σε άλλους υπολογιστές ή να τα κάνουμε migrate σε major upgrades

Stay tuned!

Friday, May 14, 2004

Αλλο ένα απόγευμα διαβάσματος!

Παρασκευή σήμερα και αλλα μια μέρα μέσα για διάβασμα. Δευτέρα δίνω Μαθηματικά και ο Θεός βοηθός! Υπομονή το καλοκαιράκι φτάνει...

Συγχρητηρία στο blogger για την αλλαγή εμφάνισης, πραγματικά οι σελίδες ειναι πολλή όμορφες. Συνεχίστε την καλή δουλεία...

Λοιπον, τα κεφάλια μέσα και πίσω για διάβασμα!

::cvasilak