Docker php:7.2-fpm and openssl extension

While running the installation of php 7.2 fpm of docker I ran into the issue caused by the installation of the extension openssl. Using docker-php-ext-install openssl resulted in a error config.m4 not found , I thought there would be a easy way to solve this but no.
I had to create a script based on docker-php-ext-install to just install the openssl extension by moving the mv config0.m4 to config.m4

https://stackoverflow.com/questions/43881834/php-openssl-in-ubuntu

 

In the Dockerfile where I’m building From php:7.2-ppm

COPY openssl.sh /
RUN chmod 0750 /openssl.sh && cd / && ./openssl.sh

In the openssl.sh file

#!/bin/bash

#!/bin/sh
set -e

# prefer user supplied CFLAGS, but default to our PHP_CFLAGS
: ${CFLAGS:=$PHP_CFLAGS}
: ${CPPFLAGS:=$PHP_CPPFLAGS}
: ${LDFLAGS:=$PHP_LDFLAGS}
export CFLAGS CPPFLAGS LDFLAGS

srcExists=
if [ -d /usr/src/php ]; then
srcExists=1
fi
docker-php-source extract
if [ -z “$srcExists” ]; then
touch /usr/src/php/.docker-delete-me
fi

cd /usr/src/php/ext

pm=’unknown’
if [ -e /lib/apk/db/installed ]; then
pm=’apk’
fi

apkDel=
if [ “$pm” = ‘apk’ ]; then
if [ -n “$PHPIZE_DEPS” ]; then
if apk info –installed .phpize-deps-configure > /dev/null; then
apkDel=’.phpize-deps-configure’
elif ! apk info –installed .phpize-deps > /dev/null; then
apk add –no-cache –virtual .phpize-deps $PHPIZE_DEPS
apkDel=’.phpize-deps’
fi
fi
fi

popDir=”$PWD”
cd openssl
mv config0.m4 config.m4
[ -e Makefile ] || docker-php-ext-configure openssl
make
make install
find modules \
-maxdepth 1 \
-name ‘*.so’ \
-exec basename ‘{}’ ‘;’ \
| xargs -r docker-php-ext-enable
make clean
cd “$popDir”

if [ “$pm” = ‘apk’ ] && [ -n “$apkDel” ]; then
apk del $apkDel
fi

if [ -e /usr/src/php/.docker-delete-me ]; then
docker-php-source delete
fi

 

Anúncios

Transform a Seq of case class to a group by a key

case class Glicose(day : String, inputed :String)
val r = Seq(Glicose(“2017-02-02”, “22”), Glicose(“2017-02-03”, “44”), Glicose(“2017-02-03”, “76”))

Transform this r Seq to a Seq( date -> Seq(inputed1, inputed2), date2 -> Seq(inputed3))

r.map { gl => Seq(gl.day -> r.filter(_.day == gl.day).map(_.inputed))}
//res8: Seq[Seq[(String, Seq[String])]] = List(List((2017-02-02,List(22))), List((2017-02-03,List(44, 76))), List((2017-02-03,List(44, 76))))

Or a solution that groups the duplicates from @tpolecat

r.groupBy(_.day).map { case (k, v) => k -> v.map(_.inputed) }

Nota 10

É tão lindo o que de ti sinto
Já são sete anos
Pequenino te vi nascer
Com números te vi crescer
Um, dois , três , Quatro,
Cinco , Seis Sete, fizeste
Agora te vejo amadurecer
E vêm muitos mais !
Vais ser grande
como o pai
São tão lindos
os passos que dás
Nas aulas acrescentas-te
mais Sabedoria,
nos dez
são notas
que vais ter
Com carinhos
e beijos vais crescer
Estes da mãe e do pai
Ao longe te enviando milhares
da avó que te ama muito !
Dez vais ter nas notas escolares
Das professoras que de ti fazem
um HOMEM
Sabedoria total és meu NETO
E de ti me orgulho
Dou-te a nota máxima ,
(DEZ) (avó que te ama muito)

MARIA ALICE

62 Reais e 20 Cêntimos para chegar a um café em Portugal, ou quase.

Ontem tive uma experiência que à muito sentia falta de Portugal. Ir a um café e comer um croissant (coraçã), à seis anos no Brasil e nunca comi um coraçã como os de Portugal mas ontem isso chegou muito perto de acontecer, na realidade de 1 a 10 aquele croissant era um 8 , com queijo e presunto (fiambre).

Em Três Rios, no Shopping 3 Rios no primeiro piso, rés do chão no canto esquerdo tem um pequeno café, do ponto de vista de quem olha de frente para o elevador estando na porta. Com alguns lugares, cadeiras e uma das paredes tem um sofá de uma ponta a outra. Não gravei o nome deste lugar porque acho que saí dele ainda meio atônito. Ia lá apenas por um café mas a atendente começou a sugerir várias opções, mas olhei para baixo e vi os coraçãs, muito atenta ela logo referiu que tinha um coraçã de presunto e queijo entre outros, mas aquele presunto e queijo foi o que me chamou a atenção.

Uma nota… Eu já tive más experiências a pedir croissants no Brasil. O que tem acontecido em casos anteriores é que a atendente leva o croissant ao micro-ondas para o vir servir passado 1 minuto na mesa e o sabor ser parecido a algo que nem deveria ter o nome de croissant.

Mas depois de a atendente me ter dito que não me queria servir o pão de queijo porque era de ontem e nem estava quente… Reparem!!! Ela não me vendeu o pão de queijo que eu até perguntei se ela tinha algum, ela não se preocupou em ganhar uns trocos com um mau serviço mas sim  com a qualidade dizendo que o pão de queijo era de ontem e os que estava a fazer ainda não estavam prontos. E então sugeriu outras opções e foi aí que eu olhei para o croissant na vitrine abaixo.

Depois de ter pedido o croissant fui para a mesa com a minha esposa, escolhemos uma mas rapidamente trocamos por outra perto do “sofá” para ela colocar a carteira. Nem deu tempo de iniciarmos conversa e já estávamos a ser servidos com dois cafés curtos que tinhamos pedido e o croissant.

Os dois cafés eram… Bons, servidos no estilo brasileiro sem ser com máquina de moer o café na hora como em Portugal mas mesmo assim gostei do detalhe de colocar as chávenas na mesa e me vir servir o café com um bule. Em Portugal só se usaria bule para chá mas aqui dado o estilo de preparação do café, bem este estilo foi diferente. Um francês teria gostado mais. Questionou se eu queria colocar o açucar antes ou depois, não sei a diferença mas escolhi antes.

Então após estarmos sozinhos a minha curiosidade e atenção foram para o croissant, foi demasiado rápido para ele ter ido ao micro-ondas. Como ele estaria?!
Após a primeira mordida senti o sabor da massa e era tanto quanto me lembro após 3 anos de privação e sofrimento, tal e qual a de Portugal, o queijo e o fiambre fundiam-se com a massa, em Portugal não se veria isso, pois em Portugal o croissant leva o fiambre e queijo após estar pronto e não durante o processo de cozedura, ele é vendido simples ou com diversas opções de conteúdo e até prensado. Mas a massa era igual, minha esposa confirmou que ele não tinha ido ao micro-ondas. Para ser mais parecido com o de Portugal a massa não poderia ter levado o presunto (fiambre) e o queijo no momento de cozedura, o topo dele deveria estar mais escuro e crocante. Mas mesmo assim foi uma grande melhoria comparativamente ao que tenho por aqui provado.

O serviço em si também foi bastante bom, mas o croissant foi o destaque.

Paguei uma merreca de 8 reais e 50 centavos por tudo enquanto em Miguel Pereira teriam-me levado até as cuecas por um croissant congelado levado ao micro-ondas.

Os 62 reais e 10 centavos foi o preço do ônibus para duas pessoas até 3 rios.

Posso dizer que fiquei muito agradecido por nesse dia ter comido um croissant daqueles servido num café ao estilo português, para uma pessoa que sente falta de algumas coisas gastronômicas isto ontem foi um achado.

 

Gnome-shell stop alt-tab grouping

https://superuser.com/questions/394376/how-to-prevent-gnome-shells-alttab-from-grouping-windows-from-similar-apps/481202

  • Open dconf-editor
  • Go to org/gnome/desktop/wm/keybindings
  • Move the value '<Alt>Tab' from switch-applications to switch-windows
  • Optionally move '<Shift><Alt>Tab' from switch-applications-backward to switch-windows-backward
  • If you want switch-windows to work across desktops, not just in the current desktop, you can also uncheck org/gnome/shell/window-switcher/current-workspace-only (Courtesy of @CharlBotha)
  • Close dconf-editor
  • Press <Alt>F2, then type r to restart Gnome.

The last step does not always appear to be necessary, but it should not hurt (especially since it does not close any of your running applications).

Summary of Josh Long Youtube video about Security OAuth and other resources for OAuth in Spring

About the video in: https://www.youtube.com/watch?v=EoK5a99Bmjc&list=WL&index=12

After the description of the video I specify on how to use a separate Resource server that “authenticates” against the Authorization server, also specify about the token store usage and an Example on how to do a @Query using the Authenticated user has a filter.

First go to spring Initializr

In the dependencies you will place “Cloud OAuth2”, “Web”, “JPA”, “H2”, “Lombok”

Artifact has “auth-service”

Hit(click) Generate

Download and Extract the file into a directory.

Open your editor (idea will point to pom.xml )

In file resources/application.properties he setup the service name

spring.application.name=auth-service

# Ideally you use a config server in a micro service architecture

# Set the server port to 9191

server.port=9091

# Set the contextPath from where all the oauth requests will be served

server.contextPath=/waa

# No explanation for the bellow see the following Url http://www.baeldung.com/spring-security-session

security.sessions=if-required

Will now create on the AuthServiceApplication a Entity Account

@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
class Account {
   @Id @GeneratedValue
   private Long id;

   private String username;

   private String password;

   private boolean active;
public Account(String username, String password, boolean active) {
   this.username = username;
   this.password = password;
   this.active = active;
}
}

Now he creates a Interface to Manage the Repository interface AccountRepository extends JpaRepository<Account, Long>

interface AccountRepository extends JpaRepository<Account, Long> {
   
}

Now he will persist some usernames to the database so he will create a CommandLineRunner

@SpringBootApplication
public class AuthServiceApplication {
   @Bean
   CommandLineRunner demo (AccountRepository accountRepository){
      return args-> Stream.of("jlong,spring", "dsier,cloud").map(tpl -> tpl.split(","))
            .forEach(tpl -> accountRepository.save(new Account(tpl[0], tpl[1], true)));
   }

   public static void main(String[] args) {
      SpringApplication.run(AuthServiceApplication.class, args);
   }
}

He also added a constructor to the Account Entity I placed it above in the Entity

Now he teaches Spring Security about our database, with an implementation of UserDetailsService, this Interface is a method of how Spring Security will “transform” our internal Account into a User understandable Username Password and all other details related to Spring Security.

loadByUsername also expects a Exception of type UsernameNotFoundException to be thrown in case the username is not found.

@Service
class AccountUserDetailService implements UserDetailsService {


   private final AccountRepository accountRepository;

   public AccountUserDetailService(AccountRepository accountRepository) {
      this.accountRepository = accountRepository;
   }

   @Override
   public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
      return accountRepository.findByUsername(username).map(account -> new User(account.getUsername(), account.getPassword(),
            account.isActive(), account.isActive(), account.isActive(), account.isActive(),
            AuthorityUtils.createAuthorityList("ROLE_USER", "ROLE_ADMIN")))
            .orElseThrow( () -> new UsernameNotFoundException("Could not find the username "+ username +" ."));
   }
}

In the next step he informs OAuth service how he will delegate the authorization step into the Spring Security using AuthServiceConfiguration

@Configuration
@EnableAuthorizationServer
class AuthServiceConfiguration extends AuthorizationServerConfigurerAdapter {

   private final AuthenticationManager authenticationManager;

   AuthServiceConfiguration(AuthenticationManager authenticationManager) {
      this.authenticationManager = authenticationManager;
   }

   /**
    * Specify what clients we want to authorize
    *
    * @param clients
    * @throws Exception
    */
   @Override
   public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
      clients.inMemory()
            .withClient("html5")
            .secret("password")
            .authorizedGrantTypes("password")
            .scopes("openId");
   }

   /**
    * indicate what authentication manager we want to use
    *
    * @param endpoints
    * @throws Exception
    */
   @Override
   public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
      endpoints.authenticationManager(authenticationManager);
   }
}

 

And now he runs the application.

Also https://gigsterous.github.io/engineering/2017/03/01/spring-boot-4.html has some aditional explanation.

Even more  https://spring.io/guides/tutorials/spring-boot-oauth2/

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-security.html

Setup a Resource Server separate from the Authorization Server

I’ve managed to setup a Resource Server separated from the Authorization server it’s very easy, just placing the annotation in the main class @EnableResourceServer and in application.properties specify the URI of the user information in the remote Authorization Server.

security.oauth2.resource.userInfoUri=http://localhost:9191/uaa/user

This /user address has to be setup in the Authorization Server of Long example like so:

@RequestMapping("/user")
public Principal user(Principal user) {
   return user;
}

This is placed inside the AuthServiceApplication class. And have to place the class AuthServiceApplication has a @RestController

New code will look like this:

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import java.security.Principal;
import java.util.stream.Stream;

import far.botshop.security.backend.authservice.entity.*;
import far.botshop.security.backend.authservice.repository.*;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@EnableResourceServer
@RestController
public class AuthServiceApplication {

   @Bean
   CommandLineRunner demo (AccountRepository accountRepository){
      return args-> Stream.of("jlong,spring", "dsier,cloud").map(tpl -> tpl.split(","))
            .forEach(tpl -> {
               accountRepository.save(new Account(tpl[0], tpl[1], true));
            });
   }

   public static void main(String[] args) {
      SpringApplication.run(AuthServiceApplication.class, args);
   }

   @RequestMapping("/user")
   public Principal user(Principal user) {
      return user;
   }
}

 

The authentication against the Resource Server is made using the token obtained from the Authorization server has previous examples from Long.

curl -X GET "http://localhost:8080/products" -H "Authorization: Bearer 22e70fcf-eb60-483c-9105-xxxx"

That’s it. Now for a JdbcTokenStore so the tokens can be reused…

First in the auth-service we create the dataSource and storeToken

@Autowired
private DataSource dataSource;
@Bean
public TokenStore tokenStore() {
 DataSource tokenDataSource = DataSourceBuilder.create()
 /*
 .driverClassName(oauthClass)
 .username("root")
 .password("")
I used a JDBC URL and ignored this from the example I got
 */
 .url(System.getenv().get("JDBC_DATABASE_URL")) // Here I'm using a JDBC url
 .build();
 return new JdbcTokenStore(tokenDataSource);
}

We change the configure method to use the tokenStore

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    endpoints.authenticationManager(authenticationManager);
    endpoints.userDetailsService(accountUserDetailService);
    endpoints.tokenStore(tokenStore());
}

Add the two tables that will have the tokens stored into them, if your using Postgresql I replaced the Blob type for a bytea type.

create table oauth_access_token (
  token_id VARCHAR(256),
  token BLOB,
  authentication_id VARCHAR(256) PRIMARY KEY,
  user_name VARCHAR(256),
  client_id VARCHAR(256),
  authentication BLOB,
  refresh_token VARCHAR(256)
);

create table oauth_refresh_token (
  token_id VARCHAR(256),
  token BLOB,
  authentication BLOB
);


Remove the CommandLineRunner @Bean from the AuthServiceApplication class.
Create the account table in the SQL Storage your using or place this

spring.jpa.hibernate.ddl-auto=update

in resources/application.properties if you do it the table will be create automatically on the system boot. If not you have to create it by hand.

This bellow was for postgresql

\d account
Table “public.account”
Column | Type | Modifiers
———-+————————+———–
id | bigint | not null
active | boolean | not null
password | character varying(255) |
username | character varying(255) |
Indexes:
“account_pkey” PRIMARY KEY, btree (id)

I was provided with the following link in freenode to github that has the full DB schema for the oauth part.

https://github.com/spring-projects/spring-security-oauth/blob/master/spring-security-oauth2/src/test/resources/schema.sql

Missing in this is the encoding of the User password…

For user jlong password spring

update account set password = ‘$2a$06$.D77Cpf92IZx/L84TUiVAuqTAcV9F1MUblFL26COWDNlvb6dFVCVu’ where id = 1;
UPDATE 1

For password cloud

update account set password = ‘$2a$06$iDAlgXOdcZX1Wm8j0KR1rOi1XyQprLsc78RwH2ikn0to9W9HzM5ci’ where id = 2;
UPDATE 1

Generated using http://bcrypthashgenerator.apphb.com/?PlainText=cloud

Uncomment the

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

in

public class AuthServiceConfiguration extends AuthorizationServerConfigurerAdapter {

And had to remove the constructor I had accepting the authenticationManager, and left it only to be inserted by Autowire.

Getting the Principal on the Resource Server…Using the Principal (Active User)to limit the data returned:

Using the Principal on the Resource Server , for this I had to extend the User Object to my own implementation, I didn’t want to touch to much on the Database side of Accounts so I created a new Object UserInfo

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;

import java.util.Collection;

public class UserInfo extends User {

    private Long Id;

    public UserInfo(String username, String password, boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired, boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities, Long id) {
        super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
        Id = id;
    }

    public Long getId() {
        return Id;
    }
}

Has seen this above has a aditional field Id wich I use to relate the Account to the item being managed in the Resource Server (I’m also returning Roles in this (done by default)). To the Account Entity I added the following method and private class to manage the GrantedAuthority types.

public UserInfo getUser() {
    List authorities = new ArrayList();

    authorities.add(new GrantedAuthorityImpl("ROLE_ADMIN"));

    return new UserInfo(this.getUsername(), this.getPassword(), this.isActive(), this.isActive(), this.isActive(),
            this.isActive(), authorities, this.id);
}

private class GrantedAuthorityImpl implements GrantedAuthority {

    private String auth;

    public GrantedAuthorityImpl(String auth) {
        this.auth = auth;
    }

    @Override
    public String getAuthority() {
        return auth;
    }
}

And in the AccountUserDetailService.java I changed what was returned in the loadByUsername method.

return ac.map(account ->
        account.getUser()
    ).orElseThrow( () -> new UsernameNotFoundException("Could not find the username "+ username +" ."));

For my case this is all I need in the Authorization Server.

Extracting the Principal in the Resource Server

http://javahotpot.blogspot.com.br/2013/12/spring-security-adding-more-information.html

I had to place my custom UserInfo in the ResourceServer

public class UserInfo {

    private String id;

    private String username;

    private String email;

    public String getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id.toString();
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "Username: " + this.getUsername() + " ID: " + this.getId();
    }
}

And created an Extractor PrincipalExtractor Implementation to retrieve this new representation on the Resource Server

import far.botshop.backend.model.UserInfo;
import org.springframework.boot.autoconfigure.security.oauth2.resource.PrincipalExtractor;
import org.springframework.stereotype.Service;

import java.util.Map;

@Service
public class myPrincipalExtractor implements PrincipalExtractor {

    @Override
    public UserInfo extractPrincipal(Map<String, Object> map) {

        Map<String,Object> principal = null;

        if (map.containsKey("principal")) {
            principal = (Map<String, Object>) map.get("principal");
        }

        UserInfo user = new UserInfo();

        if (principal != null ) {
            if (principal.containsKey("id")) {
                user.setId(Long.parseLong(principal.get("id").toString()));
            }

            if (principal.containsKey("username")) {
                user.setUsername(principal.get("username").toString());
            }

            if (principal.containsKey("email")) {
                user.setEmail(principal.get("email").toString());
            }
        }

        System.out.println("----> " + user.getUsername() + " -> " + user.getId());

        return user;
    }
}

 

Using the Principal in the @Query annotation of the Repository to filter only items related to this Account.

For this one I had a few hiccups… https://stackoverflow.com/questions/45901014/spring-using-spel-principal

https://spring.io/blog/2014/07/15/spel-support-in-spring-data-jpa-query-definitions

I created the SecurityEvaluationContextExtension you can read the details on the link above.

@Service
public class SecurityEvaluationContextExtension extends EvaluationContextExtensionSupport {

    @Override
    public String getExtensionId() {
        return "security";
    }

    @Override
    public SecurityExpressionRoot getRootObject() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        System.out.println("SER >>>>> " + authentication.getPrincipal().toString() + " -- " );

        return new SecurityExpressionRoot(authentication) {
            @Override
            public UserInfo getPrincipal() {
                System.out.println("Fetching the principal has user " + authentication.getPrincipal().toString());
                return (UserInfo) authentication.getPrincipal();
            }
        };
    }
}
@Configuration
@EnableJpaRepositories
public class SecurityConfiguration {

    @Bean
    EvaluationContextExtension securityExtension() {
        return new SecurityEvaluationContextExtension();
    }

}

And the related Repository and Query

@CrossOrigin
public interface StoreRepository extends CrudRepository<Store, Long>
{
    @Query("select p , p.store, p.category from Product p JOIN p.store s " +
            " JOIN p.category c " +
            " WHERE p.store.id = :id AND p.keywords LIKE %:keyword% AND p.store.ownerId = ?#{#security.principal.id} ")
    List<Product> findByKeywordIgnoreCase(@Param("id") Long id , @Param("keyword") String keyword);
}

This #security.principal is not in the main docs but I’ve been told in Twitter by JPA Lead Developer ( Oliver Gierke @olivergierke ) that it can be a related bug solved in version 2.x of DATA JPA details in the stackoverflow link.

That’s it, if you do the Authentication to the authorization server and use the Bearer token to access the Resource Server you should have access to your Resource.

Side Note: Make gnome-shell only alt+tab between current window apps

There is a Gnome Shell extension that does this: Alt Tab Workspace.

You could also directly enable this behavior in the default switcher by running:

gsettings set org.gnome.shell.app-switcher current-workspace-only true

which is what the extension does under the hood.

 

 

https://askubuntu.com/questions/54994/force-alttab-show-only-active-desktop-apps-in-gnome-shell

 

Enable Gnome-shell resize on alt+right click

https://unix.stackexchange.com/questions/28514/how-to-get-altright-mouse-to-resize-windows-again